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

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

Issue 121643003: Reorganize net/disk_cache into backend specific directories. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix ios breakage Created 6 years, 10 months 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/stats.h ('k') | net/disk_cache/stats_histogram.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/disk_cache/stats.h"
6
7 #include "base/format_macros.h"
8 #include "base/logging.h"
9 #include "base/metrics/histogram_samples.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12
13 namespace {
14
15 const int32 kDiskSignature = 0xF01427E0;
16
17 struct OnDiskStats {
18 int32 signature;
19 int size;
20 int data_sizes[disk_cache::Stats::kDataSizesLength];
21 int64 counters[disk_cache::Stats::MAX_COUNTER];
22 };
23 COMPILE_ASSERT(sizeof(OnDiskStats) < 512, needs_more_than_2_blocks);
24
25 // Returns the "floor" (as opposed to "ceiling") of log base 2 of number.
26 int LogBase2(int32 number) {
27 unsigned int value = static_cast<unsigned int>(number);
28 const unsigned int mask[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
29 const unsigned int s[] = {1, 2, 4, 8, 16};
30
31 unsigned int result = 0;
32 for (int i = 4; i >= 0; i--) {
33 if (value & mask[i]) {
34 value >>= s[i];
35 result |= s[i];
36 }
37 }
38 return static_cast<int>(result);
39 }
40
41 // WARNING: Add new stats only at the end, or change LoadStats().
42 static const char* kCounterNames[] = {
43 "Open miss",
44 "Open hit",
45 "Create miss",
46 "Create hit",
47 "Resurrect hit",
48 "Create error",
49 "Trim entry",
50 "Doom entry",
51 "Doom cache",
52 "Invalid entry",
53 "Open entries",
54 "Max entries",
55 "Timer",
56 "Read data",
57 "Write data",
58 "Open rankings",
59 "Get rankings",
60 "Fatal error",
61 "Last report",
62 "Last report timer",
63 "Doom recent entries",
64 "unused"
65 };
66 COMPILE_ASSERT(arraysize(kCounterNames) == disk_cache::Stats::MAX_COUNTER,
67 update_the_names);
68
69 } // namespace
70
71 namespace disk_cache {
72
73 bool VerifyStats(OnDiskStats* stats) {
74 if (stats->signature != kDiskSignature)
75 return false;
76
77 // We don't want to discard the whole cache every time we have one extra
78 // counter; we keep old data if we can.
79 if (static_cast<unsigned int>(stats->size) > sizeof(*stats)) {
80 memset(stats, 0, sizeof(*stats));
81 stats->signature = kDiskSignature;
82 } else if (static_cast<unsigned int>(stats->size) != sizeof(*stats)) {
83 size_t delta = sizeof(*stats) - static_cast<unsigned int>(stats->size);
84 memset(reinterpret_cast<char*>(stats) + stats->size, 0, delta);
85 stats->size = sizeof(*stats);
86 }
87
88 return true;
89 }
90
91 Stats::Stats() : size_histogram_(NULL) {
92 }
93
94 Stats::~Stats() {
95 if (size_histogram_) {
96 size_histogram_->Disable();
97 }
98 }
99
100 bool Stats::Init(void* data, int num_bytes, Addr address) {
101 OnDiskStats local_stats;
102 OnDiskStats* stats = &local_stats;
103 if (!num_bytes) {
104 memset(stats, 0, sizeof(local_stats));
105 local_stats.signature = kDiskSignature;
106 local_stats.size = sizeof(local_stats);
107 } else if (num_bytes >= static_cast<int>(sizeof(*stats))) {
108 stats = reinterpret_cast<OnDiskStats*>(data);
109 if (!VerifyStats(stats))
110 return false;
111 } else {
112 return false;
113 }
114
115 storage_addr_ = address;
116
117 memcpy(data_sizes_, stats->data_sizes, sizeof(data_sizes_));
118 memcpy(counters_, stats->counters, sizeof(counters_));
119
120 // Clean up old value.
121 SetCounter(UNUSED, 0);
122 return true;
123 }
124
125 void Stats::InitSizeHistogram() {
126 // It seems impossible to support this histogram for more than one
127 // simultaneous objects with the current infrastructure.
128 static bool first_time = true;
129 if (first_time) {
130 first_time = false;
131 if (!size_histogram_) {
132 // Stats may be reused when the cache is re-created, but we want only one
133 // histogram at any given time.
134 size_histogram_ = StatsHistogram::FactoryGet("DiskCache.SizeStats", this);
135 }
136 }
137 }
138
139 int Stats::StorageSize() {
140 // If we have more than 512 bytes of counters, change kDiskSignature so we
141 // don't overwrite something else (LoadStats must fail).
142 COMPILE_ASSERT(sizeof(OnDiskStats) <= 256 * 2, use_more_blocks);
143 return 256 * 2;
144 }
145
146 void Stats::ModifyStorageStats(int32 old_size, int32 new_size) {
147 // We keep a counter of the data block size on an array where each entry is
148 // the adjusted log base 2 of the size. The first entry counts blocks of 256
149 // bytes, the second blocks up to 512 bytes, etc. With 20 entries, the last
150 // one stores entries of more than 64 MB
151 int new_index = GetStatsBucket(new_size);
152 int old_index = GetStatsBucket(old_size);
153
154 if (new_size)
155 data_sizes_[new_index]++;
156
157 if (old_size)
158 data_sizes_[old_index]--;
159 }
160
161 void Stats::OnEvent(Counters an_event) {
162 DCHECK(an_event >= MIN_COUNTER && an_event < MAX_COUNTER);
163 counters_[an_event]++;
164 }
165
166 void Stats::SetCounter(Counters counter, int64 value) {
167 DCHECK(counter >= MIN_COUNTER && counter < MAX_COUNTER);
168 counters_[counter] = value;
169 }
170
171 int64 Stats::GetCounter(Counters counter) const {
172 DCHECK(counter >= MIN_COUNTER && counter < MAX_COUNTER);
173 return counters_[counter];
174 }
175
176 void Stats::GetItems(StatsItems* items) {
177 std::pair<std::string, std::string> item;
178 for (int i = 0; i < kDataSizesLength; i++) {
179 item.first = base::StringPrintf("Size%02d", i);
180 item.second = base::StringPrintf("0x%08x", data_sizes_[i]);
181 items->push_back(item);
182 }
183
184 for (int i = MIN_COUNTER; i < MAX_COUNTER; i++) {
185 item.first = kCounterNames[i];
186 item.second = base::StringPrintf("0x%" PRIx64, counters_[i]);
187 items->push_back(item);
188 }
189 }
190
191 int Stats::GetHitRatio() const {
192 return GetRatio(OPEN_HIT, OPEN_MISS);
193 }
194
195 int Stats::GetResurrectRatio() const {
196 return GetRatio(RESURRECT_HIT, CREATE_HIT);
197 }
198
199 void Stats::ResetRatios() {
200 SetCounter(OPEN_HIT, 0);
201 SetCounter(OPEN_MISS, 0);
202 SetCounter(RESURRECT_HIT, 0);
203 SetCounter(CREATE_HIT, 0);
204 }
205
206 int Stats::GetLargeEntriesSize() {
207 int total = 0;
208 // data_sizes_[20] stores values between 512 KB and 1 MB (see comment before
209 // GetStatsBucket()).
210 for (int bucket = 20; bucket < kDataSizesLength; bucket++)
211 total += data_sizes_[bucket] * GetBucketRange(bucket);
212
213 return total;
214 }
215
216 int Stats::SerializeStats(void* data, int num_bytes, Addr* address) {
217 OnDiskStats* stats = reinterpret_cast<OnDiskStats*>(data);
218 if (num_bytes < static_cast<int>(sizeof(*stats)))
219 return 0;
220
221 stats->signature = kDiskSignature;
222 stats->size = sizeof(*stats);
223 memcpy(stats->data_sizes, data_sizes_, sizeof(data_sizes_));
224 memcpy(stats->counters, counters_, sizeof(counters_));
225
226 *address = storage_addr_;
227 return sizeof(*stats);
228 }
229
230 int Stats::GetBucketRange(size_t i) const {
231 if (i < 2)
232 return static_cast<int>(1024 * i);
233
234 if (i < 12)
235 return static_cast<int>(2048 * (i - 1));
236
237 if (i < 17)
238 return static_cast<int>(4096 * (i - 11)) + 20 * 1024;
239
240 int n = 64 * 1024;
241 if (i > static_cast<size_t>(kDataSizesLength)) {
242 NOTREACHED();
243 i = kDataSizesLength;
244 }
245
246 i -= 17;
247 n <<= i;
248 return n;
249 }
250
251 void Stats::Snapshot(base::HistogramSamples* samples) const {
252 for (int i = 0; i < kDataSizesLength; i++) {
253 int count = data_sizes_[i];
254 if (count < 0)
255 count = 0;
256 samples->Accumulate(GetBucketRange(i), count);
257 }
258 }
259
260 // The array will be filled this way:
261 // index size
262 // 0 [0, 1024)
263 // 1 [1024, 2048)
264 // 2 [2048, 4096)
265 // 3 [4K, 6K)
266 // ...
267 // 10 [18K, 20K)
268 // 11 [20K, 24K)
269 // 12 [24k, 28K)
270 // ...
271 // 15 [36k, 40K)
272 // 16 [40k, 64K)
273 // 17 [64K, 128K)
274 // 18 [128K, 256K)
275 // ...
276 // 23 [4M, 8M)
277 // 24 [8M, 16M)
278 // 25 [16M, 32M)
279 // 26 [32M, 64M)
280 // 27 [64M, ...)
281 int Stats::GetStatsBucket(int32 size) {
282 if (size < 1024)
283 return 0;
284
285 // 10 slots more, until 20K.
286 if (size < 20 * 1024)
287 return size / 2048 + 1;
288
289 // 5 slots more, from 20K to 40K.
290 if (size < 40 * 1024)
291 return (size - 20 * 1024) / 4096 + 11;
292
293 // From this point on, use a logarithmic scale.
294 int result = LogBase2(size) + 1;
295
296 COMPILE_ASSERT(kDataSizesLength > 16, update_the_scale);
297 if (result >= kDataSizesLength)
298 result = kDataSizesLength - 1;
299
300 return result;
301 }
302
303 int Stats::GetRatio(Counters hit, Counters miss) const {
304 int64 ratio = GetCounter(hit) * 100;
305 if (!ratio)
306 return 0;
307
308 ratio /= (GetCounter(hit) + GetCounter(miss));
309 return static_cast<int>(ratio);
310 }
311
312 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/stats.h ('k') | net/disk_cache/stats_histogram.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698