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 3 // found in the LICENSE file. 4 5 #ifndef BASE_METRICS_HISTOGRAM_SAMPLES_H_ 6 #define BASE_METRICS_HISTOGRAM_SAMPLES_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include "base/atomicops.h" 12 #include "base/macros.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "base/metrics/histogram_base.h" 15 16 namespace base { 17 18 class Pickle; 19 class PickleIterator; 20 class SampleCountIterator; 21 22 // HistogramSamples is a container storing all samples of a histogram. 23 class BASE_EXPORT HistogramSamples { 24 public: 25 struct Metadata { 26 // Initialized when the sample-set is first created with a value provided 27 // by the caller. It is generally used to identify the sample-set across 28 // threads and processes, though not necessarily uniquely as it is possible 29 // to have multiple sample-sets representing subsets of the data. 30 uint64_t id; 31 32 // The sum of all the entries, effectivly the sum(sample * count) for 33 // all samples. Despite being atomic, no guarantees are made on the 34 // accuracy of this value; there may be races during histogram 35 // accumulation and snapshotting that we choose to accept. It should 36 // be treated as approximate. 37 // TODO(bcwhite): Change this to std::atomic<int64_t>. 38 int64_t sum; 39 40 // A "redundant" count helps identify memory corruption. It redundantly 41 // stores the total number of samples accumulated in the histogram. We 42 // can compare this count to the sum of the counts (TotalCount() function), 43 // and detect problems. Note, depending on the implementation of different 44 // histogram types, there might be races during histogram accumulation 45 // and snapshotting that we choose to accept. In this case, the tallies 46 // might mismatch even when no memory corruption has happened. 47 HistogramBase::AtomicCount redundant_count; 48 MetadataMetadata49 Metadata() : id(0), sum(0), redundant_count(0) {} 50 }; 51 52 explicit HistogramSamples(uint64_t id); 53 HistogramSamples(uint64_t id, Metadata* meta); 54 virtual ~HistogramSamples(); 55 56 virtual void Accumulate(HistogramBase::Sample value, 57 HistogramBase::Count count) = 0; 58 virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0; 59 virtual HistogramBase::Count TotalCount() const = 0; 60 61 virtual void Add(const HistogramSamples& other); 62 63 // Add from serialized samples. 64 virtual bool AddFromPickle(PickleIterator* iter); 65 66 virtual void Subtract(const HistogramSamples& other); 67 68 virtual scoped_ptr<SampleCountIterator> Iterator() const = 0; 69 virtual bool Serialize(Pickle* pickle) const; 70 71 // Accessor fuctions. id()72 uint64_t id() const { return meta_->id; } sum()73 int64_t sum() const { return meta_->sum; } redundant_count()74 HistogramBase::Count redundant_count() const { 75 return subtle::NoBarrier_Load(&meta_->redundant_count); 76 } 77 78 protected: 79 // Based on |op| type, add or subtract sample counts data from the iterator. 80 enum Operator { ADD, SUBTRACT }; 81 virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0; 82 83 void IncreaseSum(int64_t diff); 84 void IncreaseRedundantCount(HistogramBase::Count diff); 85 86 private: 87 // In order to support histograms shared through an external memory segment, 88 // meta values may be the local storage or external storage depending on the 89 // wishes of the derived class. 90 Metadata local_meta_; 91 Metadata* meta_; 92 93 DISALLOW_COPY_AND_ASSIGN(HistogramSamples); 94 }; 95 96 class BASE_EXPORT SampleCountIterator { 97 public: 98 virtual ~SampleCountIterator(); 99 100 virtual bool Done() const = 0; 101 virtual void Next() = 0; 102 103 // Get the sample and count at current position. 104 // |min| |max| and |count| can be NULL if the value is not of interest. 105 // Requires: !Done(); 106 virtual void Get(HistogramBase::Sample* min, 107 HistogramBase::Sample* max, 108 HistogramBase::Count* count) const = 0; 109 110 // Get the index of current histogram bucket. 111 // For histograms that don't use predefined buckets, it returns false. 112 // Requires: !Done(); 113 virtual bool GetBucketIndex(size_t* index) const; 114 }; 115 116 } // namespace base 117 118 #endif // BASE_METRICS_HISTOGRAM_SAMPLES_H_ 119