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

Unified 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, 5 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 side-by-side diff with in-line comments
Download patch
Index: base/metrics/histogram.h
===================================================================
--- base/metrics/histogram.h (revision 148055)
+++ base/metrics/histogram.h (working copy)
@@ -9,14 +9,29 @@
// It supports calls to accumulate either time intervals (which are processed
// as integral number of milliseconds), or arbitrary integral units.
-// The default layout of buckets is exponential. For example, buckets might
+// For Histogram(exponential histogram), LinearHistogram and CustomHistogram,
+// the minimal range is 1 (instead of 0), maximal range is
jar (doing other things) 2012/08/01 00:26:10 nit: suggest "minimal range" --> "minimum for a de
kaiwang 2012/08/01 04:13:21 Done.
+// (HistogramBase::kSampleType_MAX - 1). Currently you can give ranges input
jar (doing other things) 2012/08/01 00:26:10 nit: suggest "can give ranges input..." --> "can
kaiwang 2012/08/01 04:13:21 Done.
+// exceeding this limit, e.g. 0 as minimal or HistogramBase::kSampleType_MAX as
+// maximal. They will be *silently* converted to correct input: 0 and
+// (HistogramBase::kSampleType_MAX - 1). But you should never depend on this!
jar (doing other things) 2012/08/01 00:26:10 nit: "But..." --> "Best practice is to not exceed
kaiwang 2012/08/01 04:13:21 Done.
+
+// For Histogram and LinearHistogram, maximal range should always be larger (not
jar (doing other things) 2012/08/01 00:26:10 nit: "maximal range" --> "maximum for a declared r
kaiwang 2012/08/01 04:13:21 Done.
+// equal) than minmal range. And 0 and HistogramBase::kSampleType_MAX are always
jar (doing other things) 2012/08/01 00:26:10 nit: "And 0" --> "Zero" "are always added" --> "a
kaiwang 2012/08/01 04:13:21 Done.
+// added as first and last ranges, so the minimal bucket count is 3. However
jar (doing other things) 2012/08/01 00:26:10 nit: "minimal bucket count" --> "smallest legal bu
kaiwang 2012/08/01 04:13:21 Done.
+// CustomHistogram can have minimum bucket count as 2 (when you give a custom
+// ranges vector containing only 1 range).
+// For these 3 kind histograms, the max bucket count is always
jar (doing other things) 2012/08/01 00:26:10 "kind" --> "kinds of"
kaiwang 2012/08/01 04:13:21 Done.
+// (Histogram::kBucketCount_MAX - 1).
+
+// The buckets layout of Histogram is exponential. For example, buckets might
jar (doing other things) 2012/08/01 00:26:10 "Histogram" --> "class Histogram"
kaiwang 2012/08/01 04:13:21 Done.
// contain (sequentially) the count of values in the following intervals:
// [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity)
// That bucket allocation would actually result from construction of a histogram
// for values between 1 and 64, with 8 buckets, such as:
-// Histogram count(L"some name", 1, 64, 8);
+// Histogram count("some name", 1, 64, 8);
// Note that the underflow bucket [0,1) and the overflow bucket [64,infinity)
-// are not counted by the constructor in the user supplied "bucket_count"
+// are also counted by the constructor in the user supplied "bucket_count"
// argument.
// The above example has an exponential ratio of 2 (doubling the bucket width
// in each consecutive bucket. The Histogram class automatically calculates
@@ -28,8 +43,9 @@
// at the low end of the histogram scale, but allows the histogram to cover a
// gigantic range with the addition of very few buckets.
-// Histograms use a pattern involving a function static variable, that is a
-// pointer to a histogram. This static is explicitly initialized on any thread
+// Usually we use macros to define and use a histogram. These macros use a
+// pattern involving a function static variable, that is a pointer to a
+// histogram. This static is explicitly initialized on any thread
// that detects a uninitialized (NULL) pointer. The potentially racy
// initialization is not a problem as it is always set to point to the same
// value (i.e., the FactoryGet always returns the same value). FactoryGet
@@ -177,9 +193,10 @@
boundary_value + 1, base::Histogram::kNoFlags))
// Support histograming of an enumerated value. Samples should be one of the
-// std::vector<int> list provided via |custom_ranges|. You can use the helper
-// function |base::CustomHistogram::ArrayToCustomRanges(samples, num_samples)|
-// to transform a C-style array of valid sample values to a std::vector<int>.
+// std::vector<int> list provided via |custom_ranges|. See comments above
+// CustomRanges::FactoryGet about the requirement of |custom_ranges|.
+// You can use the helper function CustomHistogram::ArrayToCustomRanges to
+// transform a C-style array of valid sample values to a std::vector<int>.
#define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \
STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \
base::CustomHistogram::FactoryGet(name, custom_ranges, \
@@ -338,13 +355,13 @@
LINEAR_HISTOGRAM,
BOOLEAN_HISTOGRAM,
CUSTOM_HISTOGRAM,
- NOT_VALID_IN_RENDERER
+ NOT_VALID_IN_RENDERER,
};
enum BucketLayout {
EXPONENTIAL,
LINEAR,
- CUSTOM
+ CUSTOM,
};
enum Flags {
@@ -381,17 +398,17 @@
class BASE_EXPORT SampleSet {
public:
- explicit SampleSet();
+ explicit SampleSet(size_t size);
+ SampleSet();
~SampleSet();
- // Adjust size of counts_ for use with given histogram.
- void Resize(const Histogram& histogram);
- void CheckSize(const Histogram& histogram) const;
+ void Resize(size_t size);
// Accessor for histogram to make routine additions.
void Accumulate(Sample value, Count count, size_t index);
// Accessor methods.
+ size_t size() const { return counts_.size(); }
Count counts(size_t i) const { return counts_[i]; }
Count TotalCount() const;
int64 sum() const { return sum_; }
@@ -447,10 +464,32 @@
base::TimeDelta maximum,
size_t bucket_count,
Flags flags);
+
// Time call for use with DHISTOGRAM*.
// Returns TimeTicks::Now() in debug and TimeTicks() in release build.
static TimeTicks DebugNow();
+ // Convenience methods for serializing/deserializing the histograms.
+ // Histograms from Renderer process are serialized and sent to the browser.
+ // Browser process reconstructs the histogram from the pickled version
+ // accumulates the browser-side shadow copy of histograms (that mirror
+ // histograms created in the renderer).
+
+ // Serialize the given snapshot of a Histogram into a String. Uses
+ // Pickle class to flatten the object.
+ static std::string SerializeHistogramInfo(const Histogram& histogram,
jar (doing other things) 2012/08/01 00:26:10 note that grouping by "static" is not in style gui
kaiwang 2012/08/01 04:13:21 Done.
+ const SampleSet& snapshot);
+
+ // The following method accepts a list of pickled histograms and
+ // builds a histogram and updates shadow copy of histogram data in the
+ // browser process.
+ static bool DeserializeHistogramInfo(const std::string& histogram_info);
+
+ static void InitializeBucketRanges(Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ BucketRanges* ranges);
+
virtual void Add(Sample value) OVERRIDE;
// This method is an interface, used only by BooleanHistogram.
@@ -477,22 +516,6 @@
void ClearFlags(Flags flags) { flags_ = static_cast<Flags>(flags_ & ~flags); }
int flags() const { return flags_; }
- // Convenience methods for serializing/deserializing the histograms.
- // Histograms from Renderer process are serialized and sent to the browser.
- // Browser process reconstructs the histogram from the pickled version
- // accumulates the browser-side shadow copy of histograms (that mirror
- // histograms created in the renderer).
-
- // Serialize the given snapshot of a Histogram into a String. Uses
- // Pickle class to flatten the object.
- static std::string SerializeHistogramInfo(const Histogram& histogram,
- const SampleSet& snapshot);
-
- // The following method accepts a list of pickled histograms and
- // builds a histogram and updates shadow copy of histogram data in the
- // browser process.
- static bool DeserializeHistogramInfo(const std::string& histogram_info);
-
// Check to see if bucket ranges, counts and tallies in the snapshot are
// consistent with the bucket ranges and checksums in our histogram. This can
// produce a false-alarm if a race occurred in the reading of the data during
@@ -507,33 +530,35 @@
Sample declared_min() const { return declared_min_; }
Sample declared_max() const { return declared_max_; }
virtual Sample ranges(size_t i) const;
- uint32 range_checksum() const { return range_checksum_; }
virtual size_t bucket_count() const;
- BucketRanges* bucket_ranges() const { return bucket_ranges_; }
- void set_bucket_ranges(BucketRanges* bucket_ranges) {
- bucket_ranges_ = bucket_ranges;
- }
+ const BucketRanges* bucket_ranges() const { return bucket_ranges_; }
+
// Snapshot the current complete set of sample data.
// Override with atomic/locked snapshot if needed.
virtual void SnapshotSample(SampleSet* sample) const;
- virtual bool HasConstructorArguments(Sample minimum, Sample maximum,
- size_t bucket_count);
+ virtual bool HasConstructionArguments(Sample minimum,
+ Sample maximum,
+ size_t bucket_count);
+ virtual ~Histogram();
jar (doing other things) 2012/08/01 00:26:10 nit: move to near top of public section. Perhaps
kaiwang 2012/08/01 04:13:21 Done.
- virtual bool HasConstructorTimeDeltaArguments(TimeDelta minimum,
- TimeDelta maximum,
- size_t bucket_count);
- // Return true iff the range_checksum_ matches current |ranges_| vector in
- // |bucket_ranges_|.
- bool HasValidRangeChecksum() const;
-
protected:
- Histogram(const std::string& name, Sample minimum,
- Sample maximum, size_t bucket_count);
- Histogram(const std::string& name, TimeDelta minimum,
- TimeDelta maximum, size_t bucket_count);
+ // This function validates histogram construction arguments. It returns false
+ // if some of the arguments are totally bad.
+ // Note. Currently it allow some bad input, e.g. 0 as minimum, but silently
+ // converts it to good input: 1.
+ // TODO(kaiwang): Be more restrict and return false for any bad input, and
+ // make this a readonly validating function.
+ static bool InspectConstructionArguments(const std::string& name,
+ Sample* minimum,
+ Sample* maximum,
+ size_t* bucket_count);
- virtual ~Histogram();
+ Histogram(const std::string& name,
jar (doing other things) 2012/08/01 00:26:10 nit: push to top of section.
kaiwang 2012/08/01 04:13:21 Done.
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ const BucketRanges* ranges);
// Serialize the histogram's ranges to |*pickle|, returning true on success.
// Most subclasses can leave this no-op implementation, but some will want to
@@ -541,9 +566,6 @@
// serialized parameters.
virtual bool SerializeRanges(Pickle* pickle) const;
- // Initialize ranges_ mapping in bucket_ranges_.
- void InitializeBucketRange();
-
// Method to override to skip the display of the i'th bucket if it's empty.
virtual bool PrintEmptyBucket(size_t index) const;
@@ -555,9 +577,6 @@
// Get normalized size, relative to the ranges(i).
virtual double GetBucketSize(Count current, size_t i) const;
- // Recalculate range_checksum_.
- void ResetRangeChecksum();
-
// Return a string description of what goes in a given bucket.
// Most commonly this is the numeric value, but in derived classes it may
// be a name (or string description) given to the bucket.
@@ -569,18 +588,6 @@
// Update all our internal data, including histogram
virtual void Accumulate(Sample value, Count count, size_t index);
- //----------------------------------------------------------------------------
- // Accessors for derived classes.
- //----------------------------------------------------------------------------
- void SetBucketRange(size_t i, Sample value);
-
- // Validate that ranges_ in bucket_ranges_ was created sensibly (top and
- // bottom range values relate properly to the declared_min_ and
- // declared_max_).
- bool ValidateBucketRanges() const;
-
- virtual uint32 CalculateRangeChecksum() const;
-
private:
// Allow tests to corrupt our innards for testing purposes.
FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds);
@@ -590,12 +597,6 @@
friend class StatisticsRecorder; // To allow it to delete duplicates.
- // Post constructor initialization.
- void Initialize();
-
- // Checksum function for accumulating range values into a checksum.
- static uint32 Crc32(uint32 sum, Sample range);
-
//----------------------------------------------------------------------------
// Helpers for emitting Ascii graphic. Each method appends data to output.
@@ -625,11 +626,8 @@
void WriteAsciiBucketGraph(double current_size, double max_size,
std::string* output) const;
- //----------------------------------------------------------------------------
- // Table for generating Crc32 values.
- static const uint32 kCrcTable[256];
- //----------------------------------------------------------------------------
- // Invariant values set at/near construction time
+ // Does not own this object. Should get from StatisticsRecorder.
+ const BucketRanges* bucket_ranges_;
Sample declared_min_; // Less than this goes into counts_[0]
Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1].
@@ -638,17 +636,6 @@
// Flag the histogram for recording by UMA via metric_services.h.
Flags flags_;
- // For each index, show the least value that can be stored in the
- // corresponding bucket. We also append one extra element in this array,
- // containing kSampleType_MAX, to make calculations easy.
- // The dimension of ranges_ in bucket_ranges_ is bucket_count + 1.
jar (doing other things) 2012/08/01 00:26:10 nit: Preserve this comment, since we don't explain
kaiwang 2012/08/01 04:13:21 Done. Simplified the comments and added to Histogr
- BucketRanges* bucket_ranges_;
-
- // For redundancy, we store a checksum of all the sample ranges when ranges
- // are generated. If ever there is ever a difference, then the histogram must
- // have been corrupted.
- uint32 range_checksum_;
-
// Finally, provide the state that changes with the addition of each new
// sample.
SampleSet sample_;
@@ -677,6 +664,11 @@
size_t bucket_count,
Flags flags);
+ static void InitializeBucketRanges(Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ BucketRanges* ranges);
+
// Overridden from Histogram:
virtual ClassType histogram_type() const OVERRIDE;
@@ -686,14 +678,12 @@
const DescriptionPair descriptions[]) OVERRIDE;
protected:
- LinearHistogram(const std::string& name, Sample minimum,
- Sample maximum, size_t bucket_count);
+ LinearHistogram(const std::string& name,
+ Sample minimum,
+ Sample maximum,
+ size_t bucket_count,
+ const BucketRanges* ranges);
- LinearHistogram(const std::string& name, TimeDelta minimum,
- TimeDelta maximum, size_t bucket_count);
-
- // Initialize ranges_ mapping in bucket_ranges_.
- void InitializeBucketRange();
virtual double GetBucketSize(Count current, size_t i) const OVERRIDE;
// If we have a description for a bucket, then return that. Otherwise
@@ -726,7 +716,7 @@
virtual void AddBoolean(bool value) OVERRIDE;
private:
- explicit BooleanHistogram(const std::string& name);
+ BooleanHistogram(const std::string& name, const BucketRanges* ranges);
DISALLOW_COPY_AND_ASSIGN(BooleanHistogram);
};
@@ -736,7 +726,10 @@
// CustomHistogram is a histogram for a set of custom integers.
class BASE_EXPORT CustomHistogram : public Histogram {
public:
-
+ // |custom_ranges| contains a set of ranges. Each of them should be > 0 and
jar (doing other things) 2012/08/01 00:26:10 nit: "a set of ranges" --> "a vector of limits on
kaiwang 2012/08/01 04:13:21 Done.
+ // < kSampleType_MAX. (Currently 0 is still accepted for backward
+ // compatibility). The ranges can be unordered or contain duplication, but
jar (doing other things) 2012/08/01 00:26:10 nit: "ranges" --> "limits"
kaiwang 2012/08/01 04:13:21 Done.
+ // client should not depend on this.
static Histogram* FactoryGet(const std::string& name,
const std::vector<Sample>& custom_ranges,
Flags flags);
@@ -755,19 +748,22 @@
// Helper for deserializing CustomHistograms. |*ranges| should already be
// correctly sized before this call. Return true on success.
static bool DeserializeRanges(PickleIterator* iter,
- std::vector<Histogram::Sample>* ranges);
+ std::vector<Sample>* ranges);
protected:
CustomHistogram(const std::string& name,
- const std::vector<Sample>& custom_ranges);
+ const BucketRanges* ranges);
virtual bool SerializeRanges(Pickle* pickle) const OVERRIDE;
- // Initialize ranges_ mapping in bucket_ranges_.
- void InitializedCustomBucketRange(const std::vector<Sample>& custom_ranges);
virtual double GetBucketSize(Count current, size_t i) const OVERRIDE;
+ private:
+ static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges);
+ static BucketRanges* CreateBucketRangesFromCustomRanges(
+ const std::vector<Sample>& custom_ranges);
+
DISALLOW_COPY_AND_ASSIGN(CustomHistogram);
};

Powered by Google App Engine
This is Rietveld 408576698