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); |
}; |