Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: base/metrics/histogram.h

Issue 10834011: Refactor of Histogram related code (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698