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
10namespace base {
11
12namespace {
13
14class 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
32SampleCountPickleIterator::SampleCountPickleIterator(PickleIterator* iter)
33    : iter_(iter),
34      is_done_(false) {
35  Next();
36}
37
38bool SampleCountPickleIterator::Done() const {
39  return is_done_;
40}
41
42void SampleCountPickleIterator::Next() {
43  DCHECK(!Done());
44  if (!iter_->ReadInt(&min_) ||
45      !iter_->ReadInt(&max_) ||
46      !iter_->ReadInt(&count_))
47    is_done_ = true;
48}
49
50void 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
61HistogramSamples::HistogramSamples() : sum_(0), redundant_count_(0) {}
62
63HistogramSamples::~HistogramSamples() {}
64
65void HistogramSamples::Add(const HistogramSamples& other) {
66  sum_ += other.sum();
67  redundant_count_ += other.redundant_count();
68  bool success = AddSubtractImpl(other.Iterator().get(), ADD);
69  DCHECK(success);
70}
71
72bool HistogramSamples::AddFromPickle(PickleIterator* iter) {
73  int64 sum;
74  HistogramBase::Count redundant_count;
75
76  if (!iter->ReadInt64(&sum) || !iter->ReadInt(&redundant_count))
77    return false;
78  sum_ += sum;
79  redundant_count_ += redundant_count;
80
81  SampleCountPickleIterator pickle_iter(iter);
82  return AddSubtractImpl(&pickle_iter, ADD);
83}
84
85void HistogramSamples::Subtract(const HistogramSamples& other) {
86  sum_ -= other.sum();
87  redundant_count_ -= other.redundant_count();
88  bool success = AddSubtractImpl(other.Iterator().get(), SUBTRACT);
89  DCHECK(success);
90}
91
92bool HistogramSamples::Serialize(Pickle* pickle) const {
93  if (!pickle->WriteInt64(sum_) || !pickle->WriteInt(redundant_count_))
94    return false;
95
96  HistogramBase::Sample min;
97  HistogramBase::Sample max;
98  HistogramBase::Count count;
99  for (scoped_ptr<SampleCountIterator> it = Iterator();
100       !it->Done();
101       it->Next()) {
102    it->Get(&min, &max, &count);
103    if (!pickle->WriteInt(min) ||
104        !pickle->WriteInt(max) ||
105        !pickle->WriteInt(count))
106      return false;
107  }
108  return true;
109}
110
111void HistogramSamples::IncreaseSum(int64 diff) {
112  sum_ += diff;
113}
114
115void HistogramSamples::IncreaseRedundantCount(HistogramBase::Count diff) {
116  base::subtle::NoBarrier_Store(&redundant_count_,
117      base::subtle::NoBarrier_Load(&redundant_count_) + diff);
118}
119
120SampleCountIterator::~SampleCountIterator() {}
121
122bool SampleCountIterator::GetBucketIndex(size_t* index) const {
123  DCHECK(!Done());
124  return false;
125}
126
127}  // namespace base
128