Chromium Code Reviews| 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 | 8 |
| 9 // It supports calls to accumulate either time intervals (which are processed | 9 // It supports calls to accumulate either time intervals (which are processed |
| 10 // as integral number of milliseconds), or arbitrary integral units. | 10 // as integral number of milliseconds), or arbitrary integral units. |
| 11 | 11 |
| 12 // The default layout of buckets is exponential. For example, buckets might | 12 // For Histogram(exponential histogram), LinearHistogram and CustomHistogram, |
| 13 // the minimal range is 1 (instead of 0), maximal range is | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: suggest "minimal range" --> "minimum for a de
kaiwang
2012/08/01 04:13:21
Done.
| |
| 14 // (HistogramBase::kSampleType_MAX - 1). Currently you can give ranges input | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: suggest "can give ranges input..." -->
"can
kaiwang
2012/08/01 04:13:21
Done.
| |
| 15 // exceeding this limit, e.g. 0 as minimal or HistogramBase::kSampleType_MAX as | |
| 16 // maximal. They will be *silently* converted to correct input: 0 and | |
| 17 // (HistogramBase::kSampleType_MAX - 1). But you should never depend on this! | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: "But..." --> "Best practice is to not exceed
kaiwang
2012/08/01 04:13:21
Done.
| |
| 18 | |
| 19 // For Histogram and LinearHistogram, maximal range should always be larger (not | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: "maximal range" --> "maximum for a declared r
kaiwang
2012/08/01 04:13:21
Done.
| |
| 20 // equal) than minmal range. And 0 and HistogramBase::kSampleType_MAX are always | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: "And 0" --> "Zero"
"are always added" --> "a
kaiwang
2012/08/01 04:13:21
Done.
| |
| 21 // added as first and last ranges, so the minimal bucket count is 3. However | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: "minimal bucket count" --> "smallest legal bu
kaiwang
2012/08/01 04:13:21
Done.
| |
| 22 // CustomHistogram can have minimum bucket count as 2 (when you give a custom | |
| 23 // ranges vector containing only 1 range). | |
| 24 // For these 3 kind histograms, the max bucket count is always | |
|
jar (doing other things)
2012/08/01 00:26:10
"kind" --> "kinds of"
kaiwang
2012/08/01 04:13:21
Done.
| |
| 25 // (Histogram::kBucketCount_MAX - 1). | |
| 26 | |
| 27 // The buckets layout of Histogram is exponential. For example, buckets might | |
|
jar (doing other things)
2012/08/01 00:26:10
"Histogram" --> "class Histogram"
kaiwang
2012/08/01 04:13:21
Done.
| |
| 13 // contain (sequentially) the count of values in the following intervals: | 28 // contain (sequentially) the count of values in the following intervals: |
| 14 // [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity) | 29 // [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity) |
| 15 // That bucket allocation would actually result from construction of a histogram | 30 // That bucket allocation would actually result from construction of a histogram |
| 16 // for values between 1 and 64, with 8 buckets, such as: | 31 // for values between 1 and 64, with 8 buckets, such as: |
| 17 // Histogram count(L"some name", 1, 64, 8); | 32 // Histogram count("some name", 1, 64, 8); |
| 18 // Note that the underflow bucket [0,1) and the overflow bucket [64,infinity) | 33 // Note that the underflow bucket [0,1) and the overflow bucket [64,infinity) |
| 19 // are not counted by the constructor in the user supplied "bucket_count" | 34 // are also counted by the constructor in the user supplied "bucket_count" |
| 20 // argument. | 35 // argument. |
| 21 // The above example has an exponential ratio of 2 (doubling the bucket width | 36 // The above example has an exponential ratio of 2 (doubling the bucket width |
| 22 // in each consecutive bucket. The Histogram class automatically calculates | 37 // in each consecutive bucket. The Histogram class automatically calculates |
| 23 // the smallest ratio that it can use to construct the number of buckets | 38 // the smallest ratio that it can use to construct the number of buckets |
| 24 // selected in the constructor. An another example, if you had 50 buckets, | 39 // selected in the constructor. An another example, if you had 50 buckets, |
| 25 // and millisecond time values from 1 to 10000, then the ratio between | 40 // and millisecond time values from 1 to 10000, then the ratio between |
| 26 // consecutive bucket widths will be approximately somewhere around the 50th | 41 // consecutive bucket widths will be approximately somewhere around the 50th |
| 27 // root of 10000. This approach provides very fine grain (narrow) buckets | 42 // root of 10000. This approach provides very fine grain (narrow) buckets |
| 28 // at the low end of the histogram scale, but allows the histogram to cover a | 43 // at the low end of the histogram scale, but allows the histogram to cover a |
| 29 // gigantic range with the addition of very few buckets. | 44 // gigantic range with the addition of very few buckets. |
| 30 | 45 |
| 31 // Histograms use a pattern involving a function static variable, that is a | 46 // Usually we use macros to define and use a histogram. These macros use a |
| 32 // pointer to a histogram. This static is explicitly initialized on any thread | 47 // pattern involving a function static variable, that is a pointer to a |
| 48 // histogram. This static is explicitly initialized on any thread | |
| 33 // that detects a uninitialized (NULL) pointer. The potentially racy | 49 // that detects a uninitialized (NULL) pointer. The potentially racy |
| 34 // initialization is not a problem as it is always set to point to the same | 50 // initialization is not a problem as it is always set to point to the same |
| 35 // value (i.e., the FactoryGet always returns the same value). FactoryGet | 51 // value (i.e., the FactoryGet always returns the same value). FactoryGet |
| 36 // is also completely thread safe, which results in a completely thread safe, | 52 // is also completely thread safe, which results in a completely thread safe, |
| 37 // and relatively fast, set of counters. To avoid races at shutdown, the static | 53 // and relatively fast, set of counters. To avoid races at shutdown, the static |
| 38 // pointer is NOT deleted, and we leak the histograms at process termination. | 54 // pointer is NOT deleted, and we leak the histograms at process termination. |
| 39 | 55 |
| 40 #ifndef BASE_METRICS_HISTOGRAM_H_ | 56 #ifndef BASE_METRICS_HISTOGRAM_H_ |
| 41 #define BASE_METRICS_HISTOGRAM_H_ | 57 #define BASE_METRICS_HISTOGRAM_H_ |
| 42 | 58 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 170 // problems down the line if you add additional buckets to the histogram. Note | 186 // problems down the line if you add additional buckets to the histogram. Note |
| 171 // also that, despite explicitly setting the minimum bucket value to |1| below, | 187 // also that, despite explicitly setting the minimum bucket value to |1| below, |
| 172 // it is fine for enumerated histograms to be 0-indexed -- this is because | 188 // it is fine for enumerated histograms to be 0-indexed -- this is because |
| 173 // enumerated histograms should never have underflow. | 189 // enumerated histograms should never have underflow. |
| 174 #define HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ | 190 #define HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ |
| 175 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | 191 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ |
| 176 base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ | 192 base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ |
| 177 boundary_value + 1, base::Histogram::kNoFlags)) | 193 boundary_value + 1, base::Histogram::kNoFlags)) |
| 178 | 194 |
| 179 // Support histograming of an enumerated value. Samples should be one of the | 195 // Support histograming of an enumerated value. Samples should be one of the |
| 180 // std::vector<int> list provided via |custom_ranges|. You can use the helper | 196 // std::vector<int> list provided via |custom_ranges|. See comments above |
| 181 // function |base::CustomHistogram::ArrayToCustomRanges(samples, num_samples)| | 197 // CustomRanges::FactoryGet about the requirement of |custom_ranges|. |
| 182 // to transform a C-style array of valid sample values to a std::vector<int>. | 198 // You can use the helper function CustomHistogram::ArrayToCustomRanges to |
| 199 // transform a C-style array of valid sample values to a std::vector<int>. | |
| 183 #define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ | 200 #define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ |
| 184 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ | 201 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ |
| 185 base::CustomHistogram::FactoryGet(name, custom_ranges, \ | 202 base::CustomHistogram::FactoryGet(name, custom_ranges, \ |
| 186 base::Histogram::kNoFlags)) | 203 base::Histogram::kNoFlags)) |
| 187 | 204 |
| 188 //------------------------------------------------------------------------------ | 205 //------------------------------------------------------------------------------ |
| 189 // Define Debug vs non-debug flavors of macros. | 206 // Define Debug vs non-debug flavors of macros. |
| 190 #ifndef NDEBUG | 207 #ifndef NDEBUG |
| 191 | 208 |
| 192 #define DHISTOGRAM_TIMES(name, sample) HISTOGRAM_TIMES(name, sample) | 209 #define DHISTOGRAM_TIMES(name, sample) HISTOGRAM_TIMES(name, sample) |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 | 348 |
| 332 typedef std::vector<Count> Counts; | 349 typedef std::vector<Count> Counts; |
| 333 | 350 |
| 334 // These enums are used to facilitate deserialization of renderer histograms | 351 // These enums are used to facilitate deserialization of renderer histograms |
| 335 // into the browser. | 352 // into the browser. |
| 336 enum ClassType { | 353 enum ClassType { |
| 337 HISTOGRAM, | 354 HISTOGRAM, |
| 338 LINEAR_HISTOGRAM, | 355 LINEAR_HISTOGRAM, |
| 339 BOOLEAN_HISTOGRAM, | 356 BOOLEAN_HISTOGRAM, |
| 340 CUSTOM_HISTOGRAM, | 357 CUSTOM_HISTOGRAM, |
| 341 NOT_VALID_IN_RENDERER | 358 NOT_VALID_IN_RENDERER, |
| 342 }; | 359 }; |
| 343 | 360 |
| 344 enum BucketLayout { | 361 enum BucketLayout { |
| 345 EXPONENTIAL, | 362 EXPONENTIAL, |
| 346 LINEAR, | 363 LINEAR, |
| 347 CUSTOM | 364 CUSTOM, |
| 348 }; | 365 }; |
| 349 | 366 |
| 350 enum Flags { | 367 enum Flags { |
| 351 kNoFlags = 0, | 368 kNoFlags = 0, |
| 352 kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded. | 369 kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded. |
| 353 | 370 |
| 354 // Indicate that the histogram was pickled to be sent across an IPC Channel. | 371 // Indicate that the histogram was pickled to be sent across an IPC Channel. |
| 355 // If we observe this flag on a histogram being aggregated into after IPC, | 372 // If we observe this flag on a histogram being aggregated into after IPC, |
| 356 // then we are running in a single process mode, and the aggregation should | 373 // then we are running in a single process mode, and the aggregation should |
| 357 // not take place (as we would be aggregating back into the source | 374 // not take place (as we would be aggregating back into the source |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 374 struct DescriptionPair { | 391 struct DescriptionPair { |
| 375 Sample sample; | 392 Sample sample; |
| 376 const char* description; // Null means end of a list of pairs. | 393 const char* description; // Null means end of a list of pairs. |
| 377 }; | 394 }; |
| 378 | 395 |
| 379 //---------------------------------------------------------------------------- | 396 //---------------------------------------------------------------------------- |
| 380 // Statistic values, developed over the life of the histogram. | 397 // Statistic values, developed over the life of the histogram. |
| 381 | 398 |
| 382 class BASE_EXPORT SampleSet { | 399 class BASE_EXPORT SampleSet { |
| 383 public: | 400 public: |
| 384 explicit SampleSet(); | 401 explicit SampleSet(size_t size); |
| 402 SampleSet(); | |
| 385 ~SampleSet(); | 403 ~SampleSet(); |
| 386 | 404 |
| 387 // Adjust size of counts_ for use with given histogram. | 405 void Resize(size_t size); |
| 388 void Resize(const Histogram& histogram); | |
| 389 void CheckSize(const Histogram& histogram) const; | |
| 390 | 406 |
| 391 // Accessor for histogram to make routine additions. | 407 // Accessor for histogram to make routine additions. |
| 392 void Accumulate(Sample value, Count count, size_t index); | 408 void Accumulate(Sample value, Count count, size_t index); |
| 393 | 409 |
| 394 // Accessor methods. | 410 // Accessor methods. |
| 411 size_t size() const { return counts_.size(); } | |
| 395 Count counts(size_t i) const { return counts_[i]; } | 412 Count counts(size_t i) const { return counts_[i]; } |
| 396 Count TotalCount() const; | 413 Count TotalCount() const; |
| 397 int64 sum() const { return sum_; } | 414 int64 sum() const { return sum_; } |
| 398 int64 redundant_count() const { return redundant_count_; } | 415 int64 redundant_count() const { return redundant_count_; } |
| 399 | 416 |
| 400 // Arithmetic manipulation of corresponding elements of the set. | 417 // Arithmetic manipulation of corresponding elements of the set. |
| 401 void Add(const SampleSet& other); | 418 void Add(const SampleSet& other); |
| 402 void Subtract(const SampleSet& other); | 419 void Subtract(const SampleSet& other); |
| 403 | 420 |
| 404 bool Serialize(Pickle* pickle) const; | 421 bool Serialize(Pickle* pickle) const; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 static Histogram* FactoryGet(const std::string& name, | 457 static Histogram* FactoryGet(const std::string& name, |
| 441 Sample minimum, | 458 Sample minimum, |
| 442 Sample maximum, | 459 Sample maximum, |
| 443 size_t bucket_count, | 460 size_t bucket_count, |
| 444 Flags flags); | 461 Flags flags); |
| 445 static Histogram* FactoryTimeGet(const std::string& name, | 462 static Histogram* FactoryTimeGet(const std::string& name, |
| 446 base::TimeDelta minimum, | 463 base::TimeDelta minimum, |
| 447 base::TimeDelta maximum, | 464 base::TimeDelta maximum, |
| 448 size_t bucket_count, | 465 size_t bucket_count, |
| 449 Flags flags); | 466 Flags flags); |
| 467 | |
| 450 // Time call for use with DHISTOGRAM*. | 468 // Time call for use with DHISTOGRAM*. |
| 451 // Returns TimeTicks::Now() in debug and TimeTicks() in release build. | 469 // Returns TimeTicks::Now() in debug and TimeTicks() in release build. |
| 452 static TimeTicks DebugNow(); | 470 static TimeTicks DebugNow(); |
| 453 | 471 |
| 472 // Convenience methods for serializing/deserializing the histograms. | |
| 473 // Histograms from Renderer process are serialized and sent to the browser. | |
| 474 // Browser process reconstructs the histogram from the pickled version | |
| 475 // accumulates the browser-side shadow copy of histograms (that mirror | |
| 476 // histograms created in the renderer). | |
| 477 | |
| 478 // Serialize the given snapshot of a Histogram into a String. Uses | |
| 479 // Pickle class to flatten the object. | |
| 480 static std::string SerializeHistogramInfo(const Histogram& histogram, | |
|
jar (doing other things)
2012/08/01 00:26:10
note that grouping by "static" is not in style gui
kaiwang
2012/08/01 04:13:21
Done.
| |
| 481 const SampleSet& snapshot); | |
| 482 | |
| 483 // The following method accepts a list of pickled histograms and | |
| 484 // builds a histogram and updates shadow copy of histogram data in the | |
| 485 // browser process. | |
| 486 static bool DeserializeHistogramInfo(const std::string& histogram_info); | |
| 487 | |
| 488 static void InitializeBucketRanges(Sample minimum, | |
| 489 Sample maximum, | |
| 490 size_t bucket_count, | |
| 491 BucketRanges* ranges); | |
| 492 | |
| 454 virtual void Add(Sample value) OVERRIDE; | 493 virtual void Add(Sample value) OVERRIDE; |
| 455 | 494 |
| 456 // This method is an interface, used only by BooleanHistogram. | 495 // This method is an interface, used only by BooleanHistogram. |
| 457 virtual void AddBoolean(bool value); | 496 virtual void AddBoolean(bool value); |
| 458 | 497 |
| 459 // Accept a TimeDelta to increment. | 498 // Accept a TimeDelta to increment. |
| 460 void AddTime(TimeDelta time) { | 499 void AddTime(TimeDelta time) { |
| 461 Add(static_cast<int>(time.InMilliseconds())); | 500 Add(static_cast<int>(time.InMilliseconds())); |
| 462 } | 501 } |
| 463 | 502 |
| 464 void AddSampleSet(const SampleSet& sample); | 503 void AddSampleSet(const SampleSet& sample); |
| 465 | 504 |
| 466 // This method is an interface, used only by LinearHistogram. | 505 // This method is an interface, used only by LinearHistogram. |
| 467 virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); | 506 virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); |
| 468 | 507 |
| 469 // The following methods provide graphical histogram displays. | 508 // The following methods provide graphical histogram displays. |
| 470 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; | 509 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; |
| 471 virtual void WriteAscii(std::string* output) const OVERRIDE; | 510 virtual void WriteAscii(std::string* output) const OVERRIDE; |
| 472 | 511 |
| 473 // Support generic flagging of Histograms. | 512 // Support generic flagging of Histograms. |
| 474 // 0x1 Currently used to mark this histogram to be recorded by UMA.. | 513 // 0x1 Currently used to mark this histogram to be recorded by UMA.. |
| 475 // 0x8000 means print ranges in hex. | 514 // 0x8000 means print ranges in hex. |
| 476 void SetFlags(Flags flags) { flags_ = static_cast<Flags> (flags_ | flags); } | 515 void SetFlags(Flags flags) { flags_ = static_cast<Flags> (flags_ | flags); } |
| 477 void ClearFlags(Flags flags) { flags_ = static_cast<Flags>(flags_ & ~flags); } | 516 void ClearFlags(Flags flags) { flags_ = static_cast<Flags>(flags_ & ~flags); } |
| 478 int flags() const { return flags_; } | 517 int flags() const { return flags_; } |
| 479 | 518 |
| 480 // Convenience methods for serializing/deserializing the histograms. | |
| 481 // Histograms from Renderer process are serialized and sent to the browser. | |
| 482 // Browser process reconstructs the histogram from the pickled version | |
| 483 // accumulates the browser-side shadow copy of histograms (that mirror | |
| 484 // histograms created in the renderer). | |
| 485 | |
| 486 // Serialize the given snapshot of a Histogram into a String. Uses | |
| 487 // Pickle class to flatten the object. | |
| 488 static std::string SerializeHistogramInfo(const Histogram& histogram, | |
| 489 const SampleSet& snapshot); | |
| 490 | |
| 491 // The following method accepts a list of pickled histograms and | |
| 492 // builds a histogram and updates shadow copy of histogram data in the | |
| 493 // browser process. | |
| 494 static bool DeserializeHistogramInfo(const std::string& histogram_info); | |
| 495 | |
| 496 // Check to see if bucket ranges, counts and tallies in the snapshot are | 519 // Check to see if bucket ranges, counts and tallies in the snapshot are |
| 497 // consistent with the bucket ranges and checksums in our histogram. This can | 520 // consistent with the bucket ranges and checksums in our histogram. This can |
| 498 // produce a false-alarm if a race occurred in the reading of the data during | 521 // produce a false-alarm if a race occurred in the reading of the data during |
| 499 // a SnapShot process, but should otherwise be false at all times (unless we | 522 // a SnapShot process, but should otherwise be false at all times (unless we |
| 500 // have memory over-writes, or DRAM failures). | 523 // have memory over-writes, or DRAM failures). |
| 501 virtual Inconsistencies FindCorruption(const SampleSet& snapshot) const; | 524 virtual Inconsistencies FindCorruption(const SampleSet& snapshot) const; |
| 502 | 525 |
| 503 //---------------------------------------------------------------------------- | 526 //---------------------------------------------------------------------------- |
| 504 // Accessors for factory constuction, serialization and testing. | 527 // Accessors for factory constuction, serialization and testing. |
| 505 //---------------------------------------------------------------------------- | 528 //---------------------------------------------------------------------------- |
| 506 virtual ClassType histogram_type() const; | 529 virtual ClassType histogram_type() const; |
| 507 Sample declared_min() const { return declared_min_; } | 530 Sample declared_min() const { return declared_min_; } |
| 508 Sample declared_max() const { return declared_max_; } | 531 Sample declared_max() const { return declared_max_; } |
| 509 virtual Sample ranges(size_t i) const; | 532 virtual Sample ranges(size_t i) const; |
| 510 uint32 range_checksum() const { return range_checksum_; } | |
| 511 virtual size_t bucket_count() const; | 533 virtual size_t bucket_count() const; |
| 512 BucketRanges* bucket_ranges() const { return bucket_ranges_; } | 534 const BucketRanges* bucket_ranges() const { return bucket_ranges_; } |
| 513 void set_bucket_ranges(BucketRanges* bucket_ranges) { | 535 |
| 514 bucket_ranges_ = bucket_ranges; | |
| 515 } | |
| 516 // Snapshot the current complete set of sample data. | 536 // Snapshot the current complete set of sample data. |
| 517 // Override with atomic/locked snapshot if needed. | 537 // Override with atomic/locked snapshot if needed. |
| 518 virtual void SnapshotSample(SampleSet* sample) const; | 538 virtual void SnapshotSample(SampleSet* sample) const; |
| 519 | 539 |
| 520 virtual bool HasConstructorArguments(Sample minimum, Sample maximum, | 540 virtual bool HasConstructionArguments(Sample minimum, |
| 521 size_t bucket_count); | 541 Sample maximum, |
| 522 | 542 size_t bucket_count); |
| 523 virtual bool HasConstructorTimeDeltaArguments(TimeDelta minimum, | 543 virtual ~Histogram(); |
|
jar (doing other things)
2012/08/01 00:26:10
nit: move to near top of public section.
Perhaps
kaiwang
2012/08/01 04:13:21
Done.
| |
| 524 TimeDelta maximum, | |
| 525 size_t bucket_count); | |
| 526 // Return true iff the range_checksum_ matches current |ranges_| vector in | |
| 527 // |bucket_ranges_|. | |
| 528 bool HasValidRangeChecksum() const; | |
| 529 | 544 |
| 530 protected: | 545 protected: |
| 531 Histogram(const std::string& name, Sample minimum, | 546 // This function validates histogram construction arguments. It returns false |
| 532 Sample maximum, size_t bucket_count); | 547 // if some of the arguments are totally bad. |
| 533 Histogram(const std::string& name, TimeDelta minimum, | 548 // Note. Currently it allow some bad input, e.g. 0 as minimum, but silently |
| 534 TimeDelta maximum, size_t bucket_count); | 549 // converts it to good input: 1. |
| 550 // TODO(kaiwang): Be more restrict and return false for any bad input, and | |
| 551 // make this a readonly validating function. | |
| 552 static bool InspectConstructionArguments(const std::string& name, | |
| 553 Sample* minimum, | |
| 554 Sample* maximum, | |
| 555 size_t* bucket_count); | |
| 535 | 556 |
| 536 virtual ~Histogram(); | 557 Histogram(const std::string& name, |
|
jar (doing other things)
2012/08/01 00:26:10
nit: push to top of section.
kaiwang
2012/08/01 04:13:21
Done.
| |
| 558 Sample minimum, | |
| 559 Sample maximum, | |
| 560 size_t bucket_count, | |
| 561 const BucketRanges* ranges); | |
| 537 | 562 |
| 538 // Serialize the histogram's ranges to |*pickle|, returning true on success. | 563 // Serialize the histogram's ranges to |*pickle|, returning true on success. |
| 539 // Most subclasses can leave this no-op implementation, but some will want to | 564 // Most subclasses can leave this no-op implementation, but some will want to |
| 540 // override it, especially if the ranges cannot be re-derived from other | 565 // override it, especially if the ranges cannot be re-derived from other |
| 541 // serialized parameters. | 566 // serialized parameters. |
| 542 virtual bool SerializeRanges(Pickle* pickle) const; | 567 virtual bool SerializeRanges(Pickle* pickle) const; |
| 543 | 568 |
| 544 // Initialize ranges_ mapping in bucket_ranges_. | |
| 545 void InitializeBucketRange(); | |
| 546 | |
| 547 // Method to override to skip the display of the i'th bucket if it's empty. | 569 // Method to override to skip the display of the i'th bucket if it's empty. |
| 548 virtual bool PrintEmptyBucket(size_t index) const; | 570 virtual bool PrintEmptyBucket(size_t index) const; |
| 549 | 571 |
| 550 //---------------------------------------------------------------------------- | 572 //---------------------------------------------------------------------------- |
| 551 // Methods to override to create histogram with different bucket widths. | 573 // Methods to override to create histogram with different bucket widths. |
| 552 //---------------------------------------------------------------------------- | 574 //---------------------------------------------------------------------------- |
| 553 // Find bucket to increment for sample value. | 575 // Find bucket to increment for sample value. |
| 554 virtual size_t BucketIndex(Sample value) const; | 576 virtual size_t BucketIndex(Sample value) const; |
| 555 // Get normalized size, relative to the ranges(i). | 577 // Get normalized size, relative to the ranges(i). |
| 556 virtual double GetBucketSize(Count current, size_t i) const; | 578 virtual double GetBucketSize(Count current, size_t i) const; |
| 557 | 579 |
| 558 // Recalculate range_checksum_. | |
| 559 void ResetRangeChecksum(); | |
| 560 | |
| 561 // Return a string description of what goes in a given bucket. | 580 // Return a string description of what goes in a given bucket. |
| 562 // Most commonly this is the numeric value, but in derived classes it may | 581 // Most commonly this is the numeric value, but in derived classes it may |
| 563 // be a name (or string description) given to the bucket. | 582 // be a name (or string description) given to the bucket. |
| 564 virtual const std::string GetAsciiBucketRange(size_t it) const; | 583 virtual const std::string GetAsciiBucketRange(size_t it) const; |
| 565 | 584 |
| 566 //---------------------------------------------------------------------------- | 585 //---------------------------------------------------------------------------- |
| 567 // Methods to override to create thread safe histogram. | 586 // Methods to override to create thread safe histogram. |
| 568 //---------------------------------------------------------------------------- | 587 //---------------------------------------------------------------------------- |
| 569 // Update all our internal data, including histogram | 588 // Update all our internal data, including histogram |
| 570 virtual void Accumulate(Sample value, Count count, size_t index); | 589 virtual void Accumulate(Sample value, Count count, size_t index); |
| 571 | 590 |
| 572 //---------------------------------------------------------------------------- | |
| 573 // Accessors for derived classes. | |
| 574 //---------------------------------------------------------------------------- | |
| 575 void SetBucketRange(size_t i, Sample value); | |
| 576 | |
| 577 // Validate that ranges_ in bucket_ranges_ was created sensibly (top and | |
| 578 // bottom range values relate properly to the declared_min_ and | |
| 579 // declared_max_). | |
| 580 bool ValidateBucketRanges() const; | |
| 581 | |
| 582 virtual uint32 CalculateRangeChecksum() const; | |
| 583 | |
| 584 private: | 591 private: |
| 585 // Allow tests to corrupt our innards for testing purposes. | 592 // Allow tests to corrupt our innards for testing purposes. |
| 586 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); | 593 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); |
| 587 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); | 594 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); |
| 588 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32SampleHash); | 595 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32SampleHash); |
| 589 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32TableTest); | 596 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32TableTest); |
| 590 | 597 |
| 591 friend class StatisticsRecorder; // To allow it to delete duplicates. | 598 friend class StatisticsRecorder; // To allow it to delete duplicates. |
| 592 | 599 |
| 593 // Post constructor initialization. | |
| 594 void Initialize(); | |
| 595 | |
| 596 // Checksum function for accumulating range values into a checksum. | |
| 597 static uint32 Crc32(uint32 sum, Sample range); | |
| 598 | |
| 599 //---------------------------------------------------------------------------- | 600 //---------------------------------------------------------------------------- |
| 600 // Helpers for emitting Ascii graphic. Each method appends data to output. | 601 // Helpers for emitting Ascii graphic. Each method appends data to output. |
| 601 | 602 |
| 602 void WriteAsciiImpl(bool graph_it, | 603 void WriteAsciiImpl(bool graph_it, |
| 603 const std::string& newline, | 604 const std::string& newline, |
| 604 std::string* output) const; | 605 std::string* output) const; |
| 605 | 606 |
| 606 // Find out how large the (graphically) the largest bucket will appear to be. | 607 // Find out how large the (graphically) the largest bucket will appear to be. |
| 607 double GetPeakBucketSize(const SampleSet& snapshot) const; | 608 double GetPeakBucketSize(const SampleSet& snapshot) const; |
| 608 | 609 |
| 609 // Write a common header message describing this histogram. | 610 // Write a common header message describing this histogram. |
| 610 void WriteAsciiHeader(const SampleSet& snapshot, | 611 void WriteAsciiHeader(const SampleSet& snapshot, |
| 611 Count sample_count, std::string* output) const; | 612 Count sample_count, std::string* output) const; |
| 612 | 613 |
| 613 // Write information about previous, current, and next buckets. | 614 // Write information about previous, current, and next buckets. |
| 614 // Information such as cumulative percentage, etc. | 615 // Information such as cumulative percentage, etc. |
| 615 void WriteAsciiBucketContext(const int64 past, const Count current, | 616 void WriteAsciiBucketContext(const int64 past, const Count current, |
| 616 const int64 remaining, const size_t i, | 617 const int64 remaining, const size_t i, |
| 617 std::string* output) const; | 618 std::string* output) const; |
| 618 | 619 |
| 619 // Write textual description of the bucket contents (relative to histogram). | 620 // Write textual description of the bucket contents (relative to histogram). |
| 620 // Output is the count in the buckets, as well as the percentage. | 621 // Output is the count in the buckets, as well as the percentage. |
| 621 void WriteAsciiBucketValue(Count current, double scaled_sum, | 622 void WriteAsciiBucketValue(Count current, double scaled_sum, |
| 622 std::string* output) const; | 623 std::string* output) const; |
| 623 | 624 |
| 624 // Produce actual graph (set of blank vs non blank char's) for a bucket. | 625 // Produce actual graph (set of blank vs non blank char's) for a bucket. |
| 625 void WriteAsciiBucketGraph(double current_size, double max_size, | 626 void WriteAsciiBucketGraph(double current_size, double max_size, |
| 626 std::string* output) const; | 627 std::string* output) const; |
| 627 | 628 |
| 628 //---------------------------------------------------------------------------- | 629 // Does not own this object. Should get from StatisticsRecorder. |
| 629 // Table for generating Crc32 values. | 630 const BucketRanges* bucket_ranges_; |
| 630 static const uint32 kCrcTable[256]; | |
| 631 //---------------------------------------------------------------------------- | |
| 632 // Invariant values set at/near construction time | |
| 633 | 631 |
| 634 Sample declared_min_; // Less than this goes into counts_[0] | 632 Sample declared_min_; // Less than this goes into counts_[0] |
| 635 Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. | 633 Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. |
| 636 size_t bucket_count_; // Dimension of counts_[]. | 634 size_t bucket_count_; // Dimension of counts_[]. |
| 637 | 635 |
| 638 // Flag the histogram for recording by UMA via metric_services.h. | 636 // Flag the histogram for recording by UMA via metric_services.h. |
| 639 Flags flags_; | 637 Flags flags_; |
| 640 | 638 |
| 641 // For each index, show the least value that can be stored in the | |
| 642 // corresponding bucket. We also append one extra element in this array, | |
| 643 // containing kSampleType_MAX, to make calculations easy. | |
| 644 // The dimension of ranges_ in bucket_ranges_ is bucket_count + 1. | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: Preserve this comment, since we don't explain
kaiwang
2012/08/01 04:13:21
Done. Simplified the comments and added to Histogr
| |
| 645 BucketRanges* bucket_ranges_; | |
| 646 | |
| 647 // For redundancy, we store a checksum of all the sample ranges when ranges | |
| 648 // are generated. If ever there is ever a difference, then the histogram must | |
| 649 // have been corrupted. | |
| 650 uint32 range_checksum_; | |
| 651 | |
| 652 // Finally, provide the state that changes with the addition of each new | 639 // Finally, provide the state that changes with the addition of each new |
| 653 // sample. | 640 // sample. |
| 654 SampleSet sample_; | 641 SampleSet sample_; |
| 655 | 642 |
| 656 DISALLOW_COPY_AND_ASSIGN(Histogram); | 643 DISALLOW_COPY_AND_ASSIGN(Histogram); |
| 657 }; | 644 }; |
| 658 | 645 |
| 659 //------------------------------------------------------------------------------ | 646 //------------------------------------------------------------------------------ |
| 660 | 647 |
| 661 // LinearHistogram is a more traditional histogram, with evenly spaced | 648 // LinearHistogram is a more traditional histogram, with evenly spaced |
| 662 // buckets. | 649 // buckets. |
| 663 class BASE_EXPORT LinearHistogram : public Histogram { | 650 class BASE_EXPORT LinearHistogram : public Histogram { |
| 664 public: | 651 public: |
| 665 virtual ~LinearHistogram(); | 652 virtual ~LinearHistogram(); |
| 666 | 653 |
| 667 /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit | 654 /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit |
| 668 default underflow bucket. */ | 655 default underflow bucket. */ |
| 669 static Histogram* FactoryGet(const std::string& name, | 656 static Histogram* FactoryGet(const std::string& name, |
| 670 Sample minimum, | 657 Sample minimum, |
| 671 Sample maximum, | 658 Sample maximum, |
| 672 size_t bucket_count, | 659 size_t bucket_count, |
| 673 Flags flags); | 660 Flags flags); |
| 674 static Histogram* FactoryTimeGet(const std::string& name, | 661 static Histogram* FactoryTimeGet(const std::string& name, |
| 675 TimeDelta minimum, | 662 TimeDelta minimum, |
| 676 TimeDelta maximum, | 663 TimeDelta maximum, |
| 677 size_t bucket_count, | 664 size_t bucket_count, |
| 678 Flags flags); | 665 Flags flags); |
| 679 | 666 |
| 667 static void InitializeBucketRanges(Sample minimum, | |
| 668 Sample maximum, | |
| 669 size_t bucket_count, | |
| 670 BucketRanges* ranges); | |
| 671 | |
| 680 // Overridden from Histogram: | 672 // Overridden from Histogram: |
| 681 virtual ClassType histogram_type() const OVERRIDE; | 673 virtual ClassType histogram_type() const OVERRIDE; |
| 682 | 674 |
| 683 // Store a list of number/text values for use in rendering the histogram. | 675 // Store a list of number/text values for use in rendering the histogram. |
| 684 // The last element in the array has a null in its "description" slot. | 676 // The last element in the array has a null in its "description" slot. |
| 685 virtual void SetRangeDescriptions( | 677 virtual void SetRangeDescriptions( |
| 686 const DescriptionPair descriptions[]) OVERRIDE; | 678 const DescriptionPair descriptions[]) OVERRIDE; |
| 687 | 679 |
| 688 protected: | 680 protected: |
| 689 LinearHistogram(const std::string& name, Sample minimum, | 681 LinearHistogram(const std::string& name, |
| 690 Sample maximum, size_t bucket_count); | 682 Sample minimum, |
| 683 Sample maximum, | |
| 684 size_t bucket_count, | |
| 685 const BucketRanges* ranges); | |
| 691 | 686 |
| 692 LinearHistogram(const std::string& name, TimeDelta minimum, | |
| 693 TimeDelta maximum, size_t bucket_count); | |
| 694 | |
| 695 // Initialize ranges_ mapping in bucket_ranges_. | |
| 696 void InitializeBucketRange(); | |
| 697 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; | 687 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; |
| 698 | 688 |
| 699 // If we have a description for a bucket, then return that. Otherwise | 689 // If we have a description for a bucket, then return that. Otherwise |
| 700 // let parent class provide a (numeric) description. | 690 // let parent class provide a (numeric) description. |
| 701 virtual const std::string GetAsciiBucketRange(size_t i) const OVERRIDE; | 691 virtual const std::string GetAsciiBucketRange(size_t i) const OVERRIDE; |
| 702 | 692 |
| 703 // Skip printing of name for numeric range if we have a name (and if this is | 693 // Skip printing of name for numeric range if we have a name (and if this is |
| 704 // an empty bucket). | 694 // an empty bucket). |
| 705 virtual bool PrintEmptyBucket(size_t index) const OVERRIDE; | 695 virtual bool PrintEmptyBucket(size_t index) const OVERRIDE; |
| 706 | 696 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 719 // BooleanHistogram is a histogram for booleans. | 709 // BooleanHistogram is a histogram for booleans. |
| 720 class BASE_EXPORT BooleanHistogram : public LinearHistogram { | 710 class BASE_EXPORT BooleanHistogram : public LinearHistogram { |
| 721 public: | 711 public: |
| 722 static Histogram* FactoryGet(const std::string& name, Flags flags); | 712 static Histogram* FactoryGet(const std::string& name, Flags flags); |
| 723 | 713 |
| 724 virtual ClassType histogram_type() const OVERRIDE; | 714 virtual ClassType histogram_type() const OVERRIDE; |
| 725 | 715 |
| 726 virtual void AddBoolean(bool value) OVERRIDE; | 716 virtual void AddBoolean(bool value) OVERRIDE; |
| 727 | 717 |
| 728 private: | 718 private: |
| 729 explicit BooleanHistogram(const std::string& name); | 719 BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
| 730 | 720 |
| 731 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); | 721 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
| 732 }; | 722 }; |
| 733 | 723 |
| 734 //------------------------------------------------------------------------------ | 724 //------------------------------------------------------------------------------ |
| 735 | 725 |
| 736 // CustomHistogram is a histogram for a set of custom integers. | 726 // CustomHistogram is a histogram for a set of custom integers. |
| 737 class BASE_EXPORT CustomHistogram : public Histogram { | 727 class BASE_EXPORT CustomHistogram : public Histogram { |
| 738 public: | 728 public: |
| 739 | 729 // |custom_ranges| contains a set of ranges. Each of them should be > 0 and |
|
jar (doing other things)
2012/08/01 00:26:10
nit: "a set of ranges" --> "a vector of limits on
kaiwang
2012/08/01 04:13:21
Done.
| |
| 730 // < kSampleType_MAX. (Currently 0 is still accepted for backward | |
| 731 // compatibility). The ranges can be unordered or contain duplication, but | |
|
jar (doing other things)
2012/08/01 00:26:10
nit: "ranges" --> "limits"
kaiwang
2012/08/01 04:13:21
Done.
| |
| 732 // client should not depend on this. | |
| 740 static Histogram* FactoryGet(const std::string& name, | 733 static Histogram* FactoryGet(const std::string& name, |
| 741 const std::vector<Sample>& custom_ranges, | 734 const std::vector<Sample>& custom_ranges, |
| 742 Flags flags); | 735 Flags flags); |
| 743 | 736 |
| 744 // Overridden from Histogram: | 737 // Overridden from Histogram: |
| 745 virtual ClassType histogram_type() const OVERRIDE; | 738 virtual ClassType histogram_type() const OVERRIDE; |
| 746 | 739 |
| 747 // Helper method for transforming an array of valid enumeration values | 740 // Helper method for transforming an array of valid enumeration values |
| 748 // to the std::vector<int> expected by HISTOGRAM_CUSTOM_ENUMERATION. | 741 // to the std::vector<int> expected by HISTOGRAM_CUSTOM_ENUMERATION. |
| 749 // This function ensures that a guard bucket exists right after any | 742 // This function ensures that a guard bucket exists right after any |
| 750 // valid sample value (unless the next higher sample is also a valid value), | 743 // valid sample value (unless the next higher sample is also a valid value), |
| 751 // so that invalid samples never fall into the same bucket as valid samples. | 744 // so that invalid samples never fall into the same bucket as valid samples. |
| 752 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, | 745 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
| 753 size_t num_values); | 746 size_t num_values); |
| 754 | 747 |
| 755 // Helper for deserializing CustomHistograms. |*ranges| should already be | 748 // Helper for deserializing CustomHistograms. |*ranges| should already be |
| 756 // correctly sized before this call. Return true on success. | 749 // correctly sized before this call. Return true on success. |
| 757 static bool DeserializeRanges(PickleIterator* iter, | 750 static bool DeserializeRanges(PickleIterator* iter, |
| 758 std::vector<Histogram::Sample>* ranges); | 751 std::vector<Sample>* ranges); |
| 759 | 752 |
| 760 | 753 |
| 761 protected: | 754 protected: |
| 762 CustomHistogram(const std::string& name, | 755 CustomHistogram(const std::string& name, |
| 763 const std::vector<Sample>& custom_ranges); | 756 const BucketRanges* ranges); |
| 764 | 757 |
| 765 virtual bool SerializeRanges(Pickle* pickle) const OVERRIDE; | 758 virtual bool SerializeRanges(Pickle* pickle) const OVERRIDE; |
| 766 | 759 |
| 767 // Initialize ranges_ mapping in bucket_ranges_. | |
| 768 void InitializedCustomBucketRange(const std::vector<Sample>& custom_ranges); | |
| 769 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; | 760 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; |
| 770 | 761 |
| 762 private: | |
| 763 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | |
| 764 static BucketRanges* CreateBucketRangesFromCustomRanges( | |
| 765 const std::vector<Sample>& custom_ranges); | |
| 766 | |
| 771 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 767 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
| 772 }; | 768 }; |
| 773 | 769 |
| 774 } // namespace base | 770 } // namespace base |
| 775 | 771 |
| 776 #endif // BASE_METRICS_HISTOGRAM_H_ | 772 #endif // BASE_METRICS_HISTOGRAM_H_ |
| OLD | NEW |