| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // The eviction policy is a very simple pure LRU, so the elements at the end of | 5 // The eviction policy is a very simple pure LRU, so the elements at the end of |
| 6 // the list are evicted until kCleanUpMargin free space is available. There is | 6 // the list are evicted until kCleanUpMargin free space is available. There is |
| 7 // only one list in use (Rankings::NO_USE), and elements are sent to the front | 7 // only one list in use (Rankings::NO_USE), and elements are sent to the front |
| 8 // of the list whenever they are accessed. | 8 // of the list whenever they are accessed. |
| 9 | 9 |
| 10 // The new (in-development) eviction policy ads re-use as a factor to evict | 10 // The new (in-development) eviction policy ads re-use as a factor to evict |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 Rankings::ScopedRankingsBlock node(rankings_); | 85 Rankings::ScopedRankingsBlock node(rankings_); |
| 86 Rankings::ScopedRankingsBlock next(rankings_, | 86 Rankings::ScopedRankingsBlock next(rankings_, |
| 87 rankings_->GetPrev(node.get(), Rankings::NO_USE)); | 87 rankings_->GetPrev(node.get(), Rankings::NO_USE)); |
| 88 int target_size = empty ? 0 : max_size_; | 88 int target_size = empty ? 0 : max_size_; |
| 89 while (header_->num_bytes > target_size && next.get()) { | 89 while (header_->num_bytes > target_size && next.get()) { |
| 90 // The iterator could be invalidated within EvictEntry(). | 90 // The iterator could be invalidated within EvictEntry(). |
| 91 if (!next->HasData()) | 91 if (!next->HasData()) |
| 92 break; | 92 break; |
| 93 node.reset(next.release()); | 93 node.reset(next.release()); |
| 94 next.reset(rankings_->GetPrev(node.get(), Rankings::NO_USE)); | 94 next.reset(rankings_->GetPrev(node.get(), Rankings::NO_USE)); |
| 95 if (!node->Data()->pointer || empty) { | 95 if (node->Data()->dirty != backend_->GetCurrentEntryId() || empty) { |
| 96 // This entry is not being used by anybody. | 96 // This entry is not being used by anybody. |
| 97 // Do NOT use node as an iterator after this point. | 97 // Do NOT use node as an iterator after this point. |
| 98 rankings_->TrackRankingsBlock(node.get(), false); | 98 rankings_->TrackRankingsBlock(node.get(), false); |
| 99 if (!EvictEntry(node.get(), empty)) | 99 if (!EvictEntry(node.get(), empty)) |
| 100 continue; | 100 continue; |
| 101 | 101 |
| 102 if (!empty) { | 102 if (!empty) { |
| 103 backend_->OnEvent(Stats::TRIM_ENTRY); | 103 backend_->OnEvent(Stats::TRIM_ENTRY); |
| 104 | 104 |
| 105 if ((Time::Now() - start).InMilliseconds() > 20) { | 105 if ((Time::Now() - start).InMilliseconds() > 20) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 268 |
| 269 int target_size = empty ? 0 : max_size_; | 269 int target_size = empty ? 0 : max_size_; |
| 270 for (; list < kListsToSearch; list++) { | 270 for (; list < kListsToSearch; list++) { |
| 271 while (header_->num_bytes > target_size && next[list].get()) { | 271 while (header_->num_bytes > target_size && next[list].get()) { |
| 272 // The iterator could be invalidated within EvictEntry(). | 272 // The iterator could be invalidated within EvictEntry(). |
| 273 if (!next[list]->HasData()) | 273 if (!next[list]->HasData()) |
| 274 break; | 274 break; |
| 275 node.reset(next[list].release()); | 275 node.reset(next[list].release()); |
| 276 next[list].reset(rankings_->GetPrev(node.get(), | 276 next[list].reset(rankings_->GetPrev(node.get(), |
| 277 static_cast<Rankings::List>(list))); | 277 static_cast<Rankings::List>(list))); |
| 278 if (!node->Data()->pointer || empty) { | 278 if (node->Data()->dirty != backend_->GetCurrentEntryId() || empty) { |
| 279 // This entry is not being used by anybody. | 279 // This entry is not being used by anybody. |
| 280 // Do NOT use node as an iterator after this point. | 280 // Do NOT use node as an iterator after this point. |
| 281 rankings_->TrackRankingsBlock(node.get(), false); | 281 rankings_->TrackRankingsBlock(node.get(), false); |
| 282 if (!EvictEntry(node.get(), empty)) | 282 if (!EvictEntry(node.get(), empty)) |
| 283 continue; | 283 continue; |
| 284 | 284 |
| 285 if (!empty && (Time::Now() - start).InMilliseconds() > 20) { | 285 if (!empty && (Time::Now() - start).InMilliseconds() > 20) { |
| 286 MessageLoop::current()->PostTask(FROM_HERE, | 286 MessageLoop::current()->PostTask(FROM_HERE, |
| 287 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); | 287 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); |
| 288 break; | 288 break; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 bool Eviction::RemoveDeletedNode(CacheRankingsBlock* node) { | 418 bool Eviction::RemoveDeletedNode(CacheRankingsBlock* node) { |
| 419 EntryImpl* entry; | 419 EntryImpl* entry; |
| 420 bool dirty; | 420 bool dirty; |
| 421 if (backend_->NewEntry(Addr(node->Data()->contents), &entry, &dirty)) { | 421 if (backend_->NewEntry(Addr(node->Data()->contents), &entry, &dirty)) { |
| 422 Trace("NewEntry failed on Trim 0x%x", node->address().value()); | 422 Trace("NewEntry failed on Trim 0x%x", node->address().value()); |
| 423 return false; | 423 return false; |
| 424 } | 424 } |
| 425 | 425 |
| 426 // TODO(rvargas): figure out how to deal with corruption at this point (dirty | 426 // TODO(rvargas): figure out how to deal with corruption at this point (dirty |
| 427 // entries that live in this list). | 427 // entries that live in this list). |
| 428 if (node->Data()->pointer) { | 428 if (node->Data()->dirty) { |
| 429 // We ignore the failure; we're removing the entry anyway. | 429 // We ignore the failure; we're removing the entry anyway. |
| 430 entry->Update(); | 430 entry->Update(); |
| 431 } | 431 } |
| 432 entry->entry()->Data()->state = ENTRY_DOOMED; | 432 entry->entry()->Data()->state = ENTRY_DOOMED; |
| 433 entry->Doom(); | 433 entry->Doom(); |
| 434 entry->Release(); | 434 entry->Release(); |
| 435 return true; | 435 return true; |
| 436 } | 436 } |
| 437 | 437 |
| 438 bool Eviction::NodeIsOldEnough(CacheRankingsBlock* node, int list) { | 438 bool Eviction::NodeIsOldEnough(CacheRankingsBlock* node, int list) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 Time::FromInternalValue(last2.get()->Data()->last_used)); | 479 Time::FromInternalValue(last2.get()->Data()->last_used)); |
| 480 if (last3.get()) | 480 if (last3.get()) |
| 481 CACHE_UMA(AGE, "HighUseAge", header_->experiment, | 481 CACHE_UMA(AGE, "HighUseAge", header_->experiment, |
| 482 Time::FromInternalValue(last3.get()->Data()->last_used)); | 482 Time::FromInternalValue(last3.get()->Data()->last_used)); |
| 483 if (last4.get()) | 483 if (last4.get()) |
| 484 CACHE_UMA(AGE, "DeletedAge", header_->experiment, | 484 CACHE_UMA(AGE, "DeletedAge", header_->experiment, |
| 485 Time::FromInternalValue(last4.get()->Data()->last_used)); | 485 Time::FromInternalValue(last4.get()->Data()->last_used)); |
| 486 } | 486 } |
| 487 | 487 |
| 488 } // namespace disk_cache | 488 } // namespace disk_cache |
| OLD | NEW |