| 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 |