Commit 7c7a4275 authored by kaiwang@chromium.org's avatar kaiwang@chromium.org

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
parent 5bdebd9e
......@@ -438,6 +438,7 @@
'metrics/bucket_ranges_unittest.cc',
'metrics/field_trial_unittest.cc',
'metrics/histogram_unittest.cc',
'metrics/sparse_histogram_unittest.cc',
'metrics/stats_table_unittest.cc',
'metrics/statistics_recorder_unittest.cc',
'observer_list_unittest.cc',
......
......@@ -257,6 +257,8 @@
'metrics/histogram_flattener.h',
'metrics/histogram_snapshot_manager.cc',
'metrics/histogram_snapshot_manager.h',
'metrics/sparse_histogram.cc',
'metrics/sparse_histogram.h',
'metrics/statistics_recorder.cc',
'metrics/statistics_recorder.h',
'metrics/stats_counters.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);
......
......@@ -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;
......
......@@ -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
......@@ -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
......
// 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
// 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_
// 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment