Index: net/disk_cache/eviction.cc |
=================================================================== |
--- net/disk_cache/eviction.cc (revision 11934) |
+++ net/disk_cache/eviction.cc (working copy) |
@@ -209,8 +209,13 @@ |
} |
// 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. |
+ if (Rankings::HIGH_USE == list && |
+ !NodeIsOldEnough(next[Rankings::HIGH_USE].get(), 0)) |
Nicolas Sylvain
2009/03/18 17:17:35
the zero here, it should not be "list" ?
rvargas (doing something else)
2009/03/18 17:32:13
no 'cause NodeIsOldEnough(next[2], 2) was already
|
+ list = 0; |
+ } |
if (empty) |
list = 0; |
@@ -240,9 +245,12 @@ |
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,9 +340,50 @@ |
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) { |
if (!node) |
return false; |
@@ -348,10 +397,12 @@ |
} |
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; |
} |