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
SampleCountPickleIterator(PickleIterator * iter)32 SampleCountPickleIterator::SampleCountPickleIterator(PickleIterator* iter)
33 : iter_(iter),
34 is_done_(false) {
35 Next();
36 }
37
Done() const38 bool SampleCountPickleIterator::Done() const {
39 return is_done_;
40 }
41
Next()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
Get(HistogramBase::Sample * min,HistogramBase::Sample * max,HistogramBase::Count * count) const50 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
HistogramSamples()61 HistogramSamples::HistogramSamples() : sum_(0), redundant_count_(0) {}
62
~HistogramSamples()63 HistogramSamples::~HistogramSamples() {}
64
Add(const HistogramSamples & other)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
AddFromPickle(PickleIterator * iter)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
Subtract(const HistogramSamples & other)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
Serialize(Pickle * pickle) const101 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
IncreaseSum(int64 diff)121 void HistogramSamples::IncreaseSum(int64 diff) {
122 sum_ += diff;
123 }
124
IncreaseRedundantCount(HistogramBase::Count diff)125 void HistogramSamples::IncreaseRedundantCount(HistogramBase::Count diff) {
126 subtle::NoBarrier_Store(&redundant_count_,
127 subtle::NoBarrier_Load(&redundant_count_) + diff);
128 }
129
~SampleCountIterator()130 SampleCountIterator::~SampleCountIterator() {}
131
GetBucketIndex(size_t * index) const132 bool SampleCountIterator::GetBucketIndex(size_t* index) const {
133 DCHECK(!Done());
134 return false;
135 }
136
137 } // namespace base
138