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/sample_map.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/memory/ptr_util.h"
      9 #include "base/stl_util.h"
     10 
     11 namespace base {
     12 
     13 typedef HistogramBase::Count Count;
     14 typedef HistogramBase::Sample Sample;
     15 
     16 namespace {
     17 
     18 // An iterator for going through a SampleMap. The logic here is identical
     19 // to that of PersistentSampleMapIterator but with different data structures.
     20 // Changes here likely need to be duplicated there.
     21 class SampleMapIterator : public SampleCountIterator {
     22  public:
     23   typedef std::map<HistogramBase::Sample, HistogramBase::Count>
     24       SampleToCountMap;
     25 
     26   explicit SampleMapIterator(const SampleToCountMap& sample_counts);
     27   ~SampleMapIterator() override;
     28 
     29   // SampleCountIterator:
     30   bool Done() const override;
     31   void Next() override;
     32   void Get(HistogramBase::Sample* min,
     33            HistogramBase::Sample* max,
     34            HistogramBase::Count* count) const override;
     35 
     36  private:
     37   void SkipEmptyBuckets();
     38 
     39   SampleToCountMap::const_iterator iter_;
     40   const SampleToCountMap::const_iterator end_;
     41 };
     42 
     43 SampleMapIterator::SampleMapIterator(const SampleToCountMap& sample_counts)
     44     : iter_(sample_counts.begin()),
     45       end_(sample_counts.end()) {
     46   SkipEmptyBuckets();
     47 }
     48 
     49 SampleMapIterator::~SampleMapIterator() {}
     50 
     51 bool SampleMapIterator::Done() const {
     52   return iter_ == end_;
     53 }
     54 
     55 void SampleMapIterator::Next() {
     56   DCHECK(!Done());
     57   ++iter_;
     58   SkipEmptyBuckets();
     59 }
     60 
     61 void SampleMapIterator::Get(Sample* min, Sample* max, Count* count) const {
     62   DCHECK(!Done());
     63   if (min)
     64     *min = iter_->first;
     65   if (max)
     66     *max = iter_->first + 1;
     67   if (count)
     68     *count = iter_->second;
     69 }
     70 
     71 void SampleMapIterator::SkipEmptyBuckets() {
     72   while (!Done() && iter_->second == 0) {
     73     ++iter_;
     74   }
     75 }
     76 
     77 }  // namespace
     78 
     79 SampleMap::SampleMap() : SampleMap(0) {}
     80 
     81 SampleMap::SampleMap(uint64_t id) : HistogramSamples(id) {}
     82 
     83 SampleMap::~SampleMap() {}
     84 
     85 void SampleMap::Accumulate(Sample value, Count count) {
     86   sample_counts_[value] += count;
     87   IncreaseSum(static_cast<int64_t>(count) * value);
     88   IncreaseRedundantCount(count);
     89 }
     90 
     91 Count SampleMap::GetCount(Sample value) const {
     92   std::map<Sample, Count>::const_iterator it = sample_counts_.find(value);
     93   if (it == sample_counts_.end())
     94     return 0;
     95   return it->second;
     96 }
     97 
     98 Count SampleMap::TotalCount() const {
     99   Count count = 0;
    100   for (const auto& entry : sample_counts_) {
    101     count += entry.second;
    102   }
    103   return count;
    104 }
    105 
    106 std::unique_ptr<SampleCountIterator> SampleMap::Iterator() const {
    107   return WrapUnique(new SampleMapIterator(sample_counts_));
    108 }
    109 
    110 bool SampleMap::AddSubtractImpl(SampleCountIterator* iter, Operator op) {
    111   Sample min;
    112   Sample max;
    113   Count count;
    114   for (; !iter->Done(); iter->Next()) {
    115     iter->Get(&min, &max, &count);
    116     if (min + 1 != max)
    117       return false;  // SparseHistogram only supports bucket with size 1.
    118 
    119     sample_counts_[min] += (op == HistogramSamples::ADD) ? count : -count;
    120   }
    121   return true;
    122 }
    123 
    124 }  // namespace base
    125