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 #include "base/metrics/histogram_samples.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/pickle.h"
      9 
     10 namespace base {
     11 
     12 namespace {
     13 
     14 class SampleCountPickleIterator : public SampleCountIterator {
     15  public:
     16   explicit SampleCountPickleIterator(PickleIterator* iter);
     17 
     18   virtual bool Done() const OVERRIDE;
     19   virtual void Next() OVERRIDE;
     20   virtual void Get(HistogramBase::Sample* min,
     21                    HistogramBase::Sample* max,
     22                    HistogramBase::Count* count) const OVERRIDE;
     23  private:
     24   PickleIterator* const iter_;
     25 
     26   HistogramBase::Sample min_;
     27   HistogramBase::Sample max_;
     28   HistogramBase::Count count_;
     29   bool is_done_;
     30 };
     31 
     32 SampleCountPickleIterator::SampleCountPickleIterator(PickleIterator* iter)
     33     : iter_(iter),
     34       is_done_(false) {
     35   Next();
     36 }
     37 
     38 bool SampleCountPickleIterator::Done() const {
     39   return is_done_;
     40 }
     41 
     42 void SampleCountPickleIterator::Next() {
     43   DCHECK(!Done());
     44   if (!iter_->ReadInt(&min_) ||
     45       !iter_->ReadInt(&max_) ||
     46       !iter_->ReadInt(&count_))
     47     is_done_ = true;
     48 }
     49 
     50 void SampleCountPickleIterator::Get(HistogramBase::Sample* min,
     51                                     HistogramBase::Sample* max,
     52                                     HistogramBase::Count* count) const {
     53   DCHECK(!Done());
     54   *min = min_;
     55   *max = max_;
     56   *count = count_;
     57 }
     58 
     59 }  // namespace
     60 
     61 HistogramSamples::HistogramSamples() : sum_(0), redundant_count_(0) {}
     62 
     63 HistogramSamples::~HistogramSamples() {}
     64 
     65 void HistogramSamples::Add(const HistogramSamples& other) {
     66   sum_ += other.sum();
     67   HistogramBase::Count old_redundant_count =
     68       subtle::NoBarrier_Load(&redundant_count_);
     69   subtle::NoBarrier_Store(&redundant_count_,
     70       old_redundant_count + other.redundant_count());
     71   bool success = AddSubtractImpl(other.Iterator().get(), ADD);
     72   DCHECK(success);
     73 }
     74 
     75 bool HistogramSamples::AddFromPickle(PickleIterator* iter) {
     76   int64 sum;
     77   HistogramBase::Count redundant_count;
     78 
     79   if (!iter->ReadInt64(&sum) || !iter->ReadInt(&redundant_count))
     80     return false;
     81   sum_ += sum;
     82   HistogramBase::Count old_redundant_count =
     83       subtle::NoBarrier_Load(&redundant_count_);
     84   subtle::NoBarrier_Store(&redundant_count_,
     85                           old_redundant_count + redundant_count);
     86 
     87   SampleCountPickleIterator pickle_iter(iter);
     88   return AddSubtractImpl(&pickle_iter, ADD);
     89 }
     90 
     91 void HistogramSamples::Subtract(const HistogramSamples& other) {
     92   sum_ -= other.sum();
     93   HistogramBase::Count old_redundant_count =
     94       subtle::NoBarrier_Load(&redundant_count_);
     95   subtle::NoBarrier_Store(&redundant_count_,
     96                           old_redundant_count - other.redundant_count());
     97   bool success = AddSubtractImpl(other.Iterator().get(), SUBTRACT);
     98   DCHECK(success);
     99 }
    100 
    101 bool HistogramSamples::Serialize(Pickle* pickle) const {
    102   if (!pickle->WriteInt64(sum_) ||
    103       !pickle->WriteInt(subtle::NoBarrier_Load(&redundant_count_)))
    104     return false;
    105 
    106   HistogramBase::Sample min;
    107   HistogramBase::Sample max;
    108   HistogramBase::Count count;
    109   for (scoped_ptr<SampleCountIterator> it = Iterator();
    110        !it->Done();
    111        it->Next()) {
    112     it->Get(&min, &max, &count);
    113     if (!pickle->WriteInt(min) ||
    114         !pickle->WriteInt(max) ||
    115         !pickle->WriteInt(count))
    116       return false;
    117   }
    118   return true;
    119 }
    120 
    121 void HistogramSamples::IncreaseSum(int64 diff) {
    122   sum_ += diff;
    123 }
    124 
    125 void HistogramSamples::IncreaseRedundantCount(HistogramBase::Count diff) {
    126   subtle::NoBarrier_Store(&redundant_count_,
    127       subtle::NoBarrier_Load(&redundant_count_) + diff);
    128 }
    129 
    130 SampleCountIterator::~SampleCountIterator() {}
    131 
    132 bool SampleCountIterator::GetBucketIndex(size_t* index) const {
    133   DCHECK(!Done());
    134   return false;
    135 }
    136 
    137 }  // namespace base
    138