summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/rankings.cc
diff options
context:
space:
mode:
Diffstat (limited to 'net/disk_cache/rankings.cc')
-rw-r--r--net/disk_cache/rankings.cc324
1 files changed, 162 insertions, 162 deletions
diff --git a/net/disk_cache/rankings.cc b/net/disk_cache/rankings.cc
index 801d387..b10dac6 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;