blob: f5e03b979e110cbf297e27ab278225965141a1eb [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/metrics/histogram_samples.h"
#include "base/compiler_specific.h"
#include "base/pickle.h"
namespace base {
namespace {
class SampleCountPickleIterator : public SampleCountIterator {
public:
explicit SampleCountPickleIterator(PickleIterator* iter);
bool Done() const override;
void Next() override;
void Get(HistogramBase::Sample* min,
HistogramBase::Sample* max,
HistogramBase::Count* count) const override;
private:
PickleIterator* const iter_;
HistogramBase::Sample min_;
HistogramBase::Sample max_;
HistogramBase::Count count_;
bool is_done_;
};
SampleCountPickleIterator::SampleCountPickleIterator(PickleIterator* iter)
: iter_(iter),
is_done_(false) {
Next();
}
bool SampleCountPickleIterator::Done() const {
return is_done_;
}
void SampleCountPickleIterator::Next() {
DCHECK(!Done());
if (!iter_->ReadInt(&min_) ||
!iter_->ReadInt(&max_) ||
!iter_->ReadInt(&count_))
is_done_ = true;
}
void SampleCountPickleIterator::Get(HistogramBase::Sample* min,
HistogramBase::Sample* max,
HistogramBase::Count* count) const {
DCHECK(!Done());
*min = min_;
*max = max_;
*count = count_;
}
} // namespace
HistogramSamples::HistogramSamples() : sum_(0), redundant_count_(0) {}
HistogramSamples::~HistogramSamples() {}
void HistogramSamples::Add(const HistogramSamples& other) {
sum_ += other.sum();
HistogramBase::Count old_redundant_count =
subtle::NoBarrier_Load(&redundant_count_);
subtle::NoBarrier_Store(&redundant_count_,
old_redundant_count + other.redundant_count());
bool success = AddSubtractImpl(other.Iterator().get(), ADD);
DCHECK(success);
}
bool HistogramSamples::AddFromPickle(PickleIterator* iter) {
int64 sum;
HistogramBase::Count redundant_count;
if (!iter->ReadInt64(&sum) || !iter->ReadInt(&redundant_count))
return false;
sum_ += sum;
HistogramBase::Count old_redundant_count =
subtle::NoBarrier_Load(&redundant_count_);
subtle::NoBarrier_Store(&redundant_count_,
old_redundant_count + redundant_count);
SampleCountPickleIterator pickle_iter(iter);
return AddSubtractImpl(&pickle_iter, ADD);
}
void HistogramSamples::Subtract(const HistogramSamples& other) {
sum_ -= other.sum();
HistogramBase::Count old_redundant_count =
subtle::NoBarrier_Load(&redundant_count_);
subtle::NoBarrier_Store(&redundant_count_,
old_redundant_count - other.redundant_count());
bool success = AddSubtractImpl(other.Iterator().get(), SUBTRACT);
DCHECK(success);
}
bool HistogramSamples::Serialize(Pickle* pickle) const {
if (!pickle->WriteInt64(sum_) ||
!pickle->WriteInt(subtle::NoBarrier_Load(&redundant_count_)))
return false;
HistogramBase::Sample min;
HistogramBase::Sample max;
HistogramBase::Count count;
for (scoped_ptr<SampleCountIterator> it = Iterator();
!it->Done();
it->Next()) {
it->Get(&min, &max, &count);
if (!pickle->WriteInt(min) ||
!pickle->WriteInt(max) ||
!pickle->WriteInt(count))
return false;
}
return true;
}
void HistogramSamples::IncreaseSum(int64 diff) {
sum_ += diff;
}
void HistogramSamples::IncreaseRedundantCount(HistogramBase::Count diff) {
subtle::NoBarrier_Store(&redundant_count_,
subtle::NoBarrier_Load(&redundant_count_) + diff);
}
SampleCountIterator::~SampleCountIterator() {}
bool SampleCountIterator::GetBucketIndex(size_t* index) const {
DCHECK(!Done());
return false;
}
} // namespace base