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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 enum Inconsistencies { | 364 enum Inconsistencies { |
365 NO_INCONSISTENCIES = 0x0, | 365 NO_INCONSISTENCIES = 0x0, |
366 RANGE_CHECKSUM_ERROR = 0x1, | 366 RANGE_CHECKSUM_ERROR = 0x1, |
367 BUCKET_ORDER_ERROR = 0x2, | 367 BUCKET_ORDER_ERROR = 0x2, |
368 COUNT_HIGH_ERROR = 0x4, | 368 COUNT_HIGH_ERROR = 0x4, |
369 COUNT_LOW_ERROR = 0x8, | 369 COUNT_LOW_ERROR = 0x8, |
370 | 370 |
371 NEVER_EXCEEDED_VALUE = 0x10 | 371 NEVER_EXCEEDED_VALUE = 0x10 |
372 }; | 372 }; |
373 | 373 |
374 struct DescriptionPair { | |
375 Sample sample; | |
376 const char* description; // Null means end of a list of pairs. | |
377 }; | |
378 | |
379 //---------------------------------------------------------------------------- | 374 //---------------------------------------------------------------------------- |
380 // For a valid histogram, input should follow these restrictions: | 375 // For a valid histogram, input should follow these restrictions: |
381 // minimum > 0 (if a minimum below 1 is specified, it will implicitly be | 376 // minimum > 0 (if a minimum below 1 is specified, it will implicitly be |
382 // normalized up to 1) | 377 // normalized up to 1) |
383 // maximum > minimum | 378 // maximum > minimum |
384 // buckets > 2 [minimum buckets needed: underflow, overflow and the range] | 379 // buckets > 2 [minimum buckets needed: underflow, overflow and the range] |
385 // Additionally, | 380 // Additionally, |
386 // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have | 381 // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have |
387 // more buckets than the range of numbers; having more buckets than 1 per | 382 // more buckets than the range of numbers; having more buckets than 1 per |
388 // value in the range would be nonsensical. | 383 // value in the range would be nonsensical. |
(...skipping 18 matching lines...) Expand all Loading... | |
407 BucketRanges* ranges); | 402 BucketRanges* ranges); |
408 | 403 |
409 // This method is an interface, used only by BooleanHistogram. | 404 // This method is an interface, used only by BooleanHistogram. |
410 virtual void AddBoolean(bool value); | 405 virtual void AddBoolean(bool value); |
411 | 406 |
412 // Accept a TimeDelta to increment. | 407 // Accept a TimeDelta to increment. |
413 void AddTime(TimeDelta time) { | 408 void AddTime(TimeDelta time) { |
414 Add(static_cast<int>(time.InMilliseconds())); | 409 Add(static_cast<int>(time.InMilliseconds())); |
415 } | 410 } |
416 | 411 |
417 void AddSamples(const HistogramSamples& samples); | |
418 bool AddSamplesFromPickle(PickleIterator* iter); | |
419 | |
420 // Convenience methods for serializing/deserializing the histograms. | |
421 // Histograms from Renderer process are serialized and sent to the browser. | |
422 // Browser process reconstructs the histogram from the pickled version | |
423 // accumulates the browser-side shadow copy of histograms (that mirror | |
424 // histograms created in the renderer). | |
425 | |
426 // Serialize the given snapshot of a Histogram into a String. Uses | |
427 // Pickle class to flatten the object. | |
428 static std::string SerializeHistogramInfo(const Histogram& histogram, | |
429 const HistogramSamples& snapshot); | |
430 | |
431 // The following method accepts a list of pickled histograms and | |
432 // builds a histogram and updates shadow copy of histogram data in the | |
433 // browser process. | |
434 static bool DeserializeHistogramInfo(const std::string& histogram_info); | |
435 | |
436 // This constant if for FindCorruption. Since snapshots of histograms are | 412 // This constant if for FindCorruption. Since snapshots of histograms are |
437 // taken asynchronously relative to sampling, and our counting code currently | 413 // taken asynchronously relative to sampling, and our counting code currently |
438 // does not prevent race conditions, it is pretty likely that we'll catch a | 414 // does not prevent race conditions, it is pretty likely that we'll catch a |
439 // redundant count that doesn't match the sample count. We allow for a | 415 // redundant count that doesn't match the sample count. We allow for a |
440 // certain amount of slop before flagging this as an inconsistency. Even with | 416 // certain amount of slop before flagging this as an inconsistency. Even with |
441 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), | 417 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), |
442 // so we'll eventually get the data, if it was not the result of a corruption. | 418 // so we'll eventually get the data, if it was not the result of a corruption. |
443 static const int kCommonRaceBasedCountMismatch; | 419 static const int kCommonRaceBasedCountMismatch; |
444 | 420 |
445 // Check to see if bucket ranges, counts and tallies in the snapshot are | 421 // Check to see if bucket ranges, counts and tallies in the snapshot are |
(...skipping 23 matching lines...) Expand all Loading... | |
469 Sample* maximum, | 445 Sample* maximum, |
470 size_t* bucket_count); | 446 size_t* bucket_count); |
471 | 447 |
472 // HistogramBase implementation: | 448 // HistogramBase implementation: |
473 virtual HistogramType GetHistogramType() const OVERRIDE; | 449 virtual HistogramType GetHistogramType() const OVERRIDE; |
474 virtual bool HasConstructionArguments(Sample minimum, | 450 virtual bool HasConstructionArguments(Sample minimum, |
475 Sample maximum, | 451 Sample maximum, |
476 size_t bucket_count) const OVERRIDE; | 452 size_t bucket_count) const OVERRIDE; |
477 virtual void Add(Sample value) OVERRIDE; | 453 virtual void Add(Sample value) OVERRIDE; |
478 virtual scoped_ptr<HistogramSamples> SnapshotSamples() const OVERRIDE; | 454 virtual scoped_ptr<HistogramSamples> SnapshotSamples() const OVERRIDE; |
455 virtual void AddSamples(const HistogramSamples& samples) OVERRIDE; | |
456 virtual bool AddSamplesFromPickle(PickleIterator* iter) OVERRIDE; | |
479 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; | 457 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; |
480 virtual void WriteAscii(std::string* output) const OVERRIDE; | 458 virtual void WriteAscii(std::string* output) const OVERRIDE; |
481 | 459 |
482 protected: | 460 protected: |
483 // |bucket_count| and |ranges| should contain the underflow and overflow | 461 // |bucket_count| and |ranges| should contain the underflow and overflow |
484 // buckets. See top comments for example. | 462 // buckets. See top comments for example. |
485 Histogram(const std::string& name, | 463 Histogram(const std::string& name, |
486 Sample minimum, | 464 Sample minimum, |
487 Sample maximum, | 465 Sample maximum, |
488 size_t bucket_count, | 466 size_t bucket_count, |
489 const BucketRanges* ranges); | 467 const BucketRanges* ranges); |
490 | 468 |
491 virtual ~Histogram(); | 469 virtual ~Histogram(); |
492 | 470 |
493 // Serialize the histogram's ranges to |*pickle|, returning true on success. | 471 // HistogramBase implementation: |
494 // Most subclasses can leave this no-op implementation, but some will want to | 472 virtual bool SerializeInfoImpl(Pickle* pickle) const OVERRIDE; |
495 // override it, especially if the ranges cannot be re-derived from other | |
496 // serialized parameters. | |
497 virtual bool SerializeRanges(Pickle* pickle) const; | |
498 | 473 |
499 // Method to override to skip the display of the i'th bucket if it's empty. | 474 // Method to override to skip the display of the i'th bucket if it's empty. |
500 virtual bool PrintEmptyBucket(size_t index) const; | 475 virtual bool PrintEmptyBucket(size_t index) const; |
501 | 476 |
502 // Get normalized size, relative to the ranges(i). | 477 // Get normalized size, relative to the ranges(i). |
503 virtual double GetBucketSize(Count current, size_t i) const; | 478 virtual double GetBucketSize(Count current, size_t i) const; |
504 | 479 |
505 // Return a string description of what goes in a given bucket. | 480 // Return a string description of what goes in a given bucket. |
506 // Most commonly this is the numeric value, but in derived classes it may | 481 // Most commonly this is the numeric value, but in derived classes it may |
507 // be a name (or string description) given to the bucket. | 482 // be a name (or string description) given to the bucket. |
508 virtual const std::string GetAsciiBucketRange(size_t it) const; | 483 virtual const std::string GetAsciiBucketRange(size_t it) const; |
509 | 484 |
510 private: | 485 private: |
511 // Allow tests to corrupt our innards for testing purposes. | 486 // Allow tests to corrupt our innards for testing purposes. |
512 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest); | 487 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest); |
513 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest); | 488 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest); |
514 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); | 489 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); |
515 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); | 490 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); |
516 FRIEND_TEST_ALL_PREFIXES(HistogramTest, NameMatchTest); | 491 FRIEND_TEST_ALL_PREFIXES(HistogramTest, NameMatchTest); |
517 | 492 |
518 friend class StatisticsRecorder; // To allow it to delete duplicates. | 493 friend class StatisticsRecorder; // To allow it to delete duplicates. |
519 friend class StatisticsRecorderTest; | 494 friend class StatisticsRecorderTest; |
520 | 495 |
496 friend HistogramBase* DeserializeHistogramInfo(PickleIterator* iter); | |
497 static HistogramBase* DeserializeInfoImpl(PickleIterator* iter); | |
Ilya Sherman
2013/01/09 05:48:37
IMO this should be public, rather than private+fri
kaiwang
2013/01/10 23:02:24
Note it only deserialize part of the info. type fi
| |
498 | |
521 // Implementation of SnapshotSamples function. | 499 // Implementation of SnapshotSamples function. |
522 scoped_ptr<SampleVector> SnapshotSampleVector() const; | 500 scoped_ptr<SampleVector> SnapshotSampleVector() const; |
523 | 501 |
524 //---------------------------------------------------------------------------- | 502 //---------------------------------------------------------------------------- |
525 // Helpers for emitting Ascii graphic. Each method appends data to output. | 503 // Helpers for emitting Ascii graphic. Each method appends data to output. |
526 | 504 |
527 void WriteAsciiImpl(bool graph_it, | 505 void WriteAsciiImpl(bool graph_it, |
528 const std::string& newline, | 506 const std::string& newline, |
529 std::string* output) const; | 507 std::string* output) const; |
530 | 508 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
585 Sample minimum, | 563 Sample minimum, |
586 Sample maximum, | 564 Sample maximum, |
587 size_t bucket_count, | 565 size_t bucket_count, |
588 int32 flags); | 566 int32 flags); |
589 static Histogram* FactoryTimeGet(const std::string& name, | 567 static Histogram* FactoryTimeGet(const std::string& name, |
590 TimeDelta minimum, | 568 TimeDelta minimum, |
591 TimeDelta maximum, | 569 TimeDelta maximum, |
592 size_t bucket_count, | 570 size_t bucket_count, |
593 int32 flags); | 571 int32 flags); |
594 | 572 |
573 struct DescriptionPair { | |
574 Sample sample; | |
575 const char* description; // Null means end of a list of pairs. | |
576 }; | |
577 | |
595 // Create a LinearHistogram and store a list of number/text values for use in | 578 // Create a LinearHistogram and store a list of number/text values for use in |
596 // writing the histogram graph. | 579 // writing the histogram graph. |
597 // |descriptions| can be NULL, which means no special descriptions to set. If | 580 // |descriptions| can be NULL, which means no special descriptions to set. If |
598 // it's not NULL, the last element in the array must has a NULL in its | 581 // it's not NULL, the last element in the array must has a NULL in its |
599 // "description" field. | 582 // "description" field. |
600 static Histogram* FactoryGetWithRangeDescription( | 583 static Histogram* FactoryGetWithRangeDescription( |
601 const std::string& name, | 584 const std::string& name, |
602 Sample minimum, | 585 Sample minimum, |
603 Sample maximum, | 586 Sample maximum, |
604 size_t bucket_count, | 587 size_t bucket_count, |
(...skipping 19 matching lines...) Expand all Loading... | |
624 | 607 |
625 // If we have a description for a bucket, then return that. Otherwise | 608 // If we have a description for a bucket, then return that. Otherwise |
626 // let parent class provide a (numeric) description. | 609 // let parent class provide a (numeric) description. |
627 virtual const std::string GetAsciiBucketRange(size_t i) const OVERRIDE; | 610 virtual const std::string GetAsciiBucketRange(size_t i) const OVERRIDE; |
628 | 611 |
629 // Skip printing of name for numeric range if we have a name (and if this is | 612 // Skip printing of name for numeric range if we have a name (and if this is |
630 // an empty bucket). | 613 // an empty bucket). |
631 virtual bool PrintEmptyBucket(size_t index) const OVERRIDE; | 614 virtual bool PrintEmptyBucket(size_t index) const OVERRIDE; |
632 | 615 |
633 private: | 616 private: |
617 friend HistogramBase* DeserializeHistogramInfo(PickleIterator* iter); | |
618 static HistogramBase* DeserializeInfoImpl(PickleIterator* iter); | |
619 | |
634 // For some ranges, we store a printable description of a bucket range. | 620 // For some ranges, we store a printable description of a bucket range. |
635 // If there is no desciption, then GetAsciiBucketRange() uses parent class | 621 // If there is no desciption, then GetAsciiBucketRange() uses parent class |
636 // to provide a description. | 622 // to provide a description. |
637 typedef std::map<Sample, std::string> BucketDescriptionMap; | 623 typedef std::map<Sample, std::string> BucketDescriptionMap; |
638 BucketDescriptionMap bucket_description_; | 624 BucketDescriptionMap bucket_description_; |
639 | 625 |
640 DISALLOW_COPY_AND_ASSIGN(LinearHistogram); | 626 DISALLOW_COPY_AND_ASSIGN(LinearHistogram); |
641 }; | 627 }; |
642 | 628 |
643 //------------------------------------------------------------------------------ | 629 //------------------------------------------------------------------------------ |
644 | 630 |
645 // BooleanHistogram is a histogram for booleans. | 631 // BooleanHistogram is a histogram for booleans. |
646 class BASE_EXPORT BooleanHistogram : public LinearHistogram { | 632 class BASE_EXPORT BooleanHistogram : public LinearHistogram { |
647 public: | 633 public: |
648 static Histogram* FactoryGet(const std::string& name, int32 flags); | 634 static Histogram* FactoryGet(const std::string& name, int32 flags); |
649 | 635 |
650 virtual HistogramType GetHistogramType() const OVERRIDE; | 636 virtual HistogramType GetHistogramType() const OVERRIDE; |
651 | 637 |
652 virtual void AddBoolean(bool value) OVERRIDE; | 638 virtual void AddBoolean(bool value) OVERRIDE; |
653 | 639 |
654 private: | 640 private: |
655 BooleanHistogram(const std::string& name, const BucketRanges* ranges); | 641 BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
656 | 642 |
643 friend HistogramBase* DeserializeHistogramInfo(PickleIterator* iter); | |
644 static HistogramBase* DeserializeInfoImpl(PickleIterator* iter); | |
645 | |
657 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); | 646 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
658 }; | 647 }; |
659 | 648 |
660 //------------------------------------------------------------------------------ | 649 //------------------------------------------------------------------------------ |
661 | 650 |
662 // CustomHistogram is a histogram for a set of custom integers. | 651 // CustomHistogram is a histogram for a set of custom integers. |
663 class BASE_EXPORT CustomHistogram : public Histogram { | 652 class BASE_EXPORT CustomHistogram : public Histogram { |
664 public: | 653 public: |
665 // |custom_ranges| contains a vector of limits on ranges. Each limit should be | 654 // |custom_ranges| contains a vector of limits on ranges. Each limit should be |
666 // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward | 655 // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward |
667 // compatibility). The limits can be unordered or contain duplication, but | 656 // compatibility). The limits can be unordered or contain duplication, but |
668 // client should not depend on this. | 657 // client should not depend on this. |
669 static Histogram* FactoryGet(const std::string& name, | 658 static Histogram* FactoryGet(const std::string& name, |
670 const std::vector<Sample>& custom_ranges, | 659 const std::vector<Sample>& custom_ranges, |
671 int32 flags); | 660 int32 flags); |
672 | 661 |
673 // Overridden from Histogram: | 662 // Overridden from Histogram: |
674 virtual HistogramType GetHistogramType() const OVERRIDE; | 663 virtual HistogramType GetHistogramType() const OVERRIDE; |
675 | 664 |
676 // Helper method for transforming an array of valid enumeration values | 665 // Helper method for transforming an array of valid enumeration values |
677 // to the std::vector<int> expected by HISTOGRAM_CUSTOM_ENUMERATION. | 666 // to the std::vector<int> expected by HISTOGRAM_CUSTOM_ENUMERATION. |
678 // This function ensures that a guard bucket exists right after any | 667 // This function ensures that a guard bucket exists right after any |
679 // valid sample value (unless the next higher sample is also a valid value), | 668 // valid sample value (unless the next higher sample is also a valid value), |
680 // so that invalid samples never fall into the same bucket as valid samples. | 669 // so that invalid samples never fall into the same bucket as valid samples. |
681 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. | 670 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. |
682 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, | 671 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
683 size_t num_values); | 672 size_t num_values); |
684 | |
685 // Helper for deserializing CustomHistograms. |*ranges| should already be | |
686 // correctly sized before this call. Return true on success. | |
687 static bool DeserializeRanges(PickleIterator* iter, | |
688 std::vector<Sample>* ranges); | |
689 protected: | 673 protected: |
690 CustomHistogram(const std::string& name, | 674 CustomHistogram(const std::string& name, |
691 const BucketRanges* ranges); | 675 const BucketRanges* ranges); |
692 | 676 |
693 virtual bool SerializeRanges(Pickle* pickle) const OVERRIDE; | 677 // HistogramBase implementation: |
678 virtual bool SerializeInfoImpl(Pickle* pickle) const OVERRIDE; | |
694 | 679 |
695 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; | 680 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; |
696 | 681 |
697 private: | 682 private: |
683 friend HistogramBase* DeserializeHistogramInfo(PickleIterator* iter); | |
684 static HistogramBase* DeserializeInfoImpl(PickleIterator* iter); | |
685 | |
698 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | 686 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
699 static BucketRanges* CreateBucketRangesFromCustomRanges( | 687 static BucketRanges* CreateBucketRangesFromCustomRanges( |
700 const std::vector<Sample>& custom_ranges); | 688 const std::vector<Sample>& custom_ranges); |
701 | 689 |
702 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 690 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
703 }; | 691 }; |
704 | 692 |
705 } // namespace base | 693 } // namespace base |
706 | 694 |
707 #endif // BASE_METRICS_HISTOGRAM_H_ | 695 #endif // BASE_METRICS_HISTOGRAM_H_ |
OLD | NEW |