| 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 |