Index: net/disk_cache/rankings.cc |
diff --git a/net/disk_cache/rankings.cc b/net/disk_cache/rankings.cc |
index 801d387e87487c74275c2250d3add2262c6338ee..b10dac69aee5335492bed440887b25869f60b833 100644 |
--- a/net/disk_cache/rankings.cc |
+++ b/net/disk_cache/rankings.cc |
@@ -228,58 +228,6 @@ void Rankings::Reset() { |
control_data_ = NULL; |
} |
-bool Rankings::GetRanking(CacheRankingsBlock* rankings) { |
- if (!rankings->address().is_initialized()) |
- return false; |
- |
- TimeTicks start = TimeTicks::Now(); |
- if (!rankings->Load()) |
- return false; |
- |
- if (!SanityCheck(rankings, true)) { |
- backend_->CriticalError(ERR_INVALID_LINKS); |
- return false; |
- } |
- |
- 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; |
- |
- 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()->dummy = 0; |
- rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1; |
- if (!rankings->Data()->dirty) |
- rankings->Data()->dirty--; |
- return true; |
- } |
- |
- // 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 l %d", node->address().value(), list); |
DCHECK(node->HasData()); |
@@ -443,116 +391,6 @@ void Rankings::UpdateRank(CacheRankingsBlock* node, bool modified, List list) { |
CACHE_UMA(AGE_MS, "UpdateRank", 0, start); |
} |
-void Rankings::CompleteTransaction() { |
- Addr node_addr(static_cast<CacheAddr>(control_data_->transaction)); |
- if (!node_addr.is_initialized() || node_addr.is_separate_file()) { |
- NOTREACHED(); |
- LOG(ERROR) << "Invalid rankings info."; |
- return; |
- } |
- |
- Trace("CompleteTransaction 0x%x", node_addr.value()); |
- |
- CacheRankingsBlock node(backend_->File(node_addr), node_addr); |
- if (!node.Load()) |
- return; |
- |
- node.Data()->dummy = 0; |
- node.Store(); |
- |
- Addr& my_head = heads_[control_data_->operation_list]; |
- Addr& my_tail = tails_[control_data_->operation_list]; |
- |
- // We want to leave the node inside the list. The entry must me marked as |
- // dirty, and will be removed later. Otherwise, we'll get assertions when |
- // attempting to remove the dirty entry. |
- if (INSERT == control_data_->operation) { |
- Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value()); |
- FinishInsert(&node); |
- } else if (REMOVE == control_data_->operation) { |
- Trace("RevertRemove h:0x%x t:0x%x", my_head.value(), my_tail.value()); |
- RevertRemove(&node); |
- } else { |
- NOTREACHED(); |
- LOG(ERROR) << "Invalid operation to recover."; |
- } |
-} |
- |
-void Rankings::FinishInsert(CacheRankingsBlock* node) { |
- control_data_->transaction = 0; |
- control_data_->operation = 0; |
- Addr& my_head = heads_[control_data_->operation_list]; |
- Addr& my_tail = tails_[control_data_->operation_list]; |
- if (my_head.value() != node->address().value()) { |
- if (my_tail.value() == node->address().value()) { |
- // This part will be skipped by the logic of Insert. |
- node->Data()->next = my_tail.value(); |
- } |
- |
- Insert(node, true, static_cast<List>(control_data_->operation_list)); |
- } |
- |
- // Tell the backend about this entry. |
- backend_->RecoveredEntry(node); |
-} |
- |
-void Rankings::RevertRemove(CacheRankingsBlock* node) { |
- Addr next_addr(node->Data()->next); |
- Addr prev_addr(node->Data()->prev); |
- if (!next_addr.is_initialized() || !prev_addr.is_initialized()) { |
- // The operation actually finished. Nothing to do. |
- control_data_->transaction = 0; |
- return; |
- } |
- if (next_addr.is_separate_file() || prev_addr.is_separate_file()) { |
- NOTREACHED(); |
- LOG(WARNING) << "Invalid rankings info."; |
- control_data_->transaction = 0; |
- return; |
- } |
- |
- CacheRankingsBlock next(backend_->File(next_addr), next_addr); |
- CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr); |
- if (!next.Load() || !prev.Load()) |
- return; |
- |
- CacheAddr node_value = node->address().value(); |
- DCHECK(prev.Data()->next == node_value || |
- prev.Data()->next == prev_addr.value() || |
- prev.Data()->next == next.address().value()); |
- DCHECK(next.Data()->prev == node_value || |
- next.Data()->prev == next_addr.value() || |
- next.Data()->prev == prev.address().value()); |
- |
- if (node_value != prev_addr.value()) |
- prev.Data()->next = node_value; |
- if (node_value != next_addr.value()) |
- next.Data()->prev = node_value; |
- |
- List my_list = static_cast<List>(control_data_->operation_list); |
- Addr& my_head = heads_[my_list]; |
- Addr& my_tail = tails_[my_list]; |
- if (!my_head.is_initialized() || !my_tail.is_initialized()) { |
- my_head.set_value(node_value); |
- my_tail.set_value(node_value); |
- WriteHead(my_list); |
- WriteTail(my_list); |
- } else if (my_head.value() == next.address().value()) { |
- my_head.set_value(node_value); |
- prev.Data()->next = next.address().value(); |
- WriteHead(my_list); |
- } else if (my_tail.value() == prev.address().value()) { |
- my_tail.set_value(node_value); |
- next.Data()->prev = prev.address().value(); |
- WriteTail(my_list); |
- } |
- |
- next.Store(); |
- prev.Store(); |
- control_data_->transaction = 0; |
- control_data_->operation = 0; |
-} |
- |
CacheRankingsBlock* Rankings::GetNext(CacheRankingsBlock* node, List list) { |
ScopedRankingsBlock next(this); |
if (!node) { |
@@ -691,6 +529,168 @@ void Rankings::WriteTail(List list) { |
control_data_->tails[list] = tails_[list].value(); |
} |
+bool Rankings::GetRanking(CacheRankingsBlock* rankings) { |
+ if (!rankings->address().is_initialized()) |
+ return false; |
+ |
+ TimeTicks start = TimeTicks::Now(); |
+ if (!rankings->Load()) |
+ return false; |
+ |
+ if (!SanityCheck(rankings, true)) { |
+ backend_->CriticalError(ERR_INVALID_LINKS); |
+ return false; |
+ } |
+ |
+ 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; |
+ |
+ 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()->dummy = 0; |
+ rankings->Data()->dirty = backend_->GetCurrentEntryId() - 1; |
+ if (!rankings->Data()->dirty) |
+ rankings->Data()->dirty--; |
+ return true; |
+ } |
+ |
+ // 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::CompleteTransaction() { |
+ Addr node_addr(static_cast<CacheAddr>(control_data_->transaction)); |
+ if (!node_addr.is_initialized() || node_addr.is_separate_file()) { |
+ NOTREACHED(); |
+ LOG(ERROR) << "Invalid rankings info."; |
+ return; |
+ } |
+ |
+ Trace("CompleteTransaction 0x%x", node_addr.value()); |
+ |
+ CacheRankingsBlock node(backend_->File(node_addr), node_addr); |
+ if (!node.Load()) |
+ return; |
+ |
+ node.Data()->dummy = 0; |
+ node.Store(); |
+ |
+ Addr& my_head = heads_[control_data_->operation_list]; |
+ Addr& my_tail = tails_[control_data_->operation_list]; |
+ |
+ // We want to leave the node inside the list. The entry must me marked as |
+ // dirty, and will be removed later. Otherwise, we'll get assertions when |
+ // attempting to remove the dirty entry. |
+ if (INSERT == control_data_->operation) { |
+ Trace("FinishInsert h:0x%x t:0x%x", my_head.value(), my_tail.value()); |
+ FinishInsert(&node); |
+ } else if (REMOVE == control_data_->operation) { |
+ Trace("RevertRemove h:0x%x t:0x%x", my_head.value(), my_tail.value()); |
+ RevertRemove(&node); |
+ } else { |
+ NOTREACHED(); |
+ LOG(ERROR) << "Invalid operation to recover."; |
+ } |
+} |
+ |
+void Rankings::FinishInsert(CacheRankingsBlock* node) { |
+ control_data_->transaction = 0; |
+ control_data_->operation = 0; |
+ Addr& my_head = heads_[control_data_->operation_list]; |
+ Addr& my_tail = tails_[control_data_->operation_list]; |
+ if (my_head.value() != node->address().value()) { |
+ if (my_tail.value() == node->address().value()) { |
+ // This part will be skipped by the logic of Insert. |
+ node->Data()->next = my_tail.value(); |
+ } |
+ |
+ Insert(node, true, static_cast<List>(control_data_->operation_list)); |
+ } |
+ |
+ // Tell the backend about this entry. |
+ backend_->RecoveredEntry(node); |
+} |
+ |
+void Rankings::RevertRemove(CacheRankingsBlock* node) { |
+ Addr next_addr(node->Data()->next); |
+ Addr prev_addr(node->Data()->prev); |
+ if (!next_addr.is_initialized() || !prev_addr.is_initialized()) { |
+ // The operation actually finished. Nothing to do. |
+ control_data_->transaction = 0; |
+ return; |
+ } |
+ if (next_addr.is_separate_file() || prev_addr.is_separate_file()) { |
+ NOTREACHED(); |
+ LOG(WARNING) << "Invalid rankings info."; |
+ control_data_->transaction = 0; |
+ return; |
+ } |
+ |
+ CacheRankingsBlock next(backend_->File(next_addr), next_addr); |
+ CacheRankingsBlock prev(backend_->File(prev_addr), prev_addr); |
+ if (!next.Load() || !prev.Load()) |
+ return; |
+ |
+ CacheAddr node_value = node->address().value(); |
+ DCHECK(prev.Data()->next == node_value || |
+ prev.Data()->next == prev_addr.value() || |
+ prev.Data()->next == next.address().value()); |
+ DCHECK(next.Data()->prev == node_value || |
+ next.Data()->prev == next_addr.value() || |
+ next.Data()->prev == prev.address().value()); |
+ |
+ if (node_value != prev_addr.value()) |
+ prev.Data()->next = node_value; |
+ if (node_value != next_addr.value()) |
+ next.Data()->prev = node_value; |
+ |
+ List my_list = static_cast<List>(control_data_->operation_list); |
+ Addr& my_head = heads_[my_list]; |
+ Addr& my_tail = tails_[my_list]; |
+ if (!my_head.is_initialized() || !my_tail.is_initialized()) { |
+ my_head.set_value(node_value); |
+ my_tail.set_value(node_value); |
+ WriteHead(my_list); |
+ WriteTail(my_list); |
+ } else if (my_head.value() == next.address().value()) { |
+ my_head.set_value(node_value); |
+ prev.Data()->next = next.address().value(); |
+ WriteHead(my_list); |
+ } else if (my_tail.value() == prev.address().value()) { |
+ my_tail.set_value(node_value); |
+ next.Data()->prev = prev.address().value(); |
+ WriteTail(my_list); |
+ } |
+ |
+ next.Store(); |
+ prev.Store(); |
+ control_data_->transaction = 0; |
+ control_data_->operation = 0; |
+} |
+ |
bool Rankings::CheckEntry(CacheRankingsBlock* rankings) { |
if (!rankings->Data()->dummy) |
return true; |