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

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

Issue 10829466: SampleSet -> HistogramSamples (will be reused by SparseHistogram) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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
« no previous file with comments | « base/metrics/bucket_ranges.h ('k') | base/metrics/histogram.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
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"
75 #include "base/metrics/sample_vector.h"
73 #include "base/time.h" 76 #include "base/time.h"
74 77
75 class Pickle; 78 class Pickle;
76 class PickleIterator; 79 class PickleIterator;
77 80
78 namespace base { 81 namespace base {
79 82
80 class Lock; 83 class Lock;
81 //------------------------------------------------------------------------------ 84 //------------------------------------------------------------------------------
82 // Histograms are often put in areas where they are called many many times, and 85 // Histograms are often put in areas where they are called many many times, and
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ 334 base::LinearHistogram::FactoryGet(name, 1, boundary_value, \
332 boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag)) 335 boundary_value + 1, base::Histogram::kUmaTargetedHistogramFlag))
333 336
334 #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ 337 #define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \
335 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ 338 STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \
336 base::CustomHistogram::FactoryGet(name, custom_ranges, \ 339 base::CustomHistogram::FactoryGet(name, custom_ranges, \
337 base::Histogram::kUmaTargetedHistogramFlag)) 340 base::Histogram::kUmaTargetedHistogramFlag))
338 341
339 //------------------------------------------------------------------------------ 342 //------------------------------------------------------------------------------
340 343
344 class BucketRanges;
345 class SampleVector;
346
341 class BooleanHistogram; 347 class BooleanHistogram;
342 class BucketRanges;
343 class CustomHistogram; 348 class CustomHistogram;
344 class Histogram; 349 class Histogram;
345 class LinearHistogram; 350 class LinearHistogram;
346 351
347 class BASE_EXPORT Histogram : public HistogramBase { 352 class BASE_EXPORT Histogram : public HistogramBase {
348 public: 353 public:
349 // Initialize maximum number of buckets in histograms as 16,384. 354 // Initialize maximum number of buckets in histograms as 16,384.
350 static const size_t kBucketCount_MAX; 355 static const size_t kBucketCount_MAX;
351 356
352 typedef std::vector<Count> Counts; 357 typedef std::vector<Count> Counts;
(...skipping 23 matching lines...) Expand all
376 381
377 NEVER_EXCEEDED_VALUE = 0x10 382 NEVER_EXCEEDED_VALUE = 0x10
378 }; 383 };
379 384
380 struct DescriptionPair { 385 struct DescriptionPair {
381 Sample sample; 386 Sample sample;
382 const char* description; // Null means end of a list of pairs. 387 const char* description; // Null means end of a list of pairs.
383 }; 388 };
384 389
385 //---------------------------------------------------------------------------- 390 //----------------------------------------------------------------------------
386 // Statistic values, developed over the life of the histogram.
387
388 class BASE_EXPORT SampleSet {
389 public:
390 explicit SampleSet(size_t size);
391 SampleSet();
392 ~SampleSet();
393
394 void Resize(size_t size);
395
396 // Accessor for histogram to make routine additions.
397 void Accumulate(Sample value, Count count, size_t index);
398
399 // Accessor methods.
400 size_t size() const { return counts_.size(); }
401 Count counts(size_t i) const { return counts_[i]; }
402 Count TotalCount() const;
403 int64 sum() const { return sum_; }
404 int64 redundant_count() const { return redundant_count_; }
405
406 // Arithmetic manipulation of corresponding elements of the set.
407 void Add(const SampleSet& other);
408 void Subtract(const SampleSet& other);
409
410 bool Serialize(Pickle* pickle) const;
411 bool Deserialize(PickleIterator* iter);
412
413 protected:
414 // Actual histogram data is stored in buckets, showing the count of values
415 // that fit into each bucket.
416 Counts counts_;
417
418 // Save simple stats locally. Note that this MIGHT get done in base class
419 // without shared memory at some point.
420 int64 sum_; // sum of samples.
421
422 private:
423 // Allow tests to corrupt our innards for testing purposes.
424 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
425
426 // To help identify memory corruption, we reduntantly save the number of
427 // samples we've accumulated into all of our buckets. We can compare this
428 // count to the sum of the counts in all buckets, and detect problems. Note
429 // that due to races in histogram accumulation (if a histogram is indeed
430 // updated on several threads simultaneously), the tallies might mismatch,
431 // and also the snapshotting code may asynchronously get a mismatch (though
432 // generally either race based mismatch cause is VERY rare).
433 int64 redundant_count_;
434 };
435
436 //----------------------------------------------------------------------------
437 // For a valid histogram, input should follow these restrictions: 391 // For a valid histogram, input should follow these restrictions:
438 // minimum > 0 (if a minimum below 1 is specified, it will implicitly be 392 // minimum > 0 (if a minimum below 1 is specified, it will implicitly be
439 // normalized up to 1) 393 // normalized up to 1)
440 // maximum > minimum 394 // maximum > minimum
441 // buckets > 2 [minimum buckets needed: underflow, overflow and the range] 395 // buckets > 2 [minimum buckets needed: underflow, overflow and the range]
442 // Additionally, 396 // Additionally,
443 // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have 397 // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have
444 // more buckets than the range of numbers; having more buckets than 1 per 398 // more buckets than the range of numbers; having more buckets than 1 per
445 // value in the range would be nonsensical. 399 // value in the range would be nonsensical.
446 static Histogram* FactoryGet(const std::string& name, 400 static Histogram* FactoryGet(const std::string& name,
(...skipping 19 matching lines...) Expand all
466 virtual void Add(Sample value) OVERRIDE; 420 virtual void Add(Sample value) OVERRIDE;
467 421
468 // This method is an interface, used only by BooleanHistogram. 422 // This method is an interface, used only by BooleanHistogram.
469 virtual void AddBoolean(bool value); 423 virtual void AddBoolean(bool value);
470 424
471 // Accept a TimeDelta to increment. 425 // Accept a TimeDelta to increment.
472 void AddTime(TimeDelta time) { 426 void AddTime(TimeDelta time) {
473 Add(static_cast<int>(time.InMilliseconds())); 427 Add(static_cast<int>(time.InMilliseconds()));
474 } 428 }
475 429
476 void AddSampleSet(const SampleSet& sample); 430 void AddSamples(const HistogramSamples& samples);
431 bool AddSamplesFromPickle(PickleIterator* iter);
477 432
478 // This method is an interface, used only by LinearHistogram. 433 // This method is an interface, used only by LinearHistogram.
479 virtual void SetRangeDescriptions(const DescriptionPair descriptions[]); 434 virtual void SetRangeDescriptions(const DescriptionPair descriptions[]);
480 435
481 // The following methods provide graphical histogram displays. 436 // The following methods provide graphical histogram displays.
482 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; 437 virtual void WriteHTMLGraph(std::string* output) const OVERRIDE;
483 virtual void WriteAscii(std::string* output) const OVERRIDE; 438 virtual void WriteAscii(std::string* output) const OVERRIDE;
484 439
485 // Convenience methods for serializing/deserializing the histograms. 440 // Convenience methods for serializing/deserializing the histograms.
486 // Histograms from Renderer process are serialized and sent to the browser. 441 // Histograms from Renderer process are serialized and sent to the browser.
487 // Browser process reconstructs the histogram from the pickled version 442 // Browser process reconstructs the histogram from the pickled version
488 // accumulates the browser-side shadow copy of histograms (that mirror 443 // accumulates the browser-side shadow copy of histograms (that mirror
489 // histograms created in the renderer). 444 // histograms created in the renderer).
490 445
491 // Serialize the given snapshot of a Histogram into a String. Uses 446 // Serialize the given snapshot of a Histogram into a String. Uses
492 // Pickle class to flatten the object. 447 // Pickle class to flatten the object.
493 static std::string SerializeHistogramInfo(const Histogram& histogram, 448 static std::string SerializeHistogramInfo(const Histogram& histogram,
494 const SampleSet& snapshot); 449 const HistogramSamples& snapshot);
495 450
496 // The following method accepts a list of pickled histograms and 451 // The following method accepts a list of pickled histograms and
497 // builds a histogram and updates shadow copy of histogram data in the 452 // builds a histogram and updates shadow copy of histogram data in the
498 // browser process. 453 // browser process.
499 static bool DeserializeHistogramInfo(const std::string& histogram_info); 454 static bool DeserializeHistogramInfo(const std::string& histogram_info);
500 455
456 // This constant if for FindCorruption. Since snapshots of histograms are
457 // taken asynchronously relative to sampling, and our counting code currently
458 // does not prevent race conditions, it is pretty likely that we'll catch a
459 // redundant count that doesn't match the sample count. We allow for a
460 // certain amount of slop before flagging this as an inconsistency. Even with
461 // an inconsistency, we'll snapshot it again (for UMA in about a half hour),
462 // so we'll eventually get the data, if it was not the result of a corruption.
463 static const int kCommonRaceBasedCountMismatch;
464
501 // Check to see if bucket ranges, counts and tallies in the snapshot are 465 // 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 466 // 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 467 // 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 468 // a SnapShot process, but should otherwise be false at all times (unless we
505 // have memory over-writes, or DRAM failures). 469 // have memory over-writes, or DRAM failures).
506 virtual Inconsistencies FindCorruption(const SampleSet& snapshot) const; 470 virtual Inconsistencies FindCorruption(const HistogramSamples& samples) const;
507 471
508 //---------------------------------------------------------------------------- 472 //----------------------------------------------------------------------------
509 // Accessors for factory constuction, serialization and testing. 473 // Accessors for factory constuction, serialization and testing.
510 //---------------------------------------------------------------------------- 474 //----------------------------------------------------------------------------
511 virtual ClassType histogram_type() const; 475 virtual ClassType histogram_type() const;
512 Sample declared_min() const { return declared_min_; } 476 Sample declared_min() const { return declared_min_; }
513 Sample declared_max() const { return declared_max_; } 477 Sample declared_max() const { return declared_max_; }
514 virtual Sample ranges(size_t i) const; 478 virtual Sample ranges(size_t i) const;
515 virtual size_t bucket_count() const; 479 virtual size_t bucket_count() const;
516 const BucketRanges* bucket_ranges() const { return bucket_ranges_; } 480 const BucketRanges* bucket_ranges() const { return bucket_ranges_; }
517 481
518 // Snapshot the current complete set of sample data. 482 // Snapshot the current complete set of sample data.
519 // Override with atomic/locked snapshot if needed. 483 // Override with atomic/locked snapshot if needed.
520 virtual void SnapshotSample(SampleSet* sample) const; 484 virtual scoped_ptr<SampleVector> SnapshotSamples() const;
521 485
522 virtual bool HasConstructionArguments(Sample minimum, 486 virtual bool HasConstructionArguments(Sample minimum,
523 Sample maximum, 487 Sample maximum,
524 size_t bucket_count); 488 size_t bucket_count);
525 protected: 489 protected:
526 // |bucket_count| and |ranges| should contain the underflow and overflow 490 // |bucket_count| and |ranges| should contain the underflow and overflow
527 // buckets. See top comments for example. 491 // buckets. See top comments for example.
528 Histogram(const std::string& name, 492 Histogram(const std::string& name,
529 Sample minimum, 493 Sample minimum,
530 Sample maximum, 494 Sample maximum,
(...skipping 15 matching lines...) Expand all
546 510
547 // Serialize the histogram's ranges to |*pickle|, returning true on success. 511 // 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 512 // 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 513 // override it, especially if the ranges cannot be re-derived from other
550 // serialized parameters. 514 // serialized parameters.
551 virtual bool SerializeRanges(Pickle* pickle) const; 515 virtual bool SerializeRanges(Pickle* pickle) const;
552 516
553 // Method to override to skip the display of the i'th bucket if it's empty. 517 // Method to override to skip the display of the i'th bucket if it's empty.
554 virtual bool PrintEmptyBucket(size_t index) const; 518 virtual bool PrintEmptyBucket(size_t index) const;
555 519
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). 520 // Get normalized size, relative to the ranges(i).
562 virtual double GetBucketSize(Count current, size_t i) const; 521 virtual double GetBucketSize(Count current, size_t i) const;
563 522
564 // Return a string description of what goes in a given bucket. 523 // 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 524 // Most commonly this is the numeric value, but in derived classes it may
566 // be a name (or string description) given to the bucket. 525 // be a name (or string description) given to the bucket.
567 virtual const std::string GetAsciiBucketRange(size_t it) const; 526 virtual const std::string GetAsciiBucketRange(size_t it) const;
568 527
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: 528 private:
576 // Allow tests to corrupt our innards for testing purposes. 529 // Allow tests to corrupt our innards for testing purposes.
577 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); 530 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds);
578 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); 531 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
579 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32SampleHash); 532 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32SampleHash);
580 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32TableTest); 533 FRIEND_TEST_ALL_PREFIXES(HistogramTest, Crc32TableTest);
581 534
582 friend class StatisticsRecorder; // To allow it to delete duplicates. 535 friend class StatisticsRecorder; // To allow it to delete duplicates.
583 friend class StatisticsRecorderTest; 536 friend class StatisticsRecorderTest;
584 537
585 //---------------------------------------------------------------------------- 538 //----------------------------------------------------------------------------
586 // Helpers for emitting Ascii graphic. Each method appends data to output. 539 // Helpers for emitting Ascii graphic. Each method appends data to output.
587 540
588 void WriteAsciiImpl(bool graph_it, 541 void WriteAsciiImpl(bool graph_it,
589 const std::string& newline, 542 const std::string& newline,
590 std::string* output) const; 543 std::string* output) const;
591 544
592 // Find out how large the (graphically) the largest bucket will appear to be. 545 // Find out how large (graphically) the largest bucket will appear to be.
593 double GetPeakBucketSize(const SampleSet& snapshot) const; 546 double GetPeakBucketSize(const SampleVector& samples) const;
594 547
595 // Write a common header message describing this histogram. 548 // Write a common header message describing this histogram.
596 void WriteAsciiHeader(const SampleSet& snapshot, 549 void WriteAsciiHeader(const SampleVector& samples,
597 Count sample_count, std::string* output) const; 550 Count sample_count,
551 std::string* output) const;
598 552
599 // Write information about previous, current, and next buckets. 553 // Write information about previous, current, and next buckets.
600 // Information such as cumulative percentage, etc. 554 // Information such as cumulative percentage, etc.
601 void WriteAsciiBucketContext(const int64 past, const Count current, 555 void WriteAsciiBucketContext(const int64 past, const Count current,
602 const int64 remaining, const size_t i, 556 const int64 remaining, const size_t i,
603 std::string* output) const; 557 std::string* output) const;
604 558
605 // Write textual description of the bucket contents (relative to histogram). 559 // Write textual description of the bucket contents (relative to histogram).
606 // Output is the count in the buckets, as well as the percentage. 560 // Output is the count in the buckets, as well as the percentage.
607 void WriteAsciiBucketValue(Count current, double scaled_sum, 561 void WriteAsciiBucketValue(Count current, double scaled_sum,
608 std::string* output) const; 562 std::string* output) const;
609 563
610 // Produce actual graph (set of blank vs non blank char's) for a bucket. 564 // Produce actual graph (set of blank vs non blank char's) for a bucket.
611 void WriteAsciiBucketGraph(double current_size, double max_size, 565 void WriteAsciiBucketGraph(double current_size, double max_size,
612 std::string* output) const; 566 std::string* output) const;
613 567
614 // Does not own this object. Should get from StatisticsRecorder. 568 // Does not own this object. Should get from StatisticsRecorder.
615 const BucketRanges* bucket_ranges_; 569 const BucketRanges* bucket_ranges_;
616 570
617 Sample declared_min_; // Less than this goes into counts_[0] 571 Sample declared_min_; // Less than this goes into counts_[0]
618 Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. 572 Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1].
619 size_t bucket_count_; // Dimension of counts_[]. 573 size_t bucket_count_; // Dimension of counts_[].
620 574
621 // Finally, provide the state that changes with the addition of each new 575 // Finally, provide the state that changes with the addition of each new
622 // sample. 576 // sample.
623 SampleSet sample_; 577 scoped_ptr<SampleVector> samples_;
624 578
625 DISALLOW_COPY_AND_ASSIGN(Histogram); 579 DISALLOW_COPY_AND_ASSIGN(Histogram);
626 }; 580 };
627 581
628 //------------------------------------------------------------------------------ 582 //------------------------------------------------------------------------------
629 583
630 // LinearHistogram is a more traditional histogram, with evenly spaced 584 // LinearHistogram is a more traditional histogram, with evenly spaced
631 // buckets. 585 // buckets.
632 class BASE_EXPORT LinearHistogram : public Histogram { 586 class BASE_EXPORT LinearHistogram : public Histogram {
633 public: 587 public:
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); 698 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges);
745 static BucketRanges* CreateBucketRangesFromCustomRanges( 699 static BucketRanges* CreateBucketRangesFromCustomRanges(
746 const std::vector<Sample>& custom_ranges); 700 const std::vector<Sample>& custom_ranges);
747 701
748 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); 702 DISALLOW_COPY_AND_ASSIGN(CustomHistogram);
749 }; 703 };
750 704
751 } // namespace base 705 } // namespace base
752 706
753 #endif // BASE_METRICS_HISTOGRAM_H_ 707 #endif // BASE_METRICS_HISTOGRAM_H_
OLDNEW
« no previous file with comments | « base/metrics/bucket_ranges.h ('k') | base/metrics/histogram.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698