From 07c3f84910a6bc63a69d5f7fe0725090cf2af1ce Mon Sep 17 00:00:00 2001 From: "rvargas@google.com" Date: Tue, 2 Dec 2008 19:14:29 +0000 Subject: Disk cache: Add a tool to upgrade a set of cache files from one version to another. Also moves crash_cache project to the "tools folder" on the solution. Review URL: http://codereview.chromium.org/12851 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6226 0039d316-1c4b-4281-b951-d872f2087c98 --- net/disk_cache/backend_impl.cc | 121 +++++++++++++++++++++++------------------ net/disk_cache/backend_impl.h | 14 ++++- net/disk_cache/entry_impl.cc | 6 ++ net/disk_cache/entry_impl.h | 4 ++ 4 files changed, 91 insertions(+), 54 deletions(-) (limited to 'net/disk_cache') diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc index 75af4e4..7aa1e78 100644 --- a/net/disk_cache/backend_impl.cc +++ b/net/disk_cache/backend_impl.cc @@ -432,51 +432,7 @@ bool BackendImpl::DoomEntriesSince(const Time initial_time) { } bool BackendImpl::OpenNextEntry(void** iter, Entry** next_entry) { - if (disabled_) - return false; - - Rankings::ScopedRankingsBlock rankings(&rankings_, - reinterpret_cast(*iter)); - Rankings::ScopedRankingsBlock next(&rankings_, - rankings_.GetNext(rankings.get())); - *next_entry = NULL; - *iter = NULL; - if (!next.get()) - return false; - - scoped_refptr entry; - if (next->Data()->pointer) { - entry = reinterpret_cast(next->Data()->pointer); - } else { - bool dirty; - EntryImpl* temp = NULL; - if (NewEntry(Addr(next->Data()->contents), &temp, &dirty)) - return false; - entry.swap(&temp); - - if (dirty) { - // We cannot trust this entry. Call MatchEntry to go through the regular - // path and take the appropriate action. - std::string key = entry->GetKey(); - uint32 hash = entry->GetHash(); - entry = NULL; // Release the entry. - temp = MatchEntry(key, hash, false); - if (temp) - temp->Release(); - - return false; - } - - entry.swap(&temp); - temp = EntryImpl::Update(temp); // Update returns an adref'd entry. - entry.swap(&temp); - if (!entry.get()) - return false; - } - - entry.swap(reinterpret_cast(next_entry)); - *iter = next.release(); - return true; + return OpenFollowingEntry(true, iter, next_entry); } void BackendImpl::EndEnumeration(void** iter) { @@ -547,15 +503,15 @@ bool BackendImpl::CreateExternalFile(Addr* address) { int file_number = data_->header.last_file + 1; Addr file_address(0); bool success = false; - for (int i = 0; (i < 0x0fffffff) && !success; i++, file_number++) { + for (int i = 0; i < 0x0fffffff; i++, file_number++) { if (!file_address.SetFileNumber(file_number)) { file_number = 1; continue; } std::wstring name = GetFileName(file_address); int flags = base::PLATFORM_FILE_READ | - base::PLATFORM_FILE_WRITE | - base::PLATFORM_FILE_CREATE | + base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_EXCLUSIVE_WRITE; scoped_refptr file(new disk_cache::File( base::CreatePlatformFile(name.c_str(), flags, NULL))); @@ -563,6 +519,7 @@ bool BackendImpl::CreateExternalFile(Addr* address) { continue; success = true; + break; } DCHECK(success); @@ -584,7 +541,8 @@ void BackendImpl::DeleteBlock(Addr block_address, bool deep) { } void BackendImpl::UpdateRank(CacheRankingsBlock* node, bool modified) { - rankings_.UpdateRank(node, modified); + if (!read_only_) + rankings_.UpdateRank(node, modified); } void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { @@ -708,6 +666,10 @@ void BackendImpl::SetUnitTestMode() { unit_test_ = true; } +void BackendImpl::SetUpgradeMode() { + read_only_ = true; +} + void BackendImpl::ClearRefCountForTest() { num_refs_ = 0; } @@ -732,6 +694,10 @@ int BackendImpl::SelfCheck() { return CheckAllEntries(); } +bool BackendImpl::OpenPrevEntry(void** iter, Entry** prev_entry) { + return OpenFollowingEntry(false, iter, prev_entry); +} + // ------------------------------------------------------------------------ // We just created a new file so we're going to write the header and set the @@ -755,8 +721,8 @@ bool BackendImpl::InitBackingStore(bool* file_created) { file_util::AppendToPath(&index_name, kIndexName); int flags = base::PLATFORM_FILE_READ | - base::PLATFORM_FILE_WRITE | - base::PLATFORM_FILE_OPEN_ALWAYS | + base::PLATFORM_FILE_WRITE | + base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_EXCLUSIVE_WRITE; scoped_refptr file(new disk_cache::File( base::CreatePlatformFile(index_name.c_str(), flags, file_created))); @@ -866,7 +832,7 @@ int BackendImpl::NewEntry(Addr address, EntryImpl** entry, bool* dirty) { } EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, - bool find_parent) { + bool find_parent) { Addr address(data_->table[hash & mask_]); EntryImpl* cache_entry = NULL; EntryImpl* parent_entry = NULL; @@ -944,6 +910,57 @@ EntryImpl* BackendImpl::MatchEntry(const std::string& key, uint32 hash, return find_parent ? parent_entry : cache_entry; } +// This is the actual implementation for OpenNextEntry and OpenPrevEntry. +bool BackendImpl::OpenFollowingEntry(bool forward, void** iter, + Entry** next_entry) { + if (disabled_) + return false; + + Rankings::ScopedRankingsBlock rankings(&rankings_, + reinterpret_cast(*iter)); + CacheRankingsBlock* next_block = forward ? rankings_.GetNext(rankings.get()) : + rankings_.GetPrev(rankings.get()); + Rankings::ScopedRankingsBlock next(&rankings_, next_block); + *next_entry = NULL; + *iter = NULL; + if (!next.get()) + return false; + + scoped_refptr entry; + if (next->Data()->pointer) { + entry = reinterpret_cast(next->Data()->pointer); + } else { + bool dirty; + EntryImpl* temp = NULL; + if (NewEntry(Addr(next->Data()->contents), &temp, &dirty)) + return false; + entry.swap(&temp); + + if (dirty) { + // We cannot trust this entry. Call MatchEntry to go through the regular + // path and take the appropriate action. + std::string key = entry->GetKey(); + uint32 hash = entry->GetHash(); + entry = NULL; // Release the entry. + temp = MatchEntry(key, hash, false); + if (temp) + temp->Release(); + + return false; + } + + entry.swap(&temp); + temp = EntryImpl::Update(temp); // Update returns an adref'd entry. + entry.swap(&temp); + if (!entry.get()) + return false; + } + + entry.swap(reinterpret_cast(next_entry)); + *iter = next.release(); + return true; +} + void BackendImpl::DestroyInvalidEntry(Addr address, EntryImpl* entry) { LOG(WARNING) << "Destroying invalid entry."; Trace("Destroying invalid entry 0x%p", entry); diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h index 40b6f51..5c88682 100644 --- a/net/disk_cache/backend_impl.h +++ b/net/disk_cache/backend_impl.h @@ -23,12 +23,12 @@ class BackendImpl : public Backend { public: explicit BackendImpl(const std::wstring& path) : path_(path), block_files_(path), mask_(0), max_size_(0), - init_(false), restarted_(false), unit_test_(false), + init_(false), restarted_(false), unit_test_(false), read_only_(false), ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {} // mask can be used to limit the usable size of the hash table, for testing. BackendImpl(const std::wstring& path, uint32 mask) : path_(path), block_files_(path), mask_(mask), max_size_(0), - init_(false), restarted_(false), unit_test_(false), + init_(false), restarted_(false), unit_test_(false), read_only_(false), ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {} ~BackendImpl(); @@ -109,6 +109,9 @@ class BackendImpl : public Backend { // Sets internal parameters to enable unit testing mode. void SetUnitTestMode(); + // Sets internal parameters to enable upgrade mode (for internal tools). + void SetUpgradeMode(); + // Clears the counter of references to test handling of corruptions. void ClearRefCountForTest(); @@ -116,6 +119,9 @@ class BackendImpl : public Backend { // or an error code (negative value). int SelfCheck(); + // Same bahavior as OpenNextEntry but walks the list from back to front. + bool OpenPrevEntry(void** iter, Entry** prev_entry); + private: // Creates a new backing file for the cache index. bool CreateBackingStore(disk_cache::File* file); @@ -135,6 +141,9 @@ class BackendImpl : public Backend { EntryImpl* MatchEntry(const std::string& key, uint32 hash, bool find_parent); + // Opens the next or previous entry on a cache iteration. + bool OpenFollowingEntry(bool forward, void** iter, Entry** next_entry); + void DestroyInvalidEntry(Addr address, EntryImpl* entry); // Deletes entries from the cache until the current size is below the limit. @@ -175,6 +184,7 @@ class BackendImpl : public Backend { bool init_; // controls the initialization of the system. bool restarted_; bool unit_test_; + bool read_only_; // Prevents updates of the rankings data (used by tools). bool disabled_; Stats stats_; // Usage statistcs. diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc index 2821540..2e7b8c46 100644 --- a/net/disk_cache/entry_impl.cc +++ b/net/disk_cache/entry_impl.cc @@ -499,6 +499,12 @@ void EntryImpl::DecrementIoCount() { backend_->DecrementIoCount(); } +void EntryImpl::SetTimes(base::Time last_used, base::Time last_modified) { + node_.Data()->last_used = last_used.ToInternalValue(); + node_.Data()->last_modified = last_modified.ToInternalValue(); + node_.set_modified(); +} + bool EntryImpl::CreateDataBlock(int index, int size) { Addr address(entry_.Data()->data_addr[index]); DCHECK(0 == index || 1 == index); diff --git a/net/disk_cache/entry_impl.h b/net/disk_cache/entry_impl.h index 64fa75b..b504b0bd 100644 --- a/net/disk_cache/entry_impl.h +++ b/net/disk_cache/entry_impl.h @@ -84,6 +84,10 @@ class EntryImpl : public Entry, public base::RefCounted { void IncrementIoCount(); void DecrementIoCount(); + // Set the access times for this entry. This method provides support for + // the upgrade tool. + void SetTimes(base::Time last_used, base::Time last_modified); + private: ~EntryImpl(); -- cgit v1.1