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