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 #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 // Uncomment this to use the new eviction algorithm. | 20 // Uncomment this to use the new eviction algorithm. |
21 // #define USE_NEW_EVICTION | 21 // #define USE_NEW_EVICTION |
22 | 22 |
| 23 // This has to be defined before including histogram_macros.h from this file. |
| 24 #define NET_DISK_CACHE_BACKEND_IMPL_CC_ |
| 25 #include "net/disk_cache/histogram_macros.h" |
| 26 |
23 using base::Time; | 27 using base::Time; |
24 using base::TimeDelta; | 28 using base::TimeDelta; |
25 | 29 |
26 // HISTOGRAM_HOURS will collect time related data with a granularity of hours | |
27 // and normal values of a few months. | |
28 #define UMA_HISTOGRAM_HOURS UMA_HISTOGRAM_COUNTS_10000 | |
29 | |
30 namespace { | 30 namespace { |
31 | 31 |
32 const wchar_t* kIndexName = L"index"; | 32 const wchar_t* kIndexName = L"index"; |
33 const int kMaxOldFolders = 100; | 33 const int kMaxOldFolders = 100; |
34 | 34 |
35 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people. | 35 // Seems like ~240 MB correspond to less than 50k entries for 99% of the people. |
36 const int k64kEntriesStore = 240 * 1000 * 1000; | 36 const int k64kEntriesStore = 240 * 1000 * 1000; |
37 const int kBaseTableLen = 64 * 1024; | 37 const int kBaseTableLen = 64 * 1024; |
38 const int kDefaultCacheSize = 80 * 1024 * 1024; | 38 const int kDefaultCacheSize = 80 * 1024 * 1024; |
39 | 39 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 // The entry was already evicted. | 299 // The entry was already evicted. |
300 cache_entry->Release(); | 300 cache_entry->Release(); |
301 stats_.OnEvent(Stats::OPEN_MISS); | 301 stats_.OnEvent(Stats::OPEN_MISS); |
302 return false; | 302 return false; |
303 } | 303 } |
304 | 304 |
305 eviction_.OnOpenEntry(cache_entry); | 305 eviction_.OnOpenEntry(cache_entry); |
306 DCHECK(entry); | 306 DCHECK(entry); |
307 *entry = cache_entry; | 307 *entry = cache_entry; |
308 | 308 |
309 UMA_HISTOGRAM_TIMES("DiskCache.OpenTime", Time::Now() - start); | 309 CACHE_UMA(AGE_MS, "OpenTime", 0, start); |
310 stats_.OnEvent(Stats::OPEN_HIT); | 310 stats_.OnEvent(Stats::OPEN_HIT); |
311 return true; | 311 return true; |
312 } | 312 } |
313 | 313 |
314 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { | 314 bool BackendImpl::CreateEntry(const std::string& key, Entry** entry) { |
315 if (disabled_ || key.empty()) | 315 if (disabled_ || key.empty()) |
316 return false; | 316 return false; |
317 | 317 |
318 DCHECK(entry); | 318 DCHECK(entry); |
319 *entry = NULL; | 319 *entry = NULL; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); | 377 block_files_.GetFile(entry_address)->Store(cache_entry->entry()); |
378 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); | 378 block_files_.GetFile(node_address)->Store(cache_entry->rankings()); |
379 | 379 |
380 IncreaseNumEntries(); | 380 IncreaseNumEntries(); |
381 eviction_.OnCreateEntry(cache_entry); | 381 eviction_.OnCreateEntry(cache_entry); |
382 if (!parent.get()) | 382 if (!parent.get()) |
383 data_->table[hash & mask_] = entry_address.value(); | 383 data_->table[hash & mask_] = entry_address.value(); |
384 | 384 |
385 cache_entry.swap(reinterpret_cast<EntryImpl**>(entry)); | 385 cache_entry.swap(reinterpret_cast<EntryImpl**>(entry)); |
386 | 386 |
387 UMA_HISTOGRAM_TIMES("DiskCache.CreateTime", Time::Now() - start); | 387 CACHE_UMA(AGE_MS, "CreateTime", 0, start); |
388 stats_.OnEvent(Stats::CREATE_HIT); | 388 stats_.OnEvent(Stats::CREATE_HIT); |
389 Trace("create entry hit "); | 389 Trace("create entry hit "); |
390 return true; | 390 return true; |
391 } | 391 } |
392 | 392 |
393 bool BackendImpl::DoomEntry(const std::string& key) { | 393 bool BackendImpl::DoomEntry(const std::string& key) { |
394 if (disabled_) | 394 if (disabled_) |
395 return false; | 395 return false; |
396 | 396 |
397 Entry* entry; | 397 Entry* entry; |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 AddStorageSize(new_size - old_size); | 681 AddStorageSize(new_size - old_size); |
682 | 682 |
683 // Update the usage statistics. | 683 // Update the usage statistics. |
684 stats_.ModifyStorageStats(old_size, new_size); | 684 stats_.ModifyStorageStats(old_size, new_size); |
685 } | 685 } |
686 | 686 |
687 void BackendImpl::TooMuchStorageRequested(int32 size) { | 687 void BackendImpl::TooMuchStorageRequested(int32 size) { |
688 stats_.ModifyStorageStats(0, size); | 688 stats_.ModifyStorageStats(0, size); |
689 } | 689 } |
690 | 690 |
| 691 std::string BackendImpl::HistogramName(const char* name, int experiment) { |
| 692 if (!experiment) |
| 693 return StringPrintf("DiskCache.%d.%s", cache_type_, name); |
| 694 return StringPrintf("DiskCache.%d.%s_%d", cache_type_, name, experiment); |
| 695 } |
| 696 |
691 // We want to remove biases from some histograms so we only send data once per | 697 // We want to remove biases from some histograms so we only send data once per |
692 // week. | 698 // week. |
693 bool BackendImpl::ShouldReportAgain() { | 699 bool BackendImpl::ShouldReportAgain() { |
694 if (uma_report_) | 700 if (uma_report_) |
695 return uma_report_ == 2; | 701 return uma_report_ == 2; |
696 | 702 |
697 uma_report_++; | 703 uma_report_++; |
698 int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); | 704 int64 last_report = stats_.GetCounter(Stats::LAST_REPORT); |
699 Time last_time = Time::FromInternalValue(last_report); | 705 Time last_time = Time::FromInternalValue(last_report); |
700 if (!last_report || (Time::Now() - last_time).InDays() >= 7) { | 706 if (!last_report || (Time::Now() - last_time).InDays() >= 7) { |
701 stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue()); | 707 stats_.SetCounter(Stats::LAST_REPORT, Time::Now().ToInternalValue()); |
702 uma_report_++; | 708 uma_report_++; |
703 return true; | 709 return true; |
704 } | 710 } |
705 return false; | 711 return false; |
706 } | 712 } |
707 | 713 |
708 void BackendImpl::FirstEviction() { | 714 void BackendImpl::FirstEviction() { |
709 DCHECK(data_->header.create_time); | 715 DCHECK(data_->header.create_time); |
710 | 716 |
711 Time create_time = Time::FromInternalValue(data_->header.create_time); | 717 Time create_time = Time::FromInternalValue(data_->header.create_time); |
712 UMA_HISTOGRAM_HOURS("DiskCache.FillupAge", | 718 CACHE_UMA(AGE, "FillupAge", 0, create_time); |
713 (Time::Now() - create_time).InHours()); | |
714 | 719 |
715 int64 use_hours = stats_.GetCounter(Stats::TIMER) / 120; | 720 int64 use_hours = stats_.GetCounter(Stats::TIMER) / 120; |
716 UMA_HISTOGRAM_HOURS("DiskCache.FillupTime", static_cast<int>(use_hours)); | 721 CACHE_UMA(HOURS, "FillupTime", 0, static_cast<int>(use_hours)); |
717 UMA_HISTOGRAM_PERCENTAGE("DiskCache.FirstHitRatio", stats_.GetHitRatio()); | 722 CACHE_UMA(PERCENTAGE, "FirstHitRatio", 0, stats_.GetHitRatio()); |
718 | 723 |
719 int avg_size = data_->header.num_bytes / GetEntryCount(); | 724 int avg_size = data_->header.num_bytes / GetEntryCount(); |
720 UMA_HISTOGRAM_COUNTS("DiskCache.FirstEntrySize", avg_size); | 725 CACHE_UMA(COUNTS, "FirstEntrySize", 0, avg_size); |
721 | 726 |
722 int large_entries_bytes = stats_.GetLargeEntriesSize(); | 727 int large_entries_bytes = stats_.GetLargeEntriesSize(); |
723 int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; | 728 int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; |
724 UMA_HISTOGRAM_PERCENTAGE("DiskCache.FirstLargeEntriesRatio", large_ratio); | 729 CACHE_UMA(PERCENTAGE, "FirstLargeEntriesRatio", 0, large_ratio); |
725 stats_.ResetRatios(); | 730 stats_.ResetRatios(); |
726 } | 731 } |
727 | 732 |
728 void BackendImpl::CriticalError(int error) { | 733 void BackendImpl::CriticalError(int error) { |
729 LOG(ERROR) << "Critical error found " << error; | 734 LOG(ERROR) << "Critical error found " << error; |
730 if (disabled_) | 735 if (disabled_) |
731 return; | 736 return; |
732 | 737 |
733 LogStats(); | 738 LogStats(); |
734 ReportError(error); | 739 ReportError(error); |
735 | 740 |
736 // Setting the index table length to an invalid value will force re-creation | 741 // Setting the index table length to an invalid value will force re-creation |
737 // of the cache files. | 742 // of the cache files. |
738 data_->header.table_len = 1; | 743 data_->header.table_len = 1; |
739 disabled_ = true; | 744 disabled_ = true; |
740 | 745 |
741 if (!num_refs_) | 746 if (!num_refs_) |
742 RestartCache(); | 747 RestartCache(); |
743 } | 748 } |
744 | 749 |
745 void BackendImpl::ReportError(int error) { | 750 void BackendImpl::ReportError(int error) { |
746 static LinearHistogram counter("DiskCache.Error", 0, 49, 50); | |
747 counter.SetFlags(kUmaTargetedHistogramFlag); | |
748 | |
749 // We transmit positive numbers, instead of direct error codes. | 751 // We transmit positive numbers, instead of direct error codes. |
750 DCHECK(error <= 0); | 752 DCHECK(error <= 0); |
751 counter.Add(error * -1); | 753 CACHE_UMA(CACHE_ERROR, "Error", 0, error * -1); |
752 } | 754 } |
753 | 755 |
754 void BackendImpl::OnEvent(Stats::Counters an_event) { | 756 void BackendImpl::OnEvent(Stats::Counters an_event) { |
755 stats_.OnEvent(an_event); | 757 stats_.OnEvent(an_event); |
756 } | 758 } |
757 | 759 |
758 void BackendImpl::OnStatsTimer() { | 760 void BackendImpl::OnStatsTimer() { |
759 stats_.OnEvent(Stats::TIMER); | 761 stats_.OnEvent(Stats::TIMER); |
760 int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES); | 762 int64 current = stats_.GetCounter(Stats::OPEN_ENTRIES); |
761 int64 time = stats_.GetCounter(Stats::TIMER); | 763 int64 time = stats_.GetCounter(Stats::TIMER); |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 StatsItems stats; | 1268 StatsItems stats; |
1267 GetStats(&stats); | 1269 GetStats(&stats); |
1268 | 1270 |
1269 for (size_t index = 0; index < stats.size(); index++) { | 1271 for (size_t index = 0; index < stats.size(); index++) { |
1270 LOG(INFO) << stats[index].first << ": " << stats[index].second; | 1272 LOG(INFO) << stats[index].first << ": " << stats[index].second; |
1271 } | 1273 } |
1272 } | 1274 } |
1273 | 1275 |
1274 void BackendImpl::ReportStats() { | 1276 void BackendImpl::ReportStats() { |
1275 int experiment = data_->header.experiment; | 1277 int experiment = data_->header.experiment; |
1276 std::string entries(StringPrintf("DiskCache.Entries_%d", experiment)); | 1278 CACHE_UMA(COUNTS, "Entries", experiment, data_->header.num_entries); |
1277 std::string size(StringPrintf("DiskCache.Size_%d", experiment)); | 1279 CACHE_UMA(COUNTS, "Size", experiment, |
1278 std::string max_size(StringPrintf("DiskCache.MaxSize_%d", experiment)); | 1280 data_->header.num_bytes / (1024 * 1024)); |
1279 UMA_HISTOGRAM_COUNTS(entries.c_str(), data_->header.num_entries); | 1281 CACHE_UMA(COUNTS, "MaxSize", experiment, max_size_ / (1024 * 1024)); |
1280 UMA_HISTOGRAM_COUNTS(size.c_str(), data_->header.num_bytes / (1024 * 1024)); | |
1281 UMA_HISTOGRAM_COUNTS(max_size.c_str(), max_size_ / (1024 * 1024)); | |
1282 | 1282 |
1283 UMA_HISTOGRAM_COUNTS("DiskCache.AverageOpenEntries", | 1283 CACHE_UMA(COUNTS, "AverageOpenEntries", 0, |
1284 static_cast<int>(stats_.GetCounter(Stats::OPEN_ENTRIES))); | 1284 static_cast<int>(stats_.GetCounter(Stats::OPEN_ENTRIES))); |
1285 UMA_HISTOGRAM_COUNTS("DiskCache.MaxOpenEntries", | 1285 CACHE_UMA(COUNTS, "MaxOpenEntries", 0, |
1286 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); | 1286 static_cast<int>(stats_.GetCounter(Stats::MAX_ENTRIES))); |
1287 stats_.SetCounter(Stats::MAX_ENTRIES, 0); | 1287 stats_.SetCounter(Stats::MAX_ENTRIES, 0); |
1288 | 1288 |
1289 if (!data_->header.create_time) { | 1289 if (!data_->header.create_time) { |
1290 // This is a client running the experiment on the dev channel. | 1290 // This is a client running the experiment on the dev channel. |
1291 std::string hit_ratio(StringPrintf("DiskCache.HitRatio_%d", experiment)); | 1291 CACHE_UMA(PERCENTAGE, "HitRatio", experiment, stats_.GetHitRatio()); |
1292 UMA_HISTOGRAM_PERCENTAGE(hit_ratio.c_str(), stats_.GetHitRatio()); | |
1293 stats_.ResetRatios(); | 1292 stats_.ResetRatios(); |
1294 | 1293 |
1295 if (!data_->header.num_bytes) | 1294 if (!data_->header.num_bytes) |
1296 return; | 1295 return; |
1297 | 1296 |
1298 int large_entries_bytes = stats_.GetLargeEntriesSize(); | 1297 int large_entries_bytes = stats_.GetLargeEntriesSize(); |
1299 int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; | 1298 int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; |
1300 std::string large_ratio_name(StringPrintf("DiskCache.LargeEntriesRatio_%d", | 1299 CACHE_UMA(PERCENTAGE, "LargeEntriesRatio", experiment, large_ratio); |
1301 experiment)); | |
1302 UMA_HISTOGRAM_PERCENTAGE(large_ratio_name.c_str(), large_ratio); | |
1303 return; | 1300 return; |
1304 } | 1301 } |
1305 | 1302 |
1306 if (!data_->header.lru.filled) | 1303 if (!data_->header.lru.filled) |
1307 return; | 1304 return; |
1308 | 1305 |
1309 // This is an up to date client that will report FirstEviction() data. After | 1306 // This is an up to date client that will report FirstEviction() data. After |
1310 // that event, start reporting this: | 1307 // that event, start reporting this: |
1311 | 1308 |
1312 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; | 1309 int64 total_hours = stats_.GetCounter(Stats::TIMER) / 120; |
1313 UMA_HISTOGRAM_HOURS("DiskCache.TotalTime", static_cast<int>(total_hours)); | 1310 CACHE_UMA(HOURS, "TotalTime", 0, static_cast<int>(total_hours)); |
1314 | 1311 |
1315 int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; | 1312 int64 use_hours = stats_.GetCounter(Stats::LAST_REPORT_TIMER) / 120; |
1316 if (!use_hours || !GetEntryCount() || !data_->header.num_bytes) | 1313 if (!use_hours || !GetEntryCount() || !data_->header.num_bytes) |
1317 return; | 1314 return; |
1318 | 1315 |
1319 UMA_HISTOGRAM_HOURS("DiskCache.UseTime", static_cast<int>(use_hours)); | 1316 CACHE_UMA(HOURS, "UseTime", 0, static_cast<int>(use_hours)); |
1320 UMA_HISTOGRAM_PERCENTAGE("DiskCache.HitRatio", stats_.GetHitRatio()); | 1317 CACHE_UMA(PERCENTAGE, "HitRatio", 0, stats_.GetHitRatio()); |
1321 UMA_HISTOGRAM_PERCENTAGE("DiskCache.ResurrectRatio", | 1318 CACHE_UMA(PERCENTAGE, "ResurrectRatio", 0, stats_.GetResurrectRatio()); |
1322 stats_.GetResurrectRatio()); | |
1323 | 1319 |
1324 int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; | 1320 int64 trim_rate = stats_.GetCounter(Stats::TRIM_ENTRY) / use_hours; |
1325 UMA_HISTOGRAM_COUNTS("DiskCache.TrimRate", static_cast<int>(trim_rate)); | 1321 CACHE_UMA(COUNTS, "TrimRate", 0, static_cast<int>(trim_rate)); |
1326 | 1322 |
1327 int avg_size = data_->header.num_bytes / GetEntryCount(); | 1323 int avg_size = data_->header.num_bytes / GetEntryCount(); |
1328 UMA_HISTOGRAM_COUNTS("DiskCache.EntrySize", avg_size); | 1324 CACHE_UMA(COUNTS, "EntrySize", 0, avg_size); |
1329 | 1325 |
1330 int large_entries_bytes = stats_.GetLargeEntriesSize(); | 1326 int large_entries_bytes = stats_.GetLargeEntriesSize(); |
1331 int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; | 1327 int large_ratio = large_entries_bytes * 100 / data_->header.num_bytes; |
1332 UMA_HISTOGRAM_PERCENTAGE("DiskCache.LargeEntriesRatio", large_ratio); | 1328 CACHE_UMA(PERCENTAGE, "LargeEntriesRatio", 0, large_ratio); |
1333 | 1329 |
1334 stats_.ResetRatios(); | 1330 stats_.ResetRatios(); |
1335 stats_.SetCounter(Stats::TRIM_ENTRY, 0); | 1331 stats_.SetCounter(Stats::TRIM_ENTRY, 0); |
1336 stats_.SetCounter(Stats::LAST_REPORT_TIMER, 0); | 1332 stats_.SetCounter(Stats::LAST_REPORT_TIMER, 0); |
1337 } | 1333 } |
1338 | 1334 |
1339 void BackendImpl::UpgradeTo2_1() { | 1335 void BackendImpl::UpgradeTo2_1() { |
1340 // 2.1 is basically the same as 2.0, except that new fields are actually | 1336 // 2.1 is basically the same as 2.0, except that new fields are actually |
1341 // updated by the new eviction algorithm. | 1337 // updated by the new eviction algorithm. |
1342 DCHECK(0x20000 == data_->header.version); | 1338 DCHECK(0x20000 == data_->header.version); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1452 | 1448 |
1453 return num_dirty; | 1449 return num_dirty; |
1454 } | 1450 } |
1455 | 1451 |
1456 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { | 1452 bool BackendImpl::CheckEntry(EntryImpl* cache_entry) { |
1457 RankingsNode* rankings = cache_entry->rankings()->Data(); | 1453 RankingsNode* rankings = cache_entry->rankings()->Data(); |
1458 return !rankings->pointer; | 1454 return !rankings->pointer; |
1459 } | 1455 } |
1460 | 1456 |
1461 } // namespace disk_cache | 1457 } // namespace disk_cache |
OLD | NEW |