summaryrefslogtreecommitdiffstats
path: root/net/disk_cache
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-18 18:54:52 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-18 18:54:52 +0000
commit1849d01a855914348bbdc07c7674764daf549358 (patch)
tree432d2a804daa8424703d394dc3a89e662b1e3aa4 /net/disk_cache
parentd6a612019430c62642db846393dbab1e9d4c7869 (diff)
downloadchromium_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.cc2
-rw-r--r--net/disk_cache/disk_cache.h2
-rw-r--r--net/disk_cache/entry_impl.cc14
-rw-r--r--net/disk_cache/eviction.cc61
-rw-r--r--net/disk_cache/eviction.h1
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();