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