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 |