diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-18 18:54:52 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-18 18:54:52 +0000 |
commit | 1849d01a855914348bbdc07c7674764daf549358 (patch) | |
tree | 432d2a804daa8424703d394dc3a89e662b1e3aa4 /net/disk_cache | |
parent | d6a612019430c62642db846393dbab1e9d4c7869 (diff) | |
download | chromium_src-1849d01a855914348bbdc07c7674764daf549358.zip chromium_src-1849d01a855914348bbdc07c7674764daf549358.tar.gz chromium_src-1849d01a855914348bbdc07c7674764daf549358.tar.bz2 |
Disk cache: First implementation of TrimDeleted() and a few
other fixes related to the new eviction code. As before,
almost everything is disabled by default.
Review URL: http://codereview.chromium.org/48112
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11995 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache')
-rw-r--r-- | net/disk_cache/backend_impl.cc | 2 | ||||
-rw-r--r-- | net/disk_cache/disk_cache.h | 2 | ||||
-rw-r--r-- | net/disk_cache/entry_impl.cc | 14 | ||||
-rw-r--r-- | net/disk_cache/eviction.cc | 61 | ||||
-rw-r--r-- | net/disk_cache/eviction.h | 1 |
5 files changed, 70 insertions, 10 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc index 9f560cc..885f1db 100644 --- a/net/disk_cache/backend_impl.cc +++ b/net/disk_cache/backend_impl.cc @@ -641,7 +641,7 @@ void BackendImpl::RemoveEntry(EntryImpl* entry) { if (!new_eviction_) return; - DCHECK(ENTRY_DOOMED == entry->entry()->Data()->state); + DCHECK(ENTRY_NORMAL != entry->entry()->Data()->state); Trace("Remove entry 0x%p", entry); eviction_.OnDestroyEntry(entry); diff --git a/net/disk_cache/disk_cache.h b/net/disk_cache/disk_cache.h index 3ea3b25..50f50c5 100644 --- a/net/disk_cache/disk_cache.h +++ b/net/disk_cache/disk_cache.h @@ -172,7 +172,7 @@ class Entry { // Returns an asynchronous read file handle for the cache stream referenced by // |index|. Values other than base::kInvalidPlatformFileValue are successful - // and the file handle should be managed by the caller, i.e. caller should + // and the file handle should be managed by the caller, i.e. the caller should // close the handle after use or there will be a leak. virtual base::PlatformFile GetPlatformFile(int index) = 0; diff --git a/net/disk_cache/entry_impl.cc b/net/disk_cache/entry_impl.cc index 446138e..2e852a4 100644 --- a/net/disk_cache/entry_impl.cc +++ b/net/disk_cache/entry_impl.cc @@ -382,7 +382,7 @@ base::PlatformFile EntryImpl::GetPlatformFile(int index) { return base::CreatePlatformFile(backend_->GetFileName(address), base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ | - base::PLATFORM_FILE_ASYNC, + base::PLATFORM_FILE_ASYNC, NULL); } @@ -457,19 +457,25 @@ void EntryImpl::InternalDoom() { void EntryImpl::DeleteEntryData(bool everything) { DCHECK(doomed_ || !everything); - UMA_HISTOGRAM_COUNTS("DiskCache.DeleteHeader", GetDataSize(0)); - UMA_HISTOGRAM_COUNTS("DiskCache.DeleteData", GetDataSize(1)); + if (GetDataSize(0)) + UMA_HISTOGRAM_COUNTS("DiskCache.DeleteHeader", GetDataSize(0)); + if (GetDataSize(1)) + UMA_HISTOGRAM_COUNTS("DiskCache.DeleteData", GetDataSize(1)); for (int index = 0; index < NUM_STREAMS; index++) { Addr address(entry_.Data()->data_addr[index]); if (address.is_initialized()) { DeleteData(address, index); backend_->ModifyStorageSize(entry_.Data()->data_size[index] - unreported_size_[index], 0); + entry_.Data()->data_addr[index] = 0; + entry_.Data()->data_size[index] = 0; } } - if (!everything) + if (!everything) { + entry_.Store(); return; + } // Remove all traces of this entry. backend_->RemoveEntry(this); diff --git a/net/disk_cache/eviction.cc b/net/disk_cache/eviction.cc index a7eb9fc..6f7df82 100644 --- a/net/disk_cache/eviction.cc +++ b/net/disk_cache/eviction.cc @@ -209,8 +209,15 @@ void Eviction::TrimCacheV2(bool empty) { } // If we are not meeting the time targets lets move on to list length. - if (!empty && Rankings::LAST_ELEMENT == list) + if (!empty && Rankings::LAST_ELEMENT == list) { list = SelectListByLenght(); + // Make sure that frequently used items are kept for a minimum time; we know + // that this entry is not older than its current target, but it must be at + // least older than the target for list 0 (kTargetTime). + if (Rankings::HIGH_USE == list && + !NodeIsOldEnough(next[Rankings::HIGH_USE].get(), 0)) + list = 0; + } if (empty) list = 0; @@ -240,9 +247,12 @@ void Eviction::TrimCacheV2(bool empty) { list = kListsToSearch; } - if (empty || header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) + if (empty) { + TrimDeleted(true); + } else if (header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) { MessageLoop::current()->PostTask(FROM_HERE, factory_.NewRunnableMethod(&Eviction::TrimDeleted, empty)); + } UMA_HISTOGRAM_TIMES("DiskCache.TotalTrimTime", Time::Now() - start); Trace("*** Trim Cache end ***"); @@ -332,7 +342,48 @@ Rankings::List Eviction::GetListForEntryV2(EntryImpl* entry) { return Rankings::HIGH_USE; } +// This is a minimal implementation that just discards the oldest nodes. +// TODO(rvargas): Do something better here. void Eviction::TrimDeleted(bool empty) { + Trace("*** Trim Deleted ***"); + if (backend_->disabled_) + return; + + Time start = Time::Now(); + Rankings::ScopedRankingsBlock node(rankings_); + Rankings::ScopedRankingsBlock next(rankings_, + rankings_->GetPrev(node.get(), Rankings::DELETED)); + DCHECK(next.get()); + for (int i = 0; (i < 4 || empty) && next.get(); i++) { + node.reset(next.release()); + next.reset(rankings_->GetPrev(node.get(), Rankings::DELETED)); + RemoveDeletedNode(node.get()); + } + + if (header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) + MessageLoop::current()->PostTask(FROM_HERE, + factory_.NewRunnableMethod(&Eviction::TrimDeleted, false)); + + UMA_HISTOGRAM_TIMES("DiskCache.TotalTrimDeletedTime", Time::Now() - start); + Trace("*** Trim Deleted end ***"); + return; +} + +bool Eviction::RemoveDeletedNode(CacheRankingsBlock* node) { + EntryImpl* entry; + bool dirty; + if (backend_->NewEntry(Addr(node->Data()->contents), &entry, &dirty)) { + Trace("NewEntry failed on Trim 0x%x", node->address().value()); + return false; + } + + if (node->Data()->pointer) { + entry = EntryImpl::Update(entry); + } + entry->entry()->Data()->state = ENTRY_DOOMED; + entry->Doom(); + entry->Release(); + return true; } bool Eviction::NodeIsOldEnough(CacheRankingsBlock* node, int list) { @@ -348,10 +399,12 @@ bool Eviction::NodeIsOldEnough(CacheRankingsBlock* node, int list) { } int Eviction::SelectListByLenght() { + int data_entries = header_->num_entries - + header_->lru.sizes[Rankings::DELETED]; // Start by having each list to be roughly the same size. - if (header_->lru.sizes[0] > header_->num_entries / 4) + if (header_->lru.sizes[0] > data_entries / 3) return 0; - if (header_->lru.sizes[1] > header_->num_entries / 4) + if (header_->lru.sizes[1] > data_entries / 3) return 1; return 2; } diff --git a/net/disk_cache/eviction.h b/net/disk_cache/eviction.h index 2496357..56b8439 100644 --- a/net/disk_cache/eviction.h +++ b/net/disk_cache/eviction.h @@ -55,6 +55,7 @@ class Eviction { void OnDestroyEntryV2(EntryImpl* entry); Rankings::List GetListForEntryV2(EntryImpl* entry); void TrimDeleted(bool empty); + bool RemoveDeletedNode(CacheRankingsBlock* node); bool NodeIsOldEnough(CacheRankingsBlock* node, int list); int SelectListByLenght(); |