| Index: net/disk_cache/rankings.cc
|
| ===================================================================
|
| --- net/disk_cache/rankings.cc (revision 21923)
|
| +++ net/disk_cache/rankings.cc (working copy)
|
| @@ -204,10 +204,10 @@
|
| }
|
|
|
| bool Rankings::GetRanking(CacheRankingsBlock* rankings) {
|
| - Time start = Time::Now();
|
| if (!rankings->address().is_initialized())
|
| return false;
|
|
|
| + Time start = Time::Now();
|
| if (!rankings->Load())
|
| return false;
|
|
|
| @@ -216,33 +216,45 @@
|
| return false;
|
| }
|
|
|
| - if (!rankings->Data()->pointer) {
|
| - backend_->OnEvent(Stats::GET_RANKINGS);
|
| + backend_->OnEvent(Stats::OPEN_RANKINGS);
|
| +
|
| + // "dummy" is the old "pointer" value, so it has to be 0.
|
| + if (!rankings->Data()->dirty && !rankings->Data()->dummy)
|
| return true;
|
| - }
|
|
|
| - backend_->OnEvent(Stats::OPEN_RANKINGS);
|
| -
|
| - if (backend_->GetCurrentEntryId() != rankings->Data()->dirty ||
|
| - !backend_->IsOpen(rankings)) {
|
| + EntryImpl* entry = backend_->GetOpenEntry(rankings);
|
| + if (backend_->GetCurrentEntryId() != rankings->Data()->dirty || !entry) {
|
| // We cannot trust this entry, but we cannot initiate a cleanup from this
|
| // point (we may be in the middle of a cleanup already). Just get rid of
|
| // the invalid pointer and continue; the entry will be deleted when detected
|
| // from a regular open/create path.
|
| - rankings->Data()->pointer = NULL;
|
| + rankings->Data()->dummy = 0;
|
| rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1;
|
| if (!rankings->Data()->dirty)
|
| rankings->Data()->dirty--;
|
| return true;
|
| }
|
|
|
| - EntryImpl* cache_entry =
|
| - reinterpret_cast<EntryImpl*>(rankings->Data()->pointer);
|
| - rankings->SetData(cache_entry->rankings()->Data());
|
| + // Note that we should not leave this module without deleting rankings first.
|
| + rankings->SetData(entry->rankings()->Data());
|
| +
|
| CACHE_UMA(AGE_MS, "GetRankings", 0, start);
|
| return true;
|
| }
|
|
|
| +void Rankings::ConvertToLongLived(CacheRankingsBlock* rankings) {
|
| + if (rankings->own_data())
|
| + return;
|
| +
|
| + // We cannot return a shared node because we are not keeping a reference
|
| + // to the entry that owns the buffer. Make this node a copy of the one that
|
| + // we have, and let the iterator logic update it when the entry changes.
|
| + CacheRankingsBlock temp(NULL, Addr(0));
|
| + *temp.Data() = *rankings->Data();
|
| + rankings->StopSharingData();
|
| + *rankings->Data() = *temp.Data();
|
| +}
|
| +
|
| void Rankings::Insert(CacheRankingsBlock* node, bool modified, List list) {
|
| Trace("Insert 0x%x", node->address().value());
|
| DCHECK(node->HasData());
|
| @@ -414,7 +426,7 @@
|
| if (!node.Load())
|
| return;
|
|
|
| - node.Data()->pointer = NULL;
|
| + node.Data()->dummy = 0;
|
| node.Store();
|
|
|
| Addr& my_head = heads_[control_data_->operation_list];
|
| @@ -518,6 +530,8 @@
|
| return NULL;
|
| next.reset(new CacheRankingsBlock(backend_->File(my_head), my_head));
|
| } else {
|
| + if (!node->HasData())
|
| + node->Load();
|
| Addr& my_tail = tails_[list];
|
| if (!my_tail.is_initialized())
|
| return NULL;
|
| @@ -534,6 +548,7 @@
|
| if (!GetRanking(next.get()))
|
| return NULL;
|
|
|
| + ConvertToLongLived(next.get());
|
| if (node && !CheckSingleLink(node, next.get()))
|
| return NULL;
|
|
|
| @@ -548,6 +563,8 @@
|
| return NULL;
|
| prev.reset(new CacheRankingsBlock(backend_->File(my_tail), my_tail));
|
| } else {
|
| + if (!node->HasData())
|
| + node->Load();
|
| Addr& my_head = heads_[list];
|
| if (!my_head.is_initialized())
|
| return NULL;
|
| @@ -564,6 +581,7 @@
|
| if (!GetRanking(prev.get()))
|
| return NULL;
|
|
|
| + ConvertToLongLived(prev.get());
|
| if (node && !CheckSingleLink(prev.get(), node))
|
| return NULL;
|
|
|
| @@ -642,7 +660,7 @@
|
| }
|
|
|
| bool Rankings::CheckEntry(CacheRankingsBlock* rankings) {
|
| - if (!rankings->Data()->pointer)
|
| + if (!rankings->Data()->dummy)
|
| return true;
|
|
|
| // If this entry is not dirty, it is a serious problem.
|
| @@ -749,8 +767,7 @@
|
| ++it) {
|
| if (it->first == address && it->second->HasData()) {
|
| CacheRankingsBlock* other = it->second;
|
| - other->Data()->next = node->Data()->next;
|
| - other->Data()->prev = node->Data()->prev;
|
| + *other->Data() = *node->Data();
|
| }
|
| }
|
| }
|
|
|