• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SampleMapIterator(const SampleToCountMap & sample_counts)43 SampleMapIterator::SampleMapIterator(const SampleToCountMap& sample_counts)
44     : iter_(sample_counts.begin()),
45       end_(sample_counts.end()) {
46   SkipEmptyBuckets();
47 }
48 
~SampleMapIterator()49 SampleMapIterator::~SampleMapIterator() {}
50 
Done() const51 bool SampleMapIterator::Done() const {
52   return iter_ == end_;
53 }
54 
Next()55 void SampleMapIterator::Next() {
56   DCHECK(!Done());
57   ++iter_;
58   SkipEmptyBuckets();
59 }
60 
Get(Sample * min,Sample * max,Count * count) const61 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 
SkipEmptyBuckets()71 void SampleMapIterator::SkipEmptyBuckets() {
72   while (!Done() && iter_->second == 0) {
73     ++iter_;
74   }
75 }
76 
77 }  // namespace
78 
SampleMap()79 SampleMap::SampleMap() : SampleMap(0) {}
80 
SampleMap(uint64_t id)81 SampleMap::SampleMap(uint64_t id) : HistogramSamples(id) {}
82 
~SampleMap()83 SampleMap::~SampleMap() {}
84 
Accumulate(Sample value,Count count)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 
GetCount(Sample value) const91 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 
TotalCount() const98 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 
Iterator() const106 std::unique_ptr<SampleCountIterator> SampleMap::Iterator() const {
107   return WrapUnique(new SampleMapIterator(sample_counts_));
108 }
109 
AddSubtractImpl(SampleCountIterator * iter,Operator op)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