1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/stats.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/format_macros.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/backend_impl.h" 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int32 kDiskSignature = 0xF01427E0; 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct OnDiskStats { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 signature; 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int size; 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data_sizes[disk_cache::Stats::kDataSizesLength]; 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 counters[disk_cache::Stats::MAX_COUNTER]; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 233f50c38dc070f4bb515c1b64450dae14f316474eKristian MonsenCOMPILE_ASSERT(sizeof(OnDiskStats) < 512, needs_more_than_2_blocks); 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns the "floor" (as opposed to "ceiling") of log base 2 of number. 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint LogBase2(int32 number) { 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int value = static_cast<unsigned int>(number); 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const unsigned int mask[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const unsigned int s[] = {1, 2, 4, 8, 16}; 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott unsigned int result = 0; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 4; i >= 0; i--) { 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (value & mask[i]) { 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott value >>= s[i]; 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result |= s[i]; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return static_cast<int>(result); 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// WARNING: Add new stats only at the end, or change LoadStats(). 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic const char* kCounterNames[] = { 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Open miss", 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Open hit", 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Create miss", 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Create hit", 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Resurrect hit", 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Create error", 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Trim entry", 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Doom entry", 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Doom cache", 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Invalid entry", 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Open entries", 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Max entries", 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Timer", 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Read data", 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Write data", 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Open rankings", 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Get rankings", 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Fatal error", 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "Last report", 623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen "Last report timer", 633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen "Doom recent entries" 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCOMPILE_ASSERT(arraysize(kCounterNames) == disk_cache::Stats::MAX_COUNTER, 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott update_the_names); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache { 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool LoadStats(BackendImpl* backend, Addr address, OnDiskStats* stats) { 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MappedFile* file = backend->File(address); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file) 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t offset = address.start_block() * address.BlockSize() + 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kBlockHeaderSize; 793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen memset(stats, 0, sizeof(*stats)); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file->Read(stats, sizeof(*stats), offset)) 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (stats->signature != kDiskSignature) 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We don't want to discard the whole cache every time we have one extra 873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // counter; we keep old data if we can. 883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (static_cast<unsigned int>(stats->size) > sizeof(*stats)) { 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(stats, 0, sizeof(*stats)); 903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool StoreStats(BackendImpl* backend, Addr address, OnDiskStats* stats) { 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MappedFile* file = backend->File(address); 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!file) 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t offset = address.start_block() * address.BlockSize() + 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kBlockHeaderSize; 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return file->Write(stats, sizeof(*stats), offset); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool CreateStats(BackendImpl* backend, Addr* address, OnDiskStats* stats) { 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!backend->CreateBlock(BLOCK_256, 2, address)) 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we have more than 512 bytes of counters, change kDiskSignature so we 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // don't overwrite something else (LoadStats must fail). 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott COMPILE_ASSERT(sizeof(*stats) <= 256 * 2, use_more_blocks); 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(stats, 0, sizeof(*stats)); 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats->signature = kDiskSignature; 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats->size = sizeof(*stats); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return StoreStats(backend, *address, stats); 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenStats::Stats() : backend_(NULL), size_histogram_(NULL) { 12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenStats::~Stats() { 12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Stats::Init(BackendImpl* backend, uint32* storage_addr) { 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnDiskStats stats; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(*storage_addr); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (address.is_initialized()) { 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!LoadStats(backend, address, &stats)) 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!CreateStats(backend, &address, &stats)) 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *storage_addr = address.value(); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott storage_addr_ = address.value(); 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott backend_ = backend; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(data_sizes_, stats.data_sizes, sizeof(data_sizes_)); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(counters_, stats.counters, sizeof(counters_)); 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // It seems impossible to support this histogram for more than one 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // simultaneous objects with the current infrastructure. 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool first_time = true; 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (first_time) { 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott first_time = false; 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // ShouldReportAgain() will re-enter this object. 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!size_histogram_ && backend->cache_type() == net::DISK_CACHE && 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott backend->ShouldReportAgain()) { 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Stats may be reused when the cache is re-created, but we want only one 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // histogram at any given time. 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_histogram_ = 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StatsHistogram::StatsHistogramFactoryGet("DiskCache.SizeStats"); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_histogram_->Init(this); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Stats::ModifyStorageStats(int32 old_size, int32 new_size) { 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We keep a counter of the data block size on an array where each entry is 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // the adjusted log base 2 of the size. The first entry counts blocks of 256 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // bytes, the second blocks up to 512 bytes, etc. With 20 entries, the last 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // one stores entries of more than 64 MB 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int new_index = GetStatsBucket(new_size); 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int old_index = GetStatsBucket(old_size); 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (new_size) 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_sizes_[new_index]++; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (old_size) 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott data_sizes_[old_index]--; 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Stats::OnEvent(Counters an_event) { 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(an_event > MIN_COUNTER || an_event < MAX_COUNTER); 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott counters_[an_event]++; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Stats::SetCounter(Counters counter, int64 value) { 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(counter > MIN_COUNTER || counter < MAX_COUNTER); 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott counters_[counter] = value; 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint64 Stats::GetCounter(Counters counter) const { 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(counter > MIN_COUNTER || counter < MAX_COUNTER); 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return counters_[counter]; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Stats::GetItems(StatsItems* items) { 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::pair<std::string, std::string> item; 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kDataSizesLength; i++) { 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick item.first = base::StringPrintf("Size%02d", i); 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick item.second = base::StringPrintf("0x%08x", data_sizes_[i]); 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott items->push_back(item); 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = MIN_COUNTER + 1; i < MAX_COUNTER; i++) { 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott item.first = kCounterNames[i]; 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick item.second = base::StringPrintf("0x%" PRIx64, counters_[i]); 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott items->push_back(item); 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint Stats::GetHitRatio() const { 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return GetRatio(OPEN_HIT, OPEN_MISS); 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint Stats::GetResurrectRatio() const { 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return GetRatio(RESURRECT_HIT, CREATE_HIT); 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Stats::ResetRatios() { 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetCounter(OPEN_HIT, 0); 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetCounter(OPEN_MISS, 0); 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetCounter(RESURRECT_HIT, 0); 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetCounter(CREATE_HIT, 0); 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint Stats::GetLargeEntriesSize() { 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int total = 0; 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // data_sizes_[20] stores values between 512 KB and 1 MB (see comment before 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // GetStatsBucket()). 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int bucket = 20; bucket < kDataSizesLength; bucket++) 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott total += data_sizes_[bucket] * GetBucketRange(bucket); 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return total; 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Stats::Store() { 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!backend_) 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OnDiskStats stats; 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats.signature = kDiskSignature; 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stats.size = sizeof(stats); 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(stats.data_sizes, data_sizes_, sizeof(data_sizes_)); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(stats.counters, counters_, sizeof(counters_)); 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(storage_addr_); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StoreStats(backend_, address, &stats); 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint Stats::GetBucketRange(size_t i) const { 24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i < 2) 24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return static_cast<int>(1024 * i); 24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i < 12) 25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return static_cast<int>(2048 * (i - 1)); 25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i < 17) 25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return static_cast<int>(4096 * (i - 11)) + 20 * 1024; 25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int n = 64 * 1024; 25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i > static_cast<size_t>(kDataSizesLength)) { 25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED(); 25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen i = kDataSizesLength; 26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen i -= 17; 26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen n <<= i; 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return n; 26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Stats::Snapshot(StatsHistogram::StatsSamples* samples) const { 26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen samples->GetCounts()->resize(kDataSizesLength); 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (int i = 0; i < kDataSizesLength; i++) { 27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int count = data_sizes_[i]; 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (count < 0) 27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen count = 0; 27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen samples->GetCounts()->at(i) = count; 27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The array will be filled this way: 27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// index size 27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 0 [0, 1024) 28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 1 [1024, 2048) 28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 2 [2048, 4096) 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 3 [4K, 6K) 28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ... 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 10 [18K, 20K) 28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 11 [20K, 24K) 28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 12 [24k, 28K) 28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ... 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 15 [36k, 40K) 28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 16 [40k, 64K) 29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 17 [64K, 128K) 29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 18 [128K, 256K) 29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ... 29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 23 [4M, 8M) 29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 24 [8M, 16M) 29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 25 [16M, 32M) 29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 26 [32M, 64M) 29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// 27 [64M, ...) 29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint Stats::GetStatsBucket(int32 size) { 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (size < 1024) 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return 0; 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 10 slots more, until 20K. 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (size < 20 * 1024) 30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return size / 2048 + 1; 30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // 5 slots more, from 20K to 40K. 30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (size < 40 * 1024) 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return (size - 20 * 1024) / 4096 + 11; 30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // From this point on, use a logarithmic scale. 31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int result = LogBase2(size) + 1; 31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen COMPILE_ASSERT(kDataSizesLength > 16, update_the_scale); 31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (result >= kDataSizesLength) 31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = kDataSizesLength - 1; 31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint Stats::GetRatio(Counters hit, Counters miss) const { 32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int64 ratio = GetCounter(hit) * 100; 32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ratio) 32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return 0; 32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ratio /= (GetCounter(hit) + GetCounter(miss)); 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return static_cast<int>(ratio); 32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace disk_cache 330