OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Histogram is an object that aggregates statistics, and can summarize them in | 5 // Histogram is an object that aggregates statistics, and can summarize them in |
6 // various forms, including ASCII graphical, HTML, and numerically (as a | 6 // various forms, including ASCII graphical, HTML, and numerically (as a |
7 // vector of numbers corresponding to each of the aggregating buckets). | 7 // vector of numbers corresponding to each of the aggregating buckets). |
8 // See header file for details and examples. | 8 // See header file for details and examples. |
9 | 9 |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 if (next > current) | 167 if (next > current) |
168 current = next; | 168 current = next; |
169 else | 169 else |
170 ++current; // Just do a narrow bucket, and keep trying. | 170 ++current; // Just do a narrow bucket, and keep trying. |
171 ranges->set_range(bucket_index, current); | 171 ranges->set_range(bucket_index, current); |
172 } | 172 } |
173 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); | 173 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); |
174 ranges->ResetChecksum(); | 174 ranges->ResetChecksum(); |
175 } | 175 } |
176 | 176 |
177 void Histogram::Add(int value) { | |
178 DCHECK_EQ(0, ranges(0)); | |
179 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_)); | |
180 | |
181 if (value > kSampleType_MAX - 1) | |
182 value = kSampleType_MAX - 1; | |
183 if (value < 0) | |
184 value = 0; | |
185 samples_->Accumulate(value, 1); | |
186 } | |
187 | |
188 void Histogram::AddBoolean(bool value) { | 177 void Histogram::AddBoolean(bool value) { |
189 DCHECK(false); | 178 DCHECK(false); |
190 } | 179 } |
191 | 180 |
192 void Histogram::AddSamples(const HistogramSamples& samples) { | 181 void Histogram::AddSamples(const HistogramSamples& samples) { |
193 samples_->Add(samples); | 182 samples_->Add(samples); |
194 } | 183 } |
195 | 184 |
196 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { | 185 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { |
197 return samples_->AddFromPickle(iter); | 186 return samples_->AddFromPickle(iter); |
198 } | 187 } |
199 | 188 |
200 void Histogram::SetRangeDescriptions(const DescriptionPair descriptions[]) { | 189 void Histogram::SetRangeDescriptions(const DescriptionPair descriptions[]) { |
201 DCHECK(false); | 190 DCHECK(false); |
202 } | 191 } |
203 | 192 |
204 // The following methods provide a graphical histogram display. | |
205 void Histogram::WriteHTMLGraph(string* output) const { | |
206 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. | |
207 output->append("<PRE>"); | |
208 WriteAsciiImpl(true, "<br>", output); | |
209 output->append("</PRE>"); | |
210 } | |
211 | |
212 void Histogram::WriteAscii(string* output) const { | |
213 WriteAsciiImpl(true, "\n", output); | |
214 } | |
215 | |
216 // static | 193 // static |
217 string Histogram::SerializeHistogramInfo(const Histogram& histogram, | 194 string Histogram::SerializeHistogramInfo(const Histogram& histogram, |
218 const HistogramSamples& snapshot) { | 195 const HistogramSamples& snapshot) { |
219 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram.histogram_type()); | 196 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram.histogram_type()); |
220 DCHECK(histogram.bucket_ranges()->HasValidChecksum()); | 197 DCHECK(histogram.bucket_ranges()->HasValidChecksum()); |
221 | 198 |
222 Pickle pickle; | 199 Pickle pickle; |
223 pickle.WriteString(histogram.histogram_name()); | 200 pickle.WriteString(histogram.histogram_name()); |
224 pickle.WriteInt(histogram.declared_min()); | 201 pickle.WriteInt(histogram.declared_min()); |
225 pickle.WriteInt(histogram.declared_max()); | 202 pickle.WriteInt(histogram.declared_max()); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 337 } |
361 | 338 |
362 Sample Histogram::ranges(size_t i) const { | 339 Sample Histogram::ranges(size_t i) const { |
363 return bucket_ranges_->range(i); | 340 return bucket_ranges_->range(i); |
364 } | 341 } |
365 | 342 |
366 size_t Histogram::bucket_count() const { | 343 size_t Histogram::bucket_count() const { |
367 return bucket_count_; | 344 return bucket_count_; |
368 } | 345 } |
369 | 346 |
| 347 // static |
| 348 bool Histogram::InspectConstructionArguments(const string& name, |
| 349 Sample* minimum, |
| 350 Sample* maximum, |
| 351 size_t* bucket_count) { |
| 352 // Defensive code for backward compatibility. |
| 353 if (*minimum < 1) { |
| 354 DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum; |
| 355 *minimum = 1; |
| 356 } |
| 357 if (*maximum >= kSampleType_MAX) { |
| 358 DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum; |
| 359 *maximum = kSampleType_MAX - 1; |
| 360 } |
| 361 if (*bucket_count >= kBucketCount_MAX) { |
| 362 DVLOG(1) << "Histogram: " << name << " has bad bucket_count: " |
| 363 << *bucket_count; |
| 364 *bucket_count = kBucketCount_MAX - 1; |
| 365 } |
| 366 |
| 367 if (*minimum >= *maximum) |
| 368 return false; |
| 369 if (*bucket_count < 3) |
| 370 return false; |
| 371 if (*bucket_count > static_cast<size_t>(*maximum - *minimum + 2)) |
| 372 return false; |
| 373 return true; |
| 374 } |
| 375 |
| 376 bool Histogram::HasConstructionArguments(Sample minimum, |
| 377 Sample maximum, |
| 378 size_t bucket_count) const { |
| 379 return ((minimum == declared_min_) && (maximum == declared_max_) && |
| 380 (bucket_count == bucket_count_)); |
| 381 } |
| 382 |
| 383 void Histogram::Add(int value) { |
| 384 DCHECK_EQ(0, ranges(0)); |
| 385 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_)); |
| 386 |
| 387 if (value > kSampleType_MAX - 1) |
| 388 value = kSampleType_MAX - 1; |
| 389 if (value < 0) |
| 390 value = 0; |
| 391 samples_->Accumulate(value, 1); |
| 392 } |
| 393 |
370 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { | 394 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { |
371 return SnapshotSampleVector().PassAs<HistogramSamples>(); | 395 return SnapshotSampleVector().PassAs<HistogramSamples>(); |
372 } | 396 } |
373 | 397 |
374 bool Histogram::HasConstructionArguments(Sample minimum, | 398 // The following methods provide a graphical histogram display. |
375 Sample maximum, | 399 void Histogram::WriteHTMLGraph(string* output) const { |
376 size_t bucket_count) { | 400 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. |
377 return ((minimum == declared_min_) && (maximum == declared_max_) && | 401 output->append("<PRE>"); |
378 (bucket_count == bucket_count_)); | 402 WriteAsciiImpl(true, "<br>", output); |
| 403 output->append("</PRE>"); |
| 404 } |
| 405 |
| 406 void Histogram::WriteAscii(string* output) const { |
| 407 WriteAsciiImpl(true, "\n", output); |
379 } | 408 } |
380 | 409 |
381 Histogram::Histogram(const string& name, | 410 Histogram::Histogram(const string& name, |
382 Sample minimum, | 411 Sample minimum, |
383 Sample maximum, | 412 Sample maximum, |
384 size_t bucket_count, | 413 size_t bucket_count, |
385 const BucketRanges* ranges) | 414 const BucketRanges* ranges) |
386 : HistogramBase(name), | 415 : HistogramBase(name), |
387 bucket_ranges_(ranges), | 416 bucket_ranges_(ranges), |
388 declared_min_(minimum), | 417 declared_min_(minimum), |
389 declared_max_(maximum), | 418 declared_max_(maximum), |
390 bucket_count_(bucket_count) { | 419 bucket_count_(bucket_count) { |
391 if (ranges) | 420 if (ranges) |
392 samples_.reset(new SampleVector(ranges)); | 421 samples_.reset(new SampleVector(ranges)); |
393 } | 422 } |
394 | 423 |
395 Histogram::~Histogram() { | 424 Histogram::~Histogram() { |
396 if (StatisticsRecorder::dump_on_exit()) { | 425 if (StatisticsRecorder::dump_on_exit()) { |
397 string output; | 426 string output; |
398 WriteAsciiImpl(true, "\n", &output); | 427 WriteAsciiImpl(true, "\n", &output); |
399 DLOG(INFO) << output; | 428 DLOG(INFO) << output; |
400 } | 429 } |
401 } | 430 } |
402 | 431 |
403 // static | |
404 bool Histogram::InspectConstructionArguments(const string& name, | |
405 Sample* minimum, | |
406 Sample* maximum, | |
407 size_t* bucket_count) { | |
408 // Defensive code for backward compatibility. | |
409 if (*minimum < 1) { | |
410 DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum; | |
411 *minimum = 1; | |
412 } | |
413 if (*maximum >= kSampleType_MAX) { | |
414 DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum; | |
415 *maximum = kSampleType_MAX - 1; | |
416 } | |
417 if (*bucket_count >= kBucketCount_MAX) { | |
418 DVLOG(1) << "Histogram: " << name << " has bad bucket_count: " | |
419 << *bucket_count; | |
420 *bucket_count = kBucketCount_MAX - 1; | |
421 } | |
422 | |
423 if (*minimum >= *maximum) | |
424 return false; | |
425 if (*bucket_count < 3) | |
426 return false; | |
427 if (*bucket_count > static_cast<size_t>(*maximum - *minimum + 2)) | |
428 return false; | |
429 return true; | |
430 } | |
431 | |
432 bool Histogram::SerializeRanges(Pickle* pickle) const { | 432 bool Histogram::SerializeRanges(Pickle* pickle) const { |
433 return true; | 433 return true; |
434 } | 434 } |
435 | 435 |
436 bool Histogram::PrintEmptyBucket(size_t index) const { | 436 bool Histogram::PrintEmptyBucket(size_t index) const { |
437 return true; | 437 return true; |
438 } | 438 } |
439 | 439 |
440 // Use the actual bucket widths (like a linear histogram) until the widths get | 440 // Use the actual bucket widths (like a linear histogram) until the widths get |
441 // over some transition value, and then use that transition width. Exponentials | 441 // over some transition value, and then use that transition width. Exponentials |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 | 877 |
878 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 878 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
879 for (size_t i = 0; i < ranges.size(); i++) { | 879 for (size_t i = 0; i < ranges.size(); i++) { |
880 bucket_ranges->set_range(i, ranges[i]); | 880 bucket_ranges->set_range(i, ranges[i]); |
881 } | 881 } |
882 bucket_ranges->ResetChecksum(); | 882 bucket_ranges->ResetChecksum(); |
883 return bucket_ranges; | 883 return bucket_ranges; |
884 } | 884 } |
885 | 885 |
886 } // namespace base | 886 } // namespace base |
OLD | NEW |