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

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

Issue 11682003: Serialize/Deserialize support in HistogramBase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 12 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.
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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;
495 friend HistogramBase* HistogramBase::DeserializeHistogramInfo(
496 PickleIterator* iter);
Ilya Sherman 2012/12/29 00:17:30 Why does HistogramBase need to know about the Hist
kaiwang 2013/01/08 00:51:40 I need a function to know all kind of histograms t
Ilya Sherman 2013/01/08 22:31:53 If you keep roughly the current design, I'd prefer
497
498 static HistogramBase* DeserializeHistogramInfo(PickleIterator* iter);
520 499
521 // Implementation of SnapshotSamples function. 500 // Implementation of SnapshotSamples function.
522 scoped_ptr<SampleVector> SnapshotSampleVector() const; 501 scoped_ptr<SampleVector> SnapshotSampleVector() const;
523 502
524 //---------------------------------------------------------------------------- 503 //----------------------------------------------------------------------------
525 // Helpers for emitting Ascii graphic. Each method appends data to output. 504 // Helpers for emitting Ascii graphic. Each method appends data to output.
526 505
527 void WriteAsciiImpl(bool graph_it, 506 void WriteAsciiImpl(bool graph_it,
528 const std::string& newline, 507 const std::string& newline,
529 std::string* output) const; 508 std::string* output) const;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 TimeDelta minimum, 569 TimeDelta minimum,
591 TimeDelta maximum, 570 TimeDelta maximum,
592 size_t bucket_count, 571 size_t bucket_count,
593 int32 flags); 572 int32 flags);
594 573
595 // Create a LinearHistogram and store a list of number/text values for use in 574 // Create a LinearHistogram and store a list of number/text values for use in
596 // writing the histogram graph. 575 // writing the histogram graph.
597 // |descriptions| can be NULL, which means no special descriptions to set. If 576 // |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 577 // it's not NULL, the last element in the array must has a NULL in its
599 // "description" field. 578 // "description" field.
579 struct DescriptionPair {
580 Sample sample;
581 const char* description; // Null means end of a list of pairs.
582 };
Ilya Sherman 2012/12/29 00:17:30 nit: Please move this to be above the comment that
kaiwang 2013/01/08 00:51:40 Done.
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,
605 int32 flags, 588 int32 flags,
606 const DescriptionPair descriptions[]); 589 const DescriptionPair descriptions[]);
607 590
608 static void InitializeBucketRanges(Sample minimum, 591 static void InitializeBucketRanges(Sample minimum,
609 Sample maximum, 592 Sample maximum,
(...skipping 14 matching lines...) Expand all
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* HistogramBase::DeserializeHistogramInfo(
618 PickleIterator* iter);
619 static HistogramBase* DeserializeHistogramInfo(PickleIterator* iter);
620
634 // For some ranges, we store a printable description of a bucket range. 621 // For some ranges, we store a printable description of a bucket range.
635 // If there is no desciption, then GetAsciiBucketRange() uses parent class 622 // If there is no desciption, then GetAsciiBucketRange() uses parent class
636 // to provide a description. 623 // to provide a description.
637 typedef std::map<Sample, std::string> BucketDescriptionMap; 624 typedef std::map<Sample, std::string> BucketDescriptionMap;
638 BucketDescriptionMap bucket_description_; 625 BucketDescriptionMap bucket_description_;
639 626
640 DISALLOW_COPY_AND_ASSIGN(LinearHistogram); 627 DISALLOW_COPY_AND_ASSIGN(LinearHistogram);
641 }; 628 };
642 629
643 //------------------------------------------------------------------------------ 630 //------------------------------------------------------------------------------
644 631
645 // BooleanHistogram is a histogram for booleans. 632 // BooleanHistogram is a histogram for booleans.
646 class BASE_EXPORT BooleanHistogram : public LinearHistogram { 633 class BASE_EXPORT BooleanHistogram : public LinearHistogram {
647 public: 634 public:
648 static Histogram* FactoryGet(const std::string& name, int32 flags); 635 static Histogram* FactoryGet(const std::string& name, int32 flags);
649 636
650 virtual HistogramType GetHistogramType() const OVERRIDE; 637 virtual HistogramType GetHistogramType() const OVERRIDE;
651 638
652 virtual void AddBoolean(bool value) OVERRIDE; 639 virtual void AddBoolean(bool value) OVERRIDE;
653 640
654 private: 641 private:
655 BooleanHistogram(const std::string& name, const BucketRanges* ranges); 642 BooleanHistogram(const std::string& name, const BucketRanges* ranges);
656 643
644 friend HistogramBase* HistogramBase::DeserializeHistogramInfo(
645 PickleIterator* iter);
646 static HistogramBase* DeserializeHistogramInfo(PickleIterator* iter);
647
657 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); 648 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram);
658 }; 649 };
659 650
660 //------------------------------------------------------------------------------ 651 //------------------------------------------------------------------------------
661 652
662 // CustomHistogram is a histogram for a set of custom integers. 653 // CustomHistogram is a histogram for a set of custom integers.
663 class BASE_EXPORT CustomHistogram : public Histogram { 654 class BASE_EXPORT CustomHistogram : public Histogram {
664 public: 655 public:
665 // |custom_ranges| contains a vector of limits on ranges. Each limit should be 656 // |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 657 // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward
667 // compatibility). The limits can be unordered or contain duplication, but 658 // compatibility). The limits can be unordered or contain duplication, but
668 // client should not depend on this. 659 // client should not depend on this.
669 static Histogram* FactoryGet(const std::string& name, 660 static Histogram* FactoryGet(const std::string& name,
670 const std::vector<Sample>& custom_ranges, 661 const std::vector<Sample>& custom_ranges,
671 int32 flags); 662 int32 flags);
672 663
673 // Overridden from Histogram: 664 // Overridden from Histogram:
674 virtual HistogramType GetHistogramType() const OVERRIDE; 665 virtual HistogramType GetHistogramType() const OVERRIDE;
675 666
676 // Helper method for transforming an array of valid enumeration values 667 // Helper method for transforming an array of valid enumeration values
677 // to the std::vector<int> expected by HISTOGRAM_CUSTOM_ENUMERATION. 668 // to the std::vector<int> expected by HISTOGRAM_CUSTOM_ENUMERATION.
678 // This function ensures that a guard bucket exists right after any 669 // 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), 670 // 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. 671 // so that invalid samples never fall into the same bucket as valid samples.
681 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. 672 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges.
682 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, 673 static std::vector<Sample> ArrayToCustomRanges(const Sample* values,
683 size_t num_values); 674 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: 675 protected:
690 CustomHistogram(const std::string& name, 676 CustomHistogram(const std::string& name,
691 const BucketRanges* ranges); 677 const BucketRanges* ranges);
692 678
693 virtual bool SerializeRanges(Pickle* pickle) const OVERRIDE; 679 // HistogramBase implementation:
680 virtual bool SerializeInfoImpl(Pickle* pickle) const OVERRIDE;
694 681
695 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE; 682 virtual double GetBucketSize(Count current, size_t i) const OVERRIDE;
696 683
697 private: 684 private:
685 friend HistogramBase* HistogramBase::DeserializeHistogramInfo(
686 PickleIterator* iter);
687 static HistogramBase* DeserializeHistogramInfo(PickleIterator* iter);
688
698 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); 689 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges);
699 static BucketRanges* CreateBucketRangesFromCustomRanges( 690 static BucketRanges* CreateBucketRangesFromCustomRanges(
700 const std::vector<Sample>& custom_ranges); 691 const std::vector<Sample>& custom_ranges);
701 692
702 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); 693 DISALLOW_COPY_AND_ASSIGN(CustomHistogram);
703 }; 694 };
704 695
705 } // namespace base 696 } // namespace base
706 697
707 #endif // BASE_METRICS_HISTOGRAM_H_ 698 #endif // BASE_METRICS_HISTOGRAM_H_
OLDNEW
« no previous file with comments | « base/base.gyp ('k') | base/metrics/histogram.cc » ('j') | base/metrics/histogram.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698