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. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 #include <map> | 61 #include <map> |
62 #include <string> | 62 #include <string> |
63 #include <vector> | 63 #include <vector> |
64 | 64 |
65 #include "base/atomicops.h" | 65 #include "base/atomicops.h" |
66 #include "base/base_export.h" | 66 #include "base/base_export.h" |
67 #include "base/basictypes.h" | 67 #include "base/basictypes.h" |
68 #include "base/compiler_specific.h" | 68 #include "base/compiler_specific.h" |
69 #include "base/gtest_prod_util.h" | 69 #include "base/gtest_prod_util.h" |
70 #include "base/logging.h" | 70 #include "base/logging.h" |
71 #include "base/memory/scoped_ptr.h" | |
71 #include "base/metrics/bucket_ranges.h" | 72 #include "base/metrics/bucket_ranges.h" |
72 #include "base/metrics/histogram_base.h" | 73 #include "base/metrics/histogram_base.h" |
74 #include "base/metrics/histogram_samples.h" | |
73 #include "base/time.h" | 75 #include "base/time.h" |
74 | 76 |
75 class Pickle; | 77 class Pickle; |
76 class PickleIterator; | 78 class PickleIterator; |
77 | 79 |
78 namespace base { | 80 namespace base { |
79 | 81 |
80 class Lock; | 82 class Lock; |
81 //------------------------------------------------------------------------------ | 83 //------------------------------------------------------------------------------ |
82 // Histograms are often put in areas where they are called many many times, and | 84 // Histograms are often put in areas where they are called many many times, and |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 base::Histogram::kUmaTargetedHistogramFlag)) | 339 base::Histogram::kUmaTargetedHistogramFlag)) |
338 | 340 |
339 //------------------------------------------------------------------------------ | 341 //------------------------------------------------------------------------------ |
340 | 342 |
341 class BooleanHistogram; | 343 class BooleanHistogram; |
342 class BucketRanges; | 344 class BucketRanges; |
343 class CustomHistogram; | 345 class CustomHistogram; |
344 class Histogram; | 346 class Histogram; |
345 class LinearHistogram; | 347 class LinearHistogram; |
346 | 348 |
349 class BASE_EXPORT_PRIVATE BucketHistogramSamples : public HistogramSamples { | |
Ilya Sherman
2012/08/23 07:50:54
I don't really understand what a "BucketHistogram"
kaiwang
2012/08/24 04:17:58
SparseHistograms don't
Ilya Sherman
2012/08/29 08:48:16
SparseHistograms don't have *contiguous* buckets,
Ilya Sherman
2012/08/29 23:41:27
(bump)
kaiwang
2012/08/30 03:13:21
Original Histogram separates the whole sample valu
Ilya Sherman
2012/08/30 07:57:39
I think we disagree on what a histogram "bucket" m
jar (doing other things)
2012/08/30 22:54:38
I think perchance you meant ContiGuousHistogramSam
Ilya Sherman
2012/08/30 23:01:46
SGTM
| |
350 public: | |
351 BucketHistogramSamples(const BucketRanges* bucket_ranges); | |
Ilya Sherman
2012/08/23 07:50:54
nit: explicit
Ilya Sherman
2012/08/23 07:50:54
nit: Can this be passed by const-ref rather than c
kaiwang
2012/08/24 04:17:58
Done.
| |
352 virtual ~BucketHistogramSamples(); | |
353 | |
354 virtual void Accumulate(HistogramBase::Sample value, | |
Ilya Sherman
2012/08/23 07:50:54
nit: Please label these methods with something lik
kaiwang
2012/08/24 04:17:58
Done.
| |
355 HistogramBase::Count count) OVERRIDE; | |
356 virtual HistogramBase::Count GetCount( | |
357 HistogramBase::Sample value) const OVERRIDE; | |
358 virtual HistogramBase::Count TotalCount() const OVERRIDE; | |
359 | |
360 virtual scoped_ptr<SampleCountIterator> Iterator() const OVERRIDE; | |
361 | |
362 // Get count of a specific bucket. | |
363 HistogramBase::Count GetCountFromBucketIndex(size_t bucket_index) const; | |
Ilya Sherman
2012/08/23 07:50:54
nit: "From" -> "For"
kaiwang
2012/08/24 04:17:58
I really don't think "For" is better than "From",
Ilya Sherman
2012/08/29 08:48:16
If you want to use "from", the name should be "Get
kaiwang
2012/08/30 03:13:21
What do you think of GetCountAtIndex? from Jim's s
Ilya Sherman
2012/08/30 07:57:39
Works for me :)
| |
364 | |
365 protected: | |
366 virtual bool AddSubtractHelper(SampleCountIterator* iter, | |
367 bool is_add) OVERRIDE; | |
368 | |
369 static size_t BucketIndex(HistogramBase::Sample value, | |
Ilya Sherman
2012/08/23 07:50:54
nit: GetBucketIndex()
kaiwang
2012/08/24 04:17:58
Done.
| |
370 const BucketRanges* bucket_ranges); | |
Ilya Sherman
2012/08/23 07:50:54
nit: Can this be passed by const-reference?
| |
371 | |
372 private: | |
373 DISALLOW_COPY_AND_ASSIGN(BucketHistogramSamples); | |
Ilya Sherman
2012/08/23 07:50:54
Optional nit: I think this is usually the very las
kaiwang
2012/08/24 04:17:58
Done.
| |
374 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); | |
375 | |
376 std::vector<HistogramBase::Count> counts_; | |
377 | |
378 // Shares the same BucketRanges with Histogram object. | |
379 const BucketRanges* bucket_ranges_; | |
Ilya Sherman
2012/08/23 07:50:54
nit: Can this be a const reference or a const Buck
kaiwang
2012/08/24 04:17:58
Done.
| |
380 }; | |
381 | |
382 class BASE_EXPORT_PRIVATE BucketHistogramSamplesIterator | |
383 : public SampleCountIterator { | |
384 public: | |
385 BucketHistogramSamplesIterator( | |
386 const std::vector<HistogramBase::Count>* counts, | |
Ilya Sherman
2012/08/23 07:50:54
nit: Can this be passed by const-reference?
| |
387 const BucketRanges* bucket_ranges); | |
Ilya Sherman
2012/08/23 07:50:54
nit: Ditto
kaiwang
2012/08/24 04:17:58
For all the reference related comments:
IMHO, I ra
| |
388 | |
389 virtual bool Done() OVERRIDE; | |
390 virtual void Next() OVERRIDE; | |
391 virtual void Get(HistogramBase::Sample* min, | |
392 HistogramBase::Sample* max, | |
393 HistogramBase::Count* count) OVERRIDE; | |
394 private: | |
395 void ForwardIndex(); // Find the next place with data. | |
Ilya Sherman
2012/08/23 07:50:54
nit: Please choose a more descriptive name rather
kaiwang
2012/08/24 04:17:58
Done.
| |
396 | |
397 const std::vector<HistogramBase::Count>* counts_; | |
398 const BucketRanges* bucket_ranges_; | |
399 | |
400 int index_; | |
401 bool is_done_; | |
402 }; | |
Ilya Sherman
2012/08/23 07:50:54
Please declare & define these classes in separate
kaiwang
2012/08/24 04:17:58
This file currently contains all stuff related to
Ilya Sherman
2012/08/29 08:48:16
You are adding a new class, so moving the new clas
Ilya Sherman
2012/08/29 23:41:27
(bump)
kaiwang
2012/08/30 03:13:21
Done.
| |
403 | |
347 class BASE_EXPORT Histogram : public HistogramBase { | 404 class BASE_EXPORT Histogram : public HistogramBase { |
348 public: | 405 public: |
349 // Initialize maximum number of buckets in histograms as 16,384. | 406 // Initialize maximum number of buckets in histograms as 16,384. |
350 static const size_t kBucketCount_MAX; | 407 static const size_t kBucketCount_MAX; |
351 | 408 |
352 typedef std::vector<Count> Counts; | 409 typedef std::vector<Count> Counts; |
353 | 410 |
354 // These enums are used to facilitate deserialization of renderer histograms | 411 // These enums are used to facilitate deserialization of renderer histograms |
355 // into the browser. | 412 // into the browser. |
356 enum ClassType { | 413 enum ClassType { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
466 virtual void Add(Sample value) OVERRIDE; | 523 virtual void Add(Sample value) OVERRIDE; |
467 | 524 |
468 // This method is an interface, used only by BooleanHistogram. | 525 // This method is an interface, used only by BooleanHistogram. |
469 virtual void AddBoolean(bool value); | 526 virtual void AddBoolean(bool value); |
470 | 527 |
471 // Accept a TimeDelta to increment. | 528 // Accept a TimeDelta to increment. |
472 void AddTime(TimeDelta time) { | 529 void AddTime(TimeDelta time) { |
473 Add(static_cast<int>(time.InMilliseconds())); | 530 Add(static_cast<int>(time.InMilliseconds())); |
474 } | 531 } |
475 | 532 |
476 void AddSampleSet(const SampleSet& sample); | 533 void AddSamples(const HistogramSamples& samples); |
534 bool AddSamples(PickleIterator* iter); | |
477 | 535 |
478 // This method is an interface, used only by LinearHistogram. | 536 // This method is an interface, used only by LinearHistogram. |
479 virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); | 537 virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); |
480 | 538 |
481 // The following methods provide graphical histogram displays. | 539 // The following methods provide graphical histogram displays. |
482 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; | 540 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; |
483 virtual void WriteAscii(std::string* output) const OVERRIDE; | 541 virtual void WriteAscii(std::string* output) const OVERRIDE; |
484 | 542 |
485 // Convenience methods for serializing/deserializing the histograms. | 543 // Convenience methods for serializing/deserializing the histograms. |
486 // Histograms from Renderer process are serialized and sent to the browser. | 544 // Histograms from Renderer process are serialized and sent to the browser. |
487 // Browser process reconstructs the histogram from the pickled version | 545 // Browser process reconstructs the histogram from the pickled version |
488 // accumulates the browser-side shadow copy of histograms (that mirror | 546 // accumulates the browser-side shadow copy of histograms (that mirror |
489 // histograms created in the renderer). | 547 // histograms created in the renderer). |
490 | 548 |
491 // Serialize the given snapshot of a Histogram into a String. Uses | 549 // Serialize the given snapshot of a Histogram into a String. Uses |
492 // Pickle class to flatten the object. | 550 // Pickle class to flatten the object. |
493 static std::string SerializeHistogramInfo(const Histogram& histogram, | 551 static std::string SerializeHistogramInfo(const Histogram& histogram, |
494 const SampleSet& snapshot); | 552 const HistogramSamples& snapshot); |
495 | 553 |
496 // The following method accepts a list of pickled histograms and | 554 // The following method accepts a list of pickled histograms and |
497 // builds a histogram and updates shadow copy of histogram data in the | 555 // builds a histogram and updates shadow copy of histogram data in the |
498 // browser process. | 556 // browser process. |
499 static bool DeserializeHistogramInfo(const std::string& histogram_info); | 557 static bool DeserializeHistogramInfo(const std::string& histogram_info); |
500 | 558 |
559 // This constant if for FindCorruption. Since snapshots of histograms are | |
560 // taken asynchronously relative to sampling, and out counting code currently | |
jar (doing other things)
2012/08/30 22:54:38
nit: out --> our
kaiwang
2012/09/07 01:14:11
Done.
| |
561 // does not prevent race conditions, it is pretty likely that we'll catch a | |
562 // redundant count that doesn't match the sample count. We allow for a | |
563 // certain amount of slop before flagging this as an inconsistency. Even with | |
564 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), | |
565 // so we'll eventually get the data, if it was not the result of a corruption. | |
566 static const int kCommonRaceBasedCountMismatch; | |
567 | |
501 // Check to see if bucket ranges, counts and tallies in the snapshot are | 568 // Check to see if bucket ranges, counts and tallies in the snapshot are |
502 // consistent with the bucket ranges and checksums in our histogram. This can | 569 // consistent with the bucket ranges and checksums in our histogram. This can |
503 // produce a false-alarm if a race occurred in the reading of the data during | 570 // produce a false-alarm if a race occurred in the reading of the data during |
504 // a SnapShot process, but should otherwise be false at all times (unless we | 571 // a SnapShot process, but should otherwise be false at all times (unless we |
505 // have memory over-writes, or DRAM failures). | 572 // have memory over-writes, or DRAM failures). |
506 virtual Inconsistencies FindCorruption(const SampleSet& snapshot) const; | 573 virtual Inconsistencies FindCorruption(const HistogramSamples& samples) const; |
507 | 574 |
508 //---------------------------------------------------------------------------- | 575 //---------------------------------------------------------------------------- |
509 // Accessors for factory constuction, serialization and testing. | 576 // Accessors for factory constuction, serialization and testing. |
510 //---------------------------------------------------------------------------- | 577 //---------------------------------------------------------------------------- |
511 virtual ClassType histogram_type() const; | 578 virtual ClassType histogram_type() const; |
512 Sample declared_min() const { return declared_min_; } | 579 Sample declared_min() const { return declared_min_; } |
513 Sample declared_max() const { return declared_max_; } | 580 Sample declared_max() const { return declared_max_; } |
514 virtual Sample ranges(size_t i) const; | 581 virtual Sample ranges(size_t i) const; |
515 virtual size_t bucket_count() const; | 582 virtual size_t bucket_count() const; |
516 const BucketRanges* bucket_ranges() const { return bucket_ranges_; } | 583 const BucketRanges* bucket_ranges() const { return bucket_ranges_; } |
517 | 584 |
518 // Snapshot the current complete set of sample data. | 585 // Snapshot the current complete set of sample data. |
519 // Override with atomic/locked snapshot if needed. | 586 // Override with atomic/locked snapshot if needed. |
520 virtual void SnapshotSample(SampleSet* sample) const; | 587 virtual scoped_ptr<BucketHistogramSamples> SnapshotSamples() const; |
521 | 588 |
522 virtual bool HasConstructionArguments(Sample minimum, | 589 virtual bool HasConstructionArguments(Sample minimum, |
523 Sample maximum, | 590 Sample maximum, |
524 size_t bucket_count); | 591 size_t bucket_count); |
525 protected: | 592 protected: |
526 // |bucket_count| and |ranges| should contain the underflow and overflow | 593 // |bucket_count| and |ranges| should contain the underflow and overflow |
527 // buckets. See top comments for example. | 594 // buckets. See top comments for example. |
528 Histogram(const std::string& name, | 595 Histogram(const std::string& name, |
529 Sample minimum, | 596 Sample minimum, |
530 Sample maximum, | 597 Sample maximum, |
(...skipping 15 matching lines...) Expand all Loading... | |
546 | 613 |
547 // Serialize the histogram's ranges to |*pickle|, returning true on success. | 614 // Serialize the histogram's ranges to |*pickle|, returning true on success. |
548 // Most subclasses can leave this no-op implementation, but some will want to | 615 // Most subclasses can leave this no-op implementation, but some will want to |
549 // override it, especially if the ranges cannot be re-derived from other | 616 // override it, especially if the ranges cannot be re-derived from other |
550 // serialized parameters. | 617 // serialized parameters. |
551 virtual bool SerializeRanges(Pickle* pickle) const; | 618 virtual bool SerializeRanges(Pickle* pickle) const; |
552 | 619 |
553 // Method to override to skip the display of the i'th bucket if it's empty. | 620 // Method to override to skip the display of the i'th bucket if it's empty. |
554 virtual bool PrintEmptyBucket(size_t index) const; | 621 virtual bool PrintEmptyBucket(size_t index) const; |
555 | 622 |
556 //---------------------------------------------------------------------------- | |
557 // Methods to override to create histogram with different bucket widths. | |
558 //---------------------------------------------------------------------------- | |
559 // Find bucket to increment for sample value. | |
560 virtual size_t BucketIndex(Sample value) const; | |
561 // Get normalized size, relative to the ranges(i). | 623 // Get normalized size, relative to the ranges(i). |
562 virtual double GetBucketSize(Count current, size_t i) const; | 624 virtual double GetBucketSize(Count current, size_t i) const; |
563 | 625 |
564 // Return a string description of what goes in a given bucket. | 626 // Return a string description of what goes in a given bucket. |
565 // Most commonly this is the numeric value, but in derived classes it may | 627 // Most commonly this is the numeric value, but in derived classes it may |
566 // be a name (or string description) given to the bucket. | 628 // be a name (or string description) given to the bucket. |
567 virtual const std::string GetAsciiBucketRange(size_t it) const; | 629 virtual const std::string GetAsciiBucketRange(size_t it) const; |
568 | 630 |
569 //---------------------------------------------------------------------------- | |
570 // Methods to override to create thread safe histogram. | |
571 //---------------------------------------------------------------------------- | |
572 // Update all our internal data, including histogram | |
573 virtual void Accumulate(Sample value, Count count, size_t index); | |
574 | |
575 private: | 631 private: |
576 // Allow tests to corrupt our innards for testing purposes. | 632 // Allow tests to corrupt our innards for testing purposes. |
577 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); | 633 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); |
578 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); | 634 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); |
579 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32SampleHash); | 635 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32SampleHash); |
580 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32TableTest); | 636 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32TableTest); |
581 | 637 |
582 friend class StatisticsRecorder; // To allow it to delete duplicates. | 638 friend class StatisticsRecorder; // To allow it to delete duplicates. |
583 friend class StatisticsRecorderTest; | 639 friend class StatisticsRecorderTest; |
584 | 640 |
585 //---------------------------------------------------------------------------- | 641 //---------------------------------------------------------------------------- |
586 // Helpers for emitting Ascii graphic. Each method appends data to output. | 642 // Helpers for emitting Ascii graphic. Each method appends data to output. |
587 | 643 |
588 void WriteAsciiImpl(bool graph_it, | 644 void WriteAsciiImpl(bool graph_it, |
589 const std::string& newline, | 645 const std::string& newline, |
590 std::string* output) const; | 646 std::string* output) const; |
591 | 647 |
592 // Find out how large the (graphically) the largest bucket will appear to be. | 648 // Find out how large (graphically) the largest bucket will appear to be. |
593 double GetPeakBucketSize(const SampleSet& snapshot) const; | 649 double GetPeakBucketSize(const BucketHistogramSamples& samples) const; |
594 | 650 |
595 // Write a common header message describing this histogram. | 651 // Write a common header message describing this histogram. |
596 void WriteAsciiHeader(const SampleSet& snapshot, | 652 void WriteAsciiHeader(const BucketHistogramSamples& samples, |
597 Count sample_count, std::string* output) const; | 653 Count sample_count, |
654 std::string* output) const; | |
598 | 655 |
599 // Write information about previous, current, and next buckets. | 656 // Write information about previous, current, and next buckets. |
600 // Information such as cumulative percentage, etc. | 657 // Information such as cumulative percentage, etc. |
601 void WriteAsciiBucketContext(const int64 past, const Count current, | 658 void WriteAsciiBucketContext(const int64 past, const Count current, |
602 const int64 remaining, const size_t i, | 659 const int64 remaining, const size_t i, |
603 std::string* output) const; | 660 std::string* output) const; |
604 | 661 |
605 // Write textual description of the bucket contents (relative to histogram). | 662 // Write textual description of the bucket contents (relative to histogram). |
606 // Output is the count in the buckets, as well as the percentage. | 663 // Output is the count in the buckets, as well as the percentage. |
607 void WriteAsciiBucketValue(Count current, double scaled_sum, | 664 void WriteAsciiBucketValue(Count current, double scaled_sum, |
608 std::string* output) const; | 665 std::string* output) const; |
609 | 666 |
610 // Produce actual graph (set of blank vs non blank char's) for a bucket. | 667 // Produce actual graph (set of blank vs non blank char's) for a bucket. |
611 void WriteAsciiBucketGraph(double current_size, double max_size, | 668 void WriteAsciiBucketGraph(double current_size, double max_size, |
612 std::string* output) const; | 669 std::string* output) const; |
613 | 670 |
614 // Does not own this object. Should get from StatisticsRecorder. | 671 // Does not own this object. Should get from StatisticsRecorder. |
615 const BucketRanges* bucket_ranges_; | 672 const BucketRanges* bucket_ranges_; |
616 | 673 |
617 Sample declared_min_; // Less than this goes into counts_[0] | 674 Sample declared_min_; // Less than this goes into counts_[0] |
618 Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. | 675 Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. |
619 size_t bucket_count_; // Dimension of counts_[]. | 676 size_t bucket_count_; // Dimension of counts_[]. |
620 | 677 |
621 // Finally, provide the state that changes with the addition of each new | 678 // Finally, provide the state that changes with the addition of each new |
622 // sample. | 679 // sample. |
623 SampleSet sample_; | 680 scoped_ptr<BucketHistogramSamples> samples_; |
624 | 681 |
625 DISALLOW_COPY_AND_ASSIGN(Histogram); | 682 DISALLOW_COPY_AND_ASSIGN(Histogram); |
626 }; | 683 }; |
627 | 684 |
628 //------------------------------------------------------------------------------ | 685 //------------------------------------------------------------------------------ |
629 | 686 |
630 // LinearHistogram is a more traditional histogram, with evenly spaced | 687 // LinearHistogram is a more traditional histogram, with evenly spaced |
631 // buckets. | 688 // buckets. |
632 class BASE_EXPORT LinearHistogram : public Histogram { | 689 class BASE_EXPORT LinearHistogram : public Histogram { |
633 public: | 690 public: |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
744 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | 801 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
745 static BucketRanges* CreateBucketRangesFromCustomRanges( | 802 static BucketRanges* CreateBucketRangesFromCustomRanges( |
746 const std::vector<Sample>& custom_ranges); | 803 const std::vector<Sample>& custom_ranges); |
747 | 804 |
748 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 805 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
749 }; | 806 }; |
750 | 807 |
751 } // namespace base | 808 } // namespace base |
752 | 809 |
753 #endif // BASE_METRICS_HISTOGRAM_H_ | 810 #endif // BASE_METRICS_HISTOGRAM_H_ |
OLD | NEW |