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