diff options
author | kaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-09 05:14:15 +0000 |
---|---|---|
committer | kaiwang@chromium.org <kaiwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-09 05:14:15 +0000 |
commit | 7c7a4275f74bda63046b613686471fc2b8f14ac8 (patch) | |
tree | d22de02d2ca409683ceb313a9aac41fd9c564a33 /base/metrics | |
parent | 5bdebd9ecaaaada3e1632efa27ed986be2cd61a9 (diff) | |
download | chromium_src-7c7a4275f74bda63046b613686471fc2b8f14ac8.zip chromium_src-7c7a4275f74bda63046b613686471fc2b8f14ac8.tar.gz chromium_src-7c7a4275f74bda63046b613686471fc2b8f14ac8.tar.bz2 |
Skeleton code of SparseHistogram
Review URL: https://chromiumcodereview.appspot.com/10830156
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150736 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/metrics')
-rw-r--r-- | base/metrics/histogram.cc | 19 | ||||
-rw-r--r-- | base/metrics/histogram.h | 47 | ||||
-rw-r--r-- | base/metrics/histogram_base.cc | 13 | ||||
-rw-r--r-- | base/metrics/histogram_base.h | 26 | ||||
-rw-r--r-- | base/metrics/sparse_histogram.cc | 45 | ||||
-rw-r--r-- | base/metrics/sparse_histogram.h | 50 | ||||
-rw-r--r-- | base/metrics/sparse_histogram_unittest.cc | 40 |
7 files changed, 193 insertions, 47 deletions
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc index cea6d0c..ca2e4d9 100644 --- a/base/metrics/histogram.cc +++ b/base/metrics/histogram.cc @@ -133,7 +133,7 @@ Histogram* Histogram::FactoryGet(const string& name, Sample minimum, Sample maximum, size_t bucket_count, - Flags flags) { + int32 flags) { bool valid_arguments = InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); DCHECK(valid_arguments); @@ -162,7 +162,7 @@ Histogram* Histogram::FactoryTimeGet(const string& name, TimeDelta minimum, TimeDelta maximum, size_t bucket_count, - Flags flags) { + int32 flags) { return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), bucket_count, flags); } @@ -442,7 +442,6 @@ Histogram::Histogram(const string& name, declared_min_(minimum), declared_max_(maximum), bucket_count_(bucket_count), - flags_(kNoFlags), sample_(bucket_count) {} Histogram::~Histogram() { @@ -531,7 +530,7 @@ double Histogram::GetBucketSize(Count current, size_t i) const { const string Histogram::GetAsciiBucketRange(size_t i) const { string result; - if (kHexRangePrintingFlag & flags_) + if (kHexRangePrintingFlag & flags()) StringAppendF(&result, "%#x", ranges(i)); else StringAppendF(&result, "%d", ranges(i)); @@ -636,8 +635,8 @@ void Histogram::WriteAsciiHeader(const SampleSet& snapshot, StringAppendF(output, ", average = %.1f", average); } - if (flags_ & ~kHexRangePrintingFlag) - StringAppendF(output, " (flags = 0x%x)", flags_ & ~kHexRangePrintingFlag); + if (flags() & ~kHexRangePrintingFlag) + StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag); } void Histogram::WriteAsciiBucketContext(const int64 past, @@ -685,7 +684,7 @@ Histogram* LinearHistogram::FactoryGet(const string& name, Sample minimum, Sample maximum, size_t bucket_count, - Flags flags) { + int32 flags) { bool valid_arguments = Histogram::InspectConstructionArguments( name, &minimum, &maximum, &bucket_count); DCHECK(valid_arguments); @@ -715,7 +714,7 @@ Histogram* LinearHistogram::FactoryTimeGet(const string& name, TimeDelta minimum, TimeDelta maximum, size_t bucket_count, - Flags flags) { + int32 flags) { return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), bucket_count, flags); } @@ -781,7 +780,7 @@ void LinearHistogram::InitializeBucketRanges(Sample minimum, // This section provides implementation for BooleanHistogram. //------------------------------------------------------------------------------ -Histogram* BooleanHistogram::FactoryGet(const string& name, Flags flags) { +Histogram* BooleanHistogram::FactoryGet(const string& name, int32 flags) { Histogram* histogram = StatisticsRecorder::FindHistogram(name); if (!histogram) { // To avoid racy destruction at shutdown, the following will be leaked. @@ -819,7 +818,7 @@ BooleanHistogram::BooleanHistogram(const string& name, Histogram* CustomHistogram::FactoryGet(const string& name, const vector<Sample>& custom_ranges, - Flags flags) { + int32 flags) { CHECK(ValidateCustomRanges(custom_ranges)); Histogram* histogram = StatisticsRecorder::FindHistogram(name); diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h index a969dcfa..6320db6 100644 --- a/base/metrics/histogram.h +++ b/base/metrics/histogram.h @@ -64,6 +64,7 @@ #include "base/atomicops.h" #include "base/base_export.h" +#include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/logging.h" @@ -108,7 +109,7 @@ class Lock; // histogram. FactoryGet includes locks on a global histogram name map // and is completely thread safe. histogram_pointer = base::Histogram::FactoryGet( - name, min, max, bucket_count, base::Histogram::kNoFlags); + name, min, max, bucket_count, base::HistogramBase::kNoFlags); // Use Release_Store to ensure that the histogram data is made available // globally before we make the pointer visible. @@ -171,7 +172,7 @@ class Lock; #define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \ STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ base::Histogram::FactoryGet(name, min, max, bucket_count, \ - base::Histogram::kNoFlags)) + base::HistogramBase::kNoFlags)) #define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \ HISTOGRAM_ENUMERATION(name, under_one_hundred, 101) @@ -181,7 +182,7 @@ class Lock; #define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \ STATIC_HISTOGRAM_POINTER_BLOCK(name, AddTime(sample), \ base::Histogram::FactoryTimeGet(name, min, max, bucket_count, \ - base::Histogram::kNoFlags)) + base::HistogramBase::kNoFlags)) // Support histograming of an enumerated value. The samples should always be // strictly less than |boundary_value| -- this prevents you from running into @@ -192,7 +193,7 @@ class Lock; #define HISTOGRAM_ENUMERATION(name, sample, boundary_value) \ STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ base::LinearHistogram::FactoryGet(name, 1, boundary_value, \ - boundary_value + 1, base::Histogram::kNoFlags)) + boundary_value + 1, base::HistogramBase::kNoFlags)) // Support histograming of an enumerated value. Samples should be one of the // std::vector<int> list provided via |custom_ranges|. See comments above @@ -202,7 +203,7 @@ class Lock; #define HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges) \ STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample), \ base::CustomHistogram::FactoryGet(name, custom_ranges, \ - base::Histogram::kNoFlags)) + base::HistogramBase::kNoFlags)) //------------------------------------------------------------------------------ // Define Debug vs non-debug flavors of macros. @@ -366,20 +367,6 @@ class BASE_EXPORT Histogram : public HistogramBase { CUSTOM, }; - enum Flags { - kNoFlags = 0, - kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded. - - // Indicate that the histogram was pickled to be sent across an IPC Channel. - // If we observe this flag on a histogram being aggregated into after IPC, - // then we are running in a single process mode, and the aggregation should - // not take place (as we would be aggregating back into the source - // histogram!). - kIPCSerializationSourceFlag = 0x10, - - kHexRangePrintingFlag = 0x8000, // Fancy bucket-naming supported. - }; - enum Inconsistencies { NO_INCONSISTENCIES = 0x0, RANGE_CHECKSUM_ERROR = 0x1, @@ -460,12 +447,12 @@ class BASE_EXPORT Histogram : public HistogramBase { Sample minimum, Sample maximum, size_t bucket_count, - Flags flags); + int32 flags); static Histogram* FactoryTimeGet(const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count, - Flags flags); + int32 flags); // Time call for use with DHISTOGRAM*. // Returns TimeTicks::Now() in debug and TimeTicks() in release build. @@ -495,13 +482,6 @@ class BASE_EXPORT Histogram : public HistogramBase { virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; virtual void WriteAscii(std::string* output) const OVERRIDE; - // Support generic flagging of Histograms. - // 0x1 Currently used to mark this histogram to be recorded by UMA.. - // 0x8000 means print ranges in hex. - void SetFlags(Flags flags) { flags_ = static_cast<Flags> (flags_ | flags); } - 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 @@ -638,9 +618,6 @@ class BASE_EXPORT Histogram : public HistogramBase { Sample declared_max_; // Over this goes into counts_[bucket_count_ - 1]. size_t bucket_count_; // Dimension of counts_[]. - // Flag the histogram for recording by UMA via metric_services.h. - Flags flags_; - // Finally, provide the state that changes with the addition of each new // sample. SampleSet sample_; @@ -662,12 +639,12 @@ class BASE_EXPORT LinearHistogram : public Histogram { Sample minimum, Sample maximum, size_t bucket_count, - Flags flags); + int32 flags); static Histogram* FactoryTimeGet(const std::string& name, TimeDelta minimum, TimeDelta maximum, size_t bucket_count, - Flags flags); + int32 flags); static void InitializeBucketRanges(Sample minimum, Sample maximum, @@ -714,7 +691,7 @@ class BASE_EXPORT LinearHistogram : public Histogram { // BooleanHistogram is a histogram for booleans. class BASE_EXPORT BooleanHistogram : public LinearHistogram { public: - static Histogram* FactoryGet(const std::string& name, Flags flags); + static Histogram* FactoryGet(const std::string& name, int32 flags); virtual ClassType histogram_type() const OVERRIDE; @@ -737,7 +714,7 @@ class BASE_EXPORT CustomHistogram : public Histogram { // client should not depend on this. static Histogram* FactoryGet(const std::string& name, const std::vector<Sample>& custom_ranges, - Flags flags); + int32 flags); // Overridden from Histogram: virtual ClassType histogram_type() const OVERRIDE; diff --git a/base/metrics/histogram_base.cc b/base/metrics/histogram_base.cc index 42d793e..6032a35 100644 --- a/base/metrics/histogram_base.cc +++ b/base/metrics/histogram_base.cc @@ -4,13 +4,24 @@ #include "base/metrics/histogram_base.h" +#include <climits> + namespace base { const HistogramBase::Sample HistogramBase::kSampleType_MAX = INT_MAX; HistogramBase::HistogramBase(const std::string& name) - : histogram_name_(name) {} + : histogram_name_(name), + flags_(kNoFlags) {} HistogramBase::~HistogramBase() {} +void HistogramBase::SetFlags(int32 flags) { + flags_ |= flags; +} + +void HistogramBase::ClearFlags(int32 flags) { + flags_ &= ~flags; +} + } // namespace base diff --git a/base/metrics/histogram_base.h b/base/metrics/histogram_base.h index d8c2910..caa0a4c 100644 --- a/base/metrics/histogram_base.h +++ b/base/metrics/histogram_base.h @@ -5,10 +5,10 @@ #ifndef BASE_METRICS_HISTOGRAM_BASE_H_ #define BASE_METRICS_HISTOGRAM_BASE_H_ -#include <climits> #include <string> #include "base/base_export.h" +#include "base/basictypes.h" namespace base { @@ -19,11 +19,32 @@ class BASE_EXPORT HistogramBase { static const Sample kSampleType_MAX; // INT_MAX + enum Flags { + kNoFlags = 0, + kUmaTargetedHistogramFlag = 0x1, // Histogram should be UMA uploaded. + + // Indicate that the histogram was pickled to be sent across an IPC Channel. + // If we observe this flag on a histogram being aggregated into after IPC, + // then we are running in a single process mode, and the aggregation should + // not take place (as we would be aggregating back into the source + // histogram!). + kIPCSerializationSourceFlag = 0x10, + + // Only for Histogram and its sub classes: fancy bucket-naming support. + kHexRangePrintingFlag = 0x8000, + }; + + HistogramBase(const std::string& name); virtual ~HistogramBase(); std::string histogram_name() const { return histogram_name_; } + // Operations with Flags enum. + int32 flags() const { return flags_; } + void SetFlags(int32 flags); + void ClearFlags(int32 flags); + virtual void Add(Sample value) = 0; // The following methods provide graphical histogram displays. @@ -32,6 +53,9 @@ class BASE_EXPORT HistogramBase { private: const std::string histogram_name_; + int32 flags_; + + DISALLOW_COPY_AND_ASSIGN(HistogramBase); }; } // namespace base diff --git a/base/metrics/sparse_histogram.cc b/base/metrics/sparse_histogram.cc new file mode 100644 index 0000000..05a68b5 --- /dev/null +++ b/base/metrics/sparse_histogram.cc @@ -0,0 +1,45 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/metrics/sparse_histogram.h" + +#include "base/metrics/statistics_recorder.h" + +using std::string; + +namespace base { + +// static +HistogramBase* SparseHistogram::FactoryGet(const string& name, + int32 flags) { + // TODO(kaiwang): Register and get SparseHistogram with StatisticsRecorder. + HistogramBase* histogram = new SparseHistogram(name); + histogram->SetFlags(flags); + return histogram; +} + +SparseHistogram::~SparseHistogram() {} + +void SparseHistogram::Add(Sample value) { + base::AutoLock auto_lock(lock_); + samples_[value]++; +} + +void SparseHistogram::SnapshotSample(std::map<Sample, Count>* samples) const { + base::AutoLock auto_lock(lock_); + *samples = samples_; +} + +void SparseHistogram::WriteHTMLGraph(string* output) const { + // TODO(kaiwang): Implement. +} + +void SparseHistogram::WriteAscii(string* output) const { + // TODO(kaiwang): Implement. +} + +SparseHistogram::SparseHistogram(const string& name) + : HistogramBase(name) {} + +} // namespace base diff --git a/base/metrics/sparse_histogram.h b/base/metrics/sparse_histogram.h new file mode 100644 index 0000000..9ef435e --- /dev/null +++ b/base/metrics/sparse_histogram.h @@ -0,0 +1,50 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_METRICS_SPARSE_HISTOGRAM_H_ +#define BASE_METRICS_SPARSE_HISTOGRAM_H_ + +#include <map> +#include <string> + +#include "base/base_export.h" +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/metrics/histogram_base.h" +#include "base/synchronization/lock.h" + +namespace base { + +class BASE_EXPORT_PRIVATE SparseHistogram : public HistogramBase { + public: + // If there's one with same name, return the existing one. If not, create a + // new one. + static HistogramBase* FactoryGet(const std::string& name, int32 flags); + + virtual ~SparseHistogram(); + + virtual void Add(Sample value) OVERRIDE; + + virtual void SnapshotSample(std::map<Sample, Count>* sample) const; + virtual void WriteHTMLGraph(std::string* output) const OVERRIDE; + virtual void WriteAscii(std::string* output) const OVERRIDE; + + protected: + // Clients should always use FactoryGet to create SparseHistogram. + SparseHistogram(const std::string& name); + + private: + friend class SparseHistogramTest; // For constuctor calling. + + std::map<Sample, Count> samples_; + + // Protects access to above map. + mutable base::Lock lock_; + + DISALLOW_COPY_AND_ASSIGN(SparseHistogram); +}; + +} // namespace base + +#endif // BASE_METRICS_SPARSE_HISTOGRAM_H_ diff --git a/base/metrics/sparse_histogram_unittest.cc b/base/metrics/sparse_histogram_unittest.cc new file mode 100644 index 0000000..1ed0e71 --- /dev/null +++ b/base/metrics/sparse_histogram_unittest.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "base/metrics/sparse_histogram.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { + +class SparseHistogramTest : public testing::Test { + protected: + scoped_ptr<SparseHistogram> NewSparseHistogram(const std::string& name) { + return scoped_ptr<SparseHistogram>(new SparseHistogram(name)); + } +}; + +TEST_F(SparseHistogramTest, BasicTest) { + scoped_ptr<SparseHistogram> histogram(NewSparseHistogram("Sparse1")); + std::map<HistogramBase::Sample, HistogramBase::Count> sample; + histogram->SnapshotSample(&sample); + + ASSERT_EQ(0u, sample.size()); + + histogram->Add(100); + histogram->SnapshotSample(&sample); + ASSERT_EQ(1u, sample.size()); + EXPECT_EQ(1, sample[100]); + + histogram->Add(100); + histogram->Add(101); + histogram->SnapshotSample(&sample); + ASSERT_EQ(2u, sample.size()); + EXPECT_EQ(2, sample[100]); + EXPECT_EQ(1, sample[101]); +} + +} // namespace base |