Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: net/disk_cache/backend_impl.cc

Issue 14183: Disk cache: move eviction code to a separate file.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/backend_impl.h ('k') | net/disk_cache/eviction.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "net/disk_cache/backend_impl.h" 5 #include "net/disk_cache/backend_impl.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/histogram.h" 8 #include "base/histogram.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
11 #include "base/sys_info.h" 11 #include "base/sys_info.h"
12 #include "base/timer.h" 12 #include "base/timer.h"
13 #include "base/worker_pool.h" 13 #include "base/worker_pool.h"
14 #include "net/disk_cache/cache_util.h" 14 #include "net/disk_cache/cache_util.h"
15 #include "net/disk_cache/entry_impl.h" 15 #include "net/disk_cache/entry_impl.h"
16 #include "net/disk_cache/errors.h" 16 #include "net/disk_cache/errors.h"
17 #include "net/disk_cache/hash.h" 17 #include "net/disk_cache/hash.h"
18 #include "net/disk_cache/file.h" 18 #include "net/disk_cache/file.h"
19 19
20 using base::Time; 20 using base::Time;
21 using base::TimeDelta; 21 using base::TimeDelta;
22 22
23 namespace { 23 namespace {
24 24
25 const wchar_t* kIndexName = L"index"; 25 const wchar_t* kIndexName = L"index";
26 const int kCleanUpMargin = 1024 * 1024;
27 const int kMaxOldFolders = 100; 26 const int kMaxOldFolders = 100;
28 27
29 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people. 28 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people.
30 const int k64kEntriesStore = 240 * 1000 * 1000; 29 const int k64kEntriesStore = 240 * 1000 * 1000;
31 const int kBaseTableLen = 64 * 1024; 30 const int kBaseTableLen = 64 * 1024;
32 const int kDefaultCacheSize = 80 * 1024 * 1024; 31 const int kDefaultCacheSize = 80 * 1024 * 1024;
33 32
34 int DesiredIndexTableLen(int32 storage_size) { 33 int DesiredIndexTableLen(int32 storage_size) {
35 if (storage_size <= k64kEntriesStore) 34 if (storage_size <= k64kEntriesStore)
36 return kBaseTableLen; 35 return kBaseTableLen;
(...skipping 10 matching lines...) Expand all
47 46
48 int MaxStorageSizeForTable(int table_len) { 47 int MaxStorageSizeForTable(int table_len) {
49 return table_len * (k64kEntriesStore / kBaseTableLen); 48 return table_len * (k64kEntriesStore / kBaseTableLen);
50 } 49 }
51 50
52 size_t GetIndexSize(int table_len) { 51 size_t GetIndexSize(int table_len) {
53 size_t table_size = sizeof(disk_cache::CacheAddr) * table_len; 52 size_t table_size = sizeof(disk_cache::CacheAddr) * table_len;
54 return sizeof(disk_cache::IndexHeader) + table_size; 53 return sizeof(disk_cache::IndexHeader) + table_size;
55 } 54 }
56 55
57 int LowWaterAdjust(int high_water) {
58 if (high_water < kCleanUpMargin)
59 return 0;
60
61 return high_water - kCleanUpMargin;
62 }
63
64 // ------------------------------------------------------------------------ 56 // ------------------------------------------------------------------------
65 57
66 // Returns a fully qualified name from path and name, using a given name prefix 58 // Returns a fully qualified name from path and name, using a given name prefix
67 // and index number. For instance, if the arguments are "/foo", "bar" and 5, it 59 // and index number. For instance, if the arguments are "/foo", "bar" and 5, it
68 // will return "/foo/old_bar_005". 60 // will return "/foo/old_bar_005".
69 std::wstring GetPrefixedName(const std::wstring& path, const std::wstring& name, 61 std::wstring GetPrefixedName(const std::wstring& path, const std::wstring& name,
70 int index) { 62 int index) {
71 std::wstring prefixed(path); 63 std::wstring prefixed(path);
72 std::wstring tmp = StringPrintf(L"%ls%ls_%03d", L"old_", name.c_str(), index); 64 std::wstring tmp = StringPrintf(L"%ls%ls_%03d", L"old_", name.c_str(), index);
73 file_util::AppendToPath(&prefixed, tmp); 65 file_util::AppendToPath(&prefixed, tmp);
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 233
242 if (!block_files_.Init(create_files)) 234 if (!block_files_.Init(create_files))
243 return false; 235 return false;
244 236
245 // stats_ and rankings_ may end up calling back to us so we better be enabled. 237 // stats_ and rankings_ may end up calling back to us so we better be enabled.
246 disabled_ = false; 238 disabled_ = false;
247 if (!stats_.Init(this, &data_->header.stats)) 239 if (!stats_.Init(this, &data_->header.stats))
248 return false; 240 return false;
249 241
250 disabled_ = !rankings_.Init(this); 242 disabled_ = !rankings_.Init(this);
243 eviction_.Init(this);
251 244
252 return !disabled_; 245 return !disabled_;
253 } 246 }
254 247
255 BackendImpl::~BackendImpl() { 248 BackendImpl::~BackendImpl() {
256 Trace("Backend destructor"); 249 Trace("Backend destructor");
257 if (!init_) 250 if (!init_)
258 return; 251 return;
259 252
260 if (data_) 253 if (data_)
(...skipping 19 matching lines...) Expand all
280 273
281 Time start = Time::Now(); 274 Time start = Time::Now();
282 uint32 hash = Hash(key); 275 uint32 hash = Hash(key);
283 276
284 EntryImpl* cache_entry = MatchEntry(key, hash, false); 277 EntryImpl* cache_entry = MatchEntry(key, hash, false);
285 if (!cache_entry) { 278 if (!cache_entry) {
286 stats_.OnEvent(Stats::OPEN_MISS); 279 stats_.OnEvent(Stats::OPEN_MISS);
287 return false; 280 return false;
288 } 281 }
289 282
283 eviction_.OnOpenEntry(cache_entry);
290 DCHECK(entry); 284 DCHECK(entry);
291 *entry = cache_entry; 285 *entry = cache_entry;
292 286
293 UMA_HISTOGRAM_TIMES(L"DiskCache.OpenTime", Time::Now() - start); 287 UMA_HISTOGRAM_TIMES(L"DiskCache.OpenTime", Time::Now() - start);
294 stats_.OnEvent(Stats::OPEN_HIT); 288 stats_.OnEvent(Stats::OPEN_HIT);
295 return true; 289 return true;
296 } 290 }
297 291
298 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { 292 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) {
299 if (disabled_ || key.empty()) 293 if (disabled_ || key.empty())
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 } 342 }
349 343
350 if (parent.get()) 344 if (parent.get())
351 parent->SetNextAddress(entry_address); 345 parent->SetNextAddress(entry_address);
352 346
353 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); 347 block_files_.GetFile(entry_address)->Store(cache_entry->entry());
354 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); 348 block_files_.GetFile(node_address)->Store(cache_entry->rankings());
355 349
356 data_->header.num_entries++; 350 data_->header.num_entries++;
357 DCHECK(data_->header.num_entries > 0); 351 DCHECK(data_->header.num_entries > 0);
358 rankings_.Insert(cache_entry->rankings(), true, Rankings::NO_USE); 352 eviction_.OnCreateEntry(cache_entry);
359 if (!parent.get()) 353 if (!parent.get())
360 data_->table[hash & mask_] = entry_address.value(); 354 data_->table[hash & mask_] = entry_address.value();
361 355
362 DCHECK(entry); 356 DCHECK(entry);
363 *entry = NULL; 357 *entry = NULL;
364 cache_entry.swap(reinterpret_cast<EntryImpl**>(entry)); 358 cache_entry.swap(reinterpret_cast<EntryImpl**>(entry));
365 359
366 UMA_HISTOGRAM_TIMES(L"DiskCache.CreateTime", Time::Now() - start); 360 UMA_HISTOGRAM_TIMES(L"DiskCache.CreateTime", Time::Now() - start);
367 stats_.OnEvent(Stats::CREATE_HIT); 361 stats_.OnEvent(Stats::CREATE_HIT);
368 Trace("create entry hit "); 362 Trace("create entry hit ");
(...skipping 18 matching lines...) Expand all
387 381
388 bool BackendImpl::DoomAllEntries() { 382 bool BackendImpl::DoomAllEntries() {
389 if (!num_refs_) { 383 if (!num_refs_) {
390 PrepareForRestart(); 384 PrepareForRestart();
391 DeleteCache(path_.c_str(), false); 385 DeleteCache(path_.c_str(), false);
392 return Init(); 386 return Init();
393 } else { 387 } else {
394 if (disabled_) 388 if (disabled_)
395 return false; 389 return false;
396 390
397 TrimCache(true); 391 eviction_.TrimCache(true);
398 stats_.OnEvent(Stats::DOOM_CACHE); 392 stats_.OnEvent(Stats::DOOM_CACHE);
399 return true; 393 return true;
400 } 394 }
401 } 395 }
402 396
403 bool BackendImpl::DoomEntriesBetween(const Time initial_time, 397 bool BackendImpl::DoomEntriesBetween(const Time initial_time,
404 const Time end_time) { 398 const Time end_time) {
405 if (end_time.is_null()) 399 if (end_time.is_null())
406 return DoomEntriesSince(initial_time); 400 return DoomEntriesSince(initial_time);
407 401
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 void BackendImpl::DeleteBlock(Addr block_address, bool deep) { 562 void BackendImpl::DeleteBlock(Addr block_address, bool deep) {
569 block_files_.DeleteBlock(block_address, deep); 563 block_files_.DeleteBlock(block_address, deep);
570 } 564 }
571 565
572 LruData* BackendImpl::GetLruData() { 566 LruData* BackendImpl::GetLruData() {
573 return &data_->header.lru; 567 return &data_->header.lru;
574 } 568 }
575 569
576 void BackendImpl::UpdateRank(EntryImpl* entry, bool modified) { 570 void BackendImpl::UpdateRank(EntryImpl* entry, bool modified) {
577 if (!read_only_) { 571 if (!read_only_) {
578 rankings_.UpdateRank(entry->rankings(), modified, Rankings::NO_USE); 572 eviction_.UpdateRank(entry, modified);
579 } 573 }
580 } 574 }
581 575
582 void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) { 576 void BackendImpl::RecoveredEntry(CacheRankingsBlock* rankings) {
583 Addr address(rankings->Data()->contents); 577 Addr address(rankings->Data()->contents);
584 EntryImpl* cache_entry = NULL; 578 EntryImpl* cache_entry = NULL;
585 bool dirty; 579 bool dirty;
586 if (NewEntry(address, &cache_entry, &dirty)) 580 if (NewEntry(address, &cache_entry, &dirty))
587 return; 581 return;
588 582
589 uint32 hash = cache_entry->GetHash(); 583 uint32 hash = cache_entry->GetHash();
590 cache_entry->Release(); 584 cache_entry->Release();
591 585
592 // Anything on the table means that this entry is there. 586 // Anything on the table means that this entry is there.
593 if (data_->table[hash & mask_]) 587 if (data_->table[hash & mask_])
594 return; 588 return;
595 589
596 data_->table[hash & mask_] = address.value(); 590 data_->table[hash & mask_] = address.value();
597 } 591 }
598 592
599 void BackendImpl::InternalDoomEntry(EntryImpl* entry) { 593 void BackendImpl::InternalDoomEntry(EntryImpl* entry) {
600 uint32 hash = entry->GetHash(); 594 uint32 hash = entry->GetHash();
601 std::string key = entry->GetKey(); 595 std::string key = entry->GetKey();
602 EntryImpl* parent_entry = MatchEntry(key, hash, true); 596 EntryImpl* parent_entry = MatchEntry(key, hash, true);
603 CacheAddr child(entry->GetNextAddress()); 597 CacheAddr child(entry->GetNextAddress());
604 598
605 Trace("Doom entry 0x%p", entry); 599 Trace("Doom entry 0x%p", entry);
606 600
607 rankings_.Remove(entry->rankings(), Rankings::NO_USE); 601 eviction_.OnDoomEntry(entry);
608
609 entry->InternalDoom(); 602 entry->InternalDoom();
610 603
611 if (parent_entry) { 604 if (parent_entry) {
612 parent_entry->SetNextAddress(Addr(child)); 605 parent_entry->SetNextAddress(Addr(child));
613 parent_entry->Release(); 606 parent_entry->Release();
614 } else { 607 } else {
615 data_->table[hash & mask_] = child; 608 data_->table[hash & mask_] = child;
616 } 609 }
617 610
618 data_->header.num_entries--; 611 data_->header.num_entries--;
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 1006
1014 entry.swap(reinterpret_cast<EntryImpl**>(next_entry)); 1007 entry.swap(reinterpret_cast<EntryImpl**>(next_entry));
1015 *iter = next.release(); 1008 *iter = next.release();
1016 return true; 1009 return true;
1017 } 1010 }
1018 1011
1019 void BackendImpl::DestroyInvalidEntry(Addr address, EntryImpl* entry) { 1012 void BackendImpl::DestroyInvalidEntry(Addr address, EntryImpl* entry) {
1020 LOG(WARNING) << "Destroying invalid entry."; 1013 LOG(WARNING) << "Destroying invalid entry.";
1021 Trace("Destroying invalid entry 0x%p", entry); 1014 Trace("Destroying invalid entry 0x%p", entry);
1022 1015
1023 rankings_.Remove(entry->rankings(), Rankings::NO_USE);
1024 entry->SetPointerForInvalidEntry(GetCurrentEntryId()); 1016 entry->SetPointerForInvalidEntry(GetCurrentEntryId());
1025 1017
1018 eviction_.OnDoomEntry(entry);
1026 entry->InternalDoom(); 1019 entry->InternalDoom();
1027 1020
1028 data_->header.num_entries--; 1021 data_->header.num_entries--;
1029 DCHECK(data_->header.num_entries >= 0); 1022 DCHECK(data_->header.num_entries >= 0);
1030 stats_.OnEvent(Stats::INVALID_ENTRY); 1023 stats_.OnEvent(Stats::INVALID_ENTRY);
1031 } 1024 }
1032 1025
1033 void BackendImpl::TrimCache(bool empty) {
1034 Trace("*** Trim Cache ***");
1035 if (disabled_)
1036 return;
1037
1038 Time start = Time::Now();
1039 Rankings::ScopedRankingsBlock node(&rankings_);
1040 Rankings::ScopedRankingsBlock next(&rankings_,
1041 rankings_.GetPrev(node.get(), Rankings::NO_USE));
1042 DCHECK(next.get());
1043 int target_size = empty ? 0 : LowWaterAdjust(max_size_);
1044 int deleted = 0;
1045 while (data_->header.num_bytes > target_size && next.get()) {
1046 node.reset(next.release());
1047 next.reset(rankings_.GetPrev(node.get(), Rankings::NO_USE));
1048 if (!node->Data()->pointer || empty) {
1049 // This entry is not being used by anybody.
1050 EntryImpl* entry;
1051 bool dirty;
1052 if (NewEntry(Addr(node->Data()->contents), &entry, &dirty)) {
1053 Trace("NewEntry failed on Trim 0x%x", node->address().value());
1054 continue;
1055 }
1056
1057 if (node->Data()->pointer) {
1058 entry = EntryImpl::Update(entry);
1059 }
1060 ReportTrimTimes(entry);
1061 entry->Doom();
1062 entry->Release();
1063 if (!empty)
1064 stats_.OnEvent(Stats::TRIM_ENTRY);
1065 if (++deleted == 4 && !empty) {
1066 #if defined(OS_WIN)
1067 MessageLoop::current()->PostTask(FROM_HERE,
1068 factory_.NewRunnableMethod(&BackendImpl::TrimCache, false));
1069 break;
1070 #endif
1071 }
1072 }
1073 }
1074
1075 UMA_HISTOGRAM_TIMES(L"DiskCache.TotalTrimTime", Time::Now() - start);
1076 Trace("*** Trim Cache end ***");
1077 return;
1078 }
1079
1080 void BackendImpl::ReportTrimTimes(EntryImpl* entry) {
1081 static bool first_time = true;
1082 if (first_time) {
1083 first_time = false;
1084 std::wstring name(StringPrintf(L"DiskCache.TrimAge_%d",
1085 data_->header.experiment));
1086 static Histogram counter(name.c_str(), 1, 10000, 50);
1087 counter.SetFlags(kUmaTargetedHistogramFlag);
1088 counter.Add((Time::Now() - entry->GetLastUsed()).InHours());
1089 }
1090 }
1091
1092 void BackendImpl::AddStorageSize(int32 bytes) { 1026 void BackendImpl::AddStorageSize(int32 bytes) {
1093 data_->header.num_bytes += bytes; 1027 data_->header.num_bytes += bytes;
1094 DCHECK(data_->header.num_bytes >= 0); 1028 DCHECK(data_->header.num_bytes >= 0);
1095 1029
1096 if (data_->header.num_bytes > max_size_) 1030 if (data_->header.num_bytes > max_size_)
1097 TrimCache(false); 1031 eviction_.TrimCache(false);
1098 } 1032 }
1099 1033
1100 void BackendImpl::SubstractStorageSize(int32 bytes) { 1034 void BackendImpl::SubstractStorageSize(int32 bytes) {
1101 data_->header.num_bytes -= bytes; 1035 data_->header.num_bytes -= bytes;
1102 DCHECK(data_->header.num_bytes >= 0); 1036 DCHECK(data_->header.num_bytes >= 0);
1103 } 1037 }
1104 1038
1105 void BackendImpl::IncreaseNumRefs() { 1039 void BackendImpl::IncreaseNumRefs() {
1106 num_refs_++; 1040 num_refs_++;
1107 if (max_refs_ < num_refs_) 1041 if (max_refs_ < num_refs_)
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 1145
1212 return num_dirty; 1146 return num_dirty;
1213 } 1147 }
1214 1148
1215 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { 1149 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) {
1216 RankingsNode* rankings = cache_entry->rankings()->Data(); 1150 RankingsNode* rankings = cache_entry->rankings()->Data();
1217 return !rankings->pointer; 1151 return !rankings->pointer;
1218 } 1152 }
1219 1153
1220 } // namespace disk_cache 1154 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/backend_impl.h ('k') | net/disk_cache/eviction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698