// 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); virtual bool Done() const OVERRIDE; virtual void Next() OVERRIDE; virtual 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(); 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; redundant_count_ += redundant_count; SampleCountPickleIterator pickle_iter(iter); return AddSubtractImpl(&pickle_iter, ADD); } void HistogramSamples::Subtract(const HistogramSamples& other) { sum_ -= other.sum(); 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(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) { base::subtle::NoBarrier_Store(&redundant_count_, base::subtle::NoBarrier_Load(&redundant_count_) + diff); } SampleCountIterator::~SampleCountIterator() {} bool SampleCountIterator::GetBucketIndex(size_t* index) const { DCHECK(!Done()); return false; } } // namespace base