OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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" |
11 | 11 |
12 #include <math.h> | 12 #include <math.h> |
13 | 13 |
14 #include <algorithm> | 14 #include <algorithm> |
15 #include <string> | 15 #include <string> |
16 | 16 |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/pickle.h" | 18 #include "base/pickle.h" |
19 #include "base/stringprintf.h" | 19 #include "base/stringprintf.h" |
20 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
21 | 21 |
22 namespace base { | 22 namespace base { |
23 | 23 |
24 typedef Histogram::Count Count; | 24 typedef Histogram::Count Count; |
25 | 25 |
| 26 // static |
| 27 const size_t Histogram::kBucketCount_MAX = 10000u; |
| 28 |
26 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, | 29 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name, |
27 Sample minimum, Sample maximum, size_t bucket_count, Flags flags) { | 30 Sample minimum, Sample maximum, size_t bucket_count, Flags flags) { |
28 scoped_refptr<Histogram> histogram(NULL); | 31 scoped_refptr<Histogram> histogram(NULL); |
29 | 32 |
30 // Defensive code. | 33 // Defensive code. |
31 if (minimum < 1) | 34 if (minimum < 1) |
32 minimum = 1; | 35 minimum = 1; |
33 if (maximum > kSampleType_MAX - 1) | 36 if (maximum > kSampleType_MAX - 1) |
34 maximum = kSampleType_MAX - 1; | 37 maximum = kSampleType_MAX - 1; |
35 | 38 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // Use simple binary search. This is very general, but there are better | 409 // Use simple binary search. This is very general, but there are better |
407 // approaches if we knew that the buckets were linearly distributed. | 410 // approaches if we knew that the buckets were linearly distributed. |
408 DCHECK_LE(ranges(0), value); | 411 DCHECK_LE(ranges(0), value); |
409 DCHECK_GT(ranges(bucket_count()), value); | 412 DCHECK_GT(ranges(bucket_count()), value); |
410 size_t under = 0; | 413 size_t under = 0; |
411 size_t over = bucket_count(); | 414 size_t over = bucket_count(); |
412 size_t mid; | 415 size_t mid; |
413 | 416 |
414 do { | 417 do { |
415 DCHECK_GE(over, under); | 418 DCHECK_GE(over, under); |
416 mid = (over + under)/2; | 419 mid = under + (over - under)/2; |
417 if (mid == under) | 420 if (mid == under) |
418 break; | 421 break; |
419 if (ranges(mid) <= value) | 422 if (ranges(mid) <= value) |
420 under = mid; | 423 under = mid; |
421 else | 424 else |
422 over = mid; | 425 over = mid; |
423 } while (true); | 426 } while (true); |
424 | 427 |
425 DCHECK_LE(ranges(mid), value); | 428 DCHECK_LE(ranges(mid), value); |
426 DCHECK_GT(ranges(mid+1), value); | 429 CHECK_GT(ranges(mid+1), value); |
427 return mid; | 430 return mid; |
428 } | 431 } |
429 | 432 |
430 // Use the actual bucket widths (like a linear histogram) until the widths get | 433 // Use the actual bucket widths (like a linear histogram) until the widths get |
431 // over some transition value, and then use that transition width. Exponentials | 434 // over some transition value, and then use that transition width. Exponentials |
432 // get so big so fast (and we don't expect to see a lot of entries in the large | 435 // get so big so fast (and we don't expect to see a lot of entries in the large |
433 // buckets), so we need this to make it possible to see what is going on and | 436 // buckets), so we need this to make it possible to see what is going on and |
434 // not have 0-graphical-height buckets. | 437 // not have 0-graphical-height buckets. |
435 double Histogram::GetBucketSize(Count current, size_t i) const { | 438 double Histogram::GetBucketSize(Count current, size_t i) const { |
436 DCHECK_GT(ranges(i + 1), ranges(i)); | 439 DCHECK_GT(ranges(i + 1), ranges(i)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 } | 479 } |
477 | 480 |
478 void Histogram::Initialize() { | 481 void Histogram::Initialize() { |
479 sample_.Resize(*this); | 482 sample_.Resize(*this); |
480 if (declared_min_ < 1) | 483 if (declared_min_ < 1) |
481 declared_min_ = 1; | 484 declared_min_ = 1; |
482 if (declared_max_ > kSampleType_MAX - 1) | 485 if (declared_max_ > kSampleType_MAX - 1) |
483 declared_max_ = kSampleType_MAX - 1; | 486 declared_max_ = kSampleType_MAX - 1; |
484 DCHECK_LE(declared_min_, declared_max_); | 487 DCHECK_LE(declared_min_, declared_max_); |
485 DCHECK_GT(bucket_count_, 1u); | 488 DCHECK_GT(bucket_count_, 1u); |
| 489 CHECK_LT(bucket_count_, kBucketCount_MAX); |
486 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; | 490 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; |
487 DCHECK_LE(bucket_count_, maximal_bucket_count); | 491 DCHECK_LE(bucket_count_, maximal_bucket_count); |
488 DCHECK_EQ(0, ranges_[0]); | 492 DCHECK_EQ(0, ranges_[0]); |
489 ranges_[bucket_count_] = kSampleType_MAX; | 493 ranges_[bucket_count_] = kSampleType_MAX; |
490 InitializeBucketRange(); | 494 InitializeBucketRange(); |
491 DCHECK(ValidateBucketRanges()); | 495 DCHECK(ValidateBucketRanges()); |
492 StatisticsRecorder::Register(this); | 496 StatisticsRecorder::Register(this); |
493 } | 497 } |
494 | 498 |
495 bool Histogram::HasValidRangeChecksum() const { | 499 bool Histogram::HasValidRangeChecksum() const { |
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1043 } | 1047 } |
1044 | 1048 |
1045 // static | 1049 // static |
1046 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 1050 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
1047 // static | 1051 // static |
1048 base::Lock* StatisticsRecorder::lock_ = NULL; | 1052 base::Lock* StatisticsRecorder::lock_ = NULL; |
1049 // static | 1053 // static |
1050 bool StatisticsRecorder::dump_on_exit_ = false; | 1054 bool StatisticsRecorder::dump_on_exit_ = false; |
1051 | 1055 |
1052 } // namespace base | 1056 } // namespace base |
OLD | NEW |