| 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 20 matching lines...) Expand all Loading... |
| 31 #include "base/logging.h" | 31 #include "base/logging.h" |
| 32 #include "base/message_loop.h" | 32 #include "base/message_loop.h" |
| 33 #include "base/string_util.h" | 33 #include "base/string_util.h" |
| 34 #include "base/time.h" | 34 #include "base/time.h" |
| 35 #include "net/disk_cache/backend_impl.h" | 35 #include "net/disk_cache/backend_impl.h" |
| 36 #include "net/disk_cache/entry_impl.h" | 36 #include "net/disk_cache/entry_impl.h" |
| 37 #include "net/disk_cache/histogram_macros.h" | 37 #include "net/disk_cache/histogram_macros.h" |
| 38 #include "net/disk_cache/trace.h" | 38 #include "net/disk_cache/trace.h" |
| 39 | 39 |
| 40 using base::Time; | 40 using base::Time; |
| 41 using base::TimeTicks; |
| 41 | 42 |
| 42 namespace { | 43 namespace { |
| 43 | 44 |
| 44 const int kCleanUpMargin = 1024 * 1024; | 45 const int kCleanUpMargin = 1024 * 1024; |
| 45 const int kHighUse = 10; // Reuse count to be on the HIGH_USE list. | 46 const int kHighUse = 10; // Reuse count to be on the HIGH_USE list. |
| 46 const int kTargetTime = 24 * 7; // Time to be evicted (hours since last use). | 47 const int kTargetTime = 24 * 7; // Time to be evicted (hours since last use). |
| 47 const int kMaxDelayedTrims = 60; | 48 const int kMaxDelayedTrims = 60; |
| 48 | 49 |
| 49 int LowWaterAdjust(int high_water) { | 50 int LowWaterAdjust(int high_water) { |
| 50 if (high_water < kCleanUpMargin) | 51 if (high_water < kCleanUpMargin) |
| (...skipping 25 matching lines...) Expand all Loading... |
| 76 return; | 77 return; |
| 77 | 78 |
| 78 if (!empty && !ShouldTrim()) | 79 if (!empty && !ShouldTrim()) |
| 79 return PostDelayedTrim(); | 80 return PostDelayedTrim(); |
| 80 | 81 |
| 81 if (new_eviction_) | 82 if (new_eviction_) |
| 82 return TrimCacheV2(empty); | 83 return TrimCacheV2(empty); |
| 83 | 84 |
| 84 Trace("*** Trim Cache ***"); | 85 Trace("*** Trim Cache ***"); |
| 85 trimming_ = true; | 86 trimming_ = true; |
| 86 Time start = Time::Now(); | 87 TimeTicks start = TimeTicks::Now(); |
| 87 Rankings::ScopedRankingsBlock node(rankings_); | 88 Rankings::ScopedRankingsBlock node(rankings_); |
| 88 Rankings::ScopedRankingsBlock next(rankings_, | 89 Rankings::ScopedRankingsBlock next(rankings_, |
| 89 rankings_->GetPrev(node.get(), Rankings::NO_USE)); | 90 rankings_->GetPrev(node.get(), Rankings::NO_USE)); |
| 90 int target_size = empty ? 0 : max_size_; | 91 int target_size = empty ? 0 : max_size_; |
| 91 while (header_->num_bytes > target_size && next.get()) { | 92 while (header_->num_bytes > target_size && next.get()) { |
| 92 // The iterator could be invalidated within EvictEntry(). | 93 // The iterator could be invalidated within EvictEntry(). |
| 93 if (!next->HasData()) | 94 if (!next->HasData()) |
| 94 break; | 95 break; |
| 95 node.reset(next.release()); | 96 node.reset(next.release()); |
| 96 next.reset(rankings_->GetPrev(node.get(), Rankings::NO_USE)); | 97 next.reset(rankings_->GetPrev(node.get(), Rankings::NO_USE)); |
| 97 if (node->Data()->dirty != backend_->GetCurrentEntryId() || empty) { | 98 if (node->Data()->dirty != backend_->GetCurrentEntryId() || empty) { |
| 98 // This entry is not being used by anybody. | 99 // This entry is not being used by anybody. |
| 99 // Do NOT use node as an iterator after this point. | 100 // Do NOT use node as an iterator after this point. |
| 100 rankings_->TrackRankingsBlock(node.get(), false); | 101 rankings_->TrackRankingsBlock(node.get(), false); |
| 101 if (!EvictEntry(node.get(), empty)) | 102 if (!EvictEntry(node.get(), empty)) |
| 102 continue; | 103 continue; |
| 103 | 104 |
| 104 if (!empty) { | 105 if (!empty) { |
| 105 backend_->OnEvent(Stats::TRIM_ENTRY); | 106 backend_->OnEvent(Stats::TRIM_ENTRY); |
| 106 | 107 |
| 107 if ((Time::Now() - start).InMilliseconds() > 20) { | 108 if ((TimeTicks::Now() - start).InMilliseconds() > 20) { |
| 108 MessageLoop::current()->PostTask(FROM_HERE, | 109 MessageLoop::current()->PostTask(FROM_HERE, |
| 109 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); | 110 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); |
| 110 break; | 111 break; |
| 111 } | 112 } |
| 112 } | 113 } |
| 113 } | 114 } |
| 114 } | 115 } |
| 115 | 116 |
| 116 if (empty) { | 117 if (empty) { |
| 117 CACHE_UMA(AGE_MS, "TotalClearTimeV1", 0, start); | 118 CACHE_UMA(AGE_MS, "TotalClearTimeV1", 0, start); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 entry->Release(); | 239 entry->Release(); |
| 239 | 240 |
| 240 return true; | 241 return true; |
| 241 } | 242 } |
| 242 | 243 |
| 243 // ----------------------------------------------------------------------- | 244 // ----------------------------------------------------------------------- |
| 244 | 245 |
| 245 void Eviction::TrimCacheV2(bool empty) { | 246 void Eviction::TrimCacheV2(bool empty) { |
| 246 Trace("*** Trim Cache ***"); | 247 Trace("*** Trim Cache ***"); |
| 247 trimming_ = true; | 248 trimming_ = true; |
| 248 Time start = Time::Now(); | 249 TimeTicks start = TimeTicks::Now(); |
| 249 | 250 |
| 250 const int kListsToSearch = 3; | 251 const int kListsToSearch = 3; |
| 251 Rankings::ScopedRankingsBlock next[kListsToSearch]; | 252 Rankings::ScopedRankingsBlock next[kListsToSearch]; |
| 252 int list = Rankings::LAST_ELEMENT; | 253 int list = Rankings::LAST_ELEMENT; |
| 253 | 254 |
| 254 // Get a node from each list. | 255 // Get a node from each list. |
| 255 for (int i = 0; i < kListsToSearch; i++) { | 256 for (int i = 0; i < kListsToSearch; i++) { |
| 256 bool done = false; | 257 bool done = false; |
| 257 next[i].set_rankings(rankings_); | 258 next[i].set_rankings(rankings_); |
| 258 if (done) | 259 if (done) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 289 node.reset(next[list].release()); | 290 node.reset(next[list].release()); |
| 290 next[list].reset(rankings_->GetPrev(node.get(), | 291 next[list].reset(rankings_->GetPrev(node.get(), |
| 291 static_cast<Rankings::List>(list))); | 292 static_cast<Rankings::List>(list))); |
| 292 if (node->Data()->dirty != backend_->GetCurrentEntryId() || empty) { | 293 if (node->Data()->dirty != backend_->GetCurrentEntryId() || empty) { |
| 293 // This entry is not being used by anybody. | 294 // This entry is not being used by anybody. |
| 294 // Do NOT use node as an iterator after this point. | 295 // Do NOT use node as an iterator after this point. |
| 295 rankings_->TrackRankingsBlock(node.get(), false); | 296 rankings_->TrackRankingsBlock(node.get(), false); |
| 296 if (!EvictEntry(node.get(), empty)) | 297 if (!EvictEntry(node.get(), empty)) |
| 297 continue; | 298 continue; |
| 298 | 299 |
| 299 if (!empty && (Time::Now() - start).InMilliseconds() > 20) { | 300 if (!empty && (TimeTicks::Now() - start).InMilliseconds() > 20) { |
| 300 MessageLoop::current()->PostTask(FROM_HERE, | 301 MessageLoop::current()->PostTask(FROM_HERE, |
| 301 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); | 302 factory_.NewRunnableMethod(&Eviction::TrimCache, false)); |
| 302 break; | 303 break; |
| 303 } | 304 } |
| 304 } | 305 } |
| 305 } | 306 } |
| 306 if (!empty) | 307 if (!empty) |
| 307 list = kListsToSearch; | 308 list = kListsToSearch; |
| 308 } | 309 } |
| 309 | 310 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 return Rankings::HIGH_USE; | 409 return Rankings::HIGH_USE; |
| 409 } | 410 } |
| 410 | 411 |
| 411 // This is a minimal implementation that just discards the oldest nodes. | 412 // This is a minimal implementation that just discards the oldest nodes. |
| 412 // TODO(rvargas): Do something better here. | 413 // TODO(rvargas): Do something better here. |
| 413 void Eviction::TrimDeleted(bool empty) { | 414 void Eviction::TrimDeleted(bool empty) { |
| 414 Trace("*** Trim Deleted ***"); | 415 Trace("*** Trim Deleted ***"); |
| 415 if (backend_->disabled_) | 416 if (backend_->disabled_) |
| 416 return; | 417 return; |
| 417 | 418 |
| 418 Time start = Time::Now(); | 419 TimeTicks start = TimeTicks::Now(); |
| 419 Rankings::ScopedRankingsBlock node(rankings_); | 420 Rankings::ScopedRankingsBlock node(rankings_); |
| 420 Rankings::ScopedRankingsBlock next(rankings_, | 421 Rankings::ScopedRankingsBlock next(rankings_, |
| 421 rankings_->GetPrev(node.get(), Rankings::DELETED)); | 422 rankings_->GetPrev(node.get(), Rankings::DELETED)); |
| 422 for (int i = 0; (i < 4 || empty) && next.get(); i++) { | 423 for (int i = 0; (i < 4 || empty) && next.get(); i++) { |
| 423 node.reset(next.release()); | 424 node.reset(next.release()); |
| 424 next.reset(rankings_->GetPrev(node.get(), Rankings::DELETED)); | 425 next.reset(rankings_->GetPrev(node.get(), Rankings::DELETED)); |
| 425 RemoveDeletedNode(node.get()); | 426 RemoveDeletedNode(node.get()); |
| 426 } | 427 } |
| 427 | 428 |
| 428 if (header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) | 429 if (header_->lru.sizes[Rankings::DELETED] > header_->num_entries / 4) |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 Time::FromInternalValue(last2.get()->Data()->last_used)); | 499 Time::FromInternalValue(last2.get()->Data()->last_used)); |
| 499 if (last3.get()) | 500 if (last3.get()) |
| 500 CACHE_UMA(AGE, "HighUseAge", 0, | 501 CACHE_UMA(AGE, "HighUseAge", 0, |
| 501 Time::FromInternalValue(last3.get()->Data()->last_used)); | 502 Time::FromInternalValue(last3.get()->Data()->last_used)); |
| 502 if (last4.get()) | 503 if (last4.get()) |
| 503 CACHE_UMA(AGE, "DeletedAge", 0, | 504 CACHE_UMA(AGE, "DeletedAge", 0, |
| 504 Time::FromInternalValue(last4.get()->Data()->last_used)); | 505 Time::FromInternalValue(last4.get()->Data()->last_used)); |
| 505 } | 506 } |
| 506 | 507 |
| 507 } // namespace disk_cache | 508 } // namespace disk_cache |
| OLD | NEW |