1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/metrics/sample_map.h" 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/logging.h" 894ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez#include "base/memory/ptr_util.h" 945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko#include "base/stl_util.h" 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattypedef HistogramBase::Count Count; 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattypedef HistogramBase::Sample Sample; 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkonamespace { 1745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 1845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// An iterator for going through a SampleMap. The logic here is identical 1945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// to that of PersistentSampleMapIterator but with different data structures. 2045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko// Changes here likely need to be duplicated there. 2145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoclass SampleMapIterator : public SampleCountIterator { 2245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko public: 2345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko typedef std::map<HistogramBase::Sample, HistogramBase::Count> 2445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko SampleToCountMap; 2545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 2645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko explicit SampleMapIterator(const SampleToCountMap& sample_counts); 2745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ~SampleMapIterator() override; 2845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 2945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // SampleCountIterator: 3045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko bool Done() const override; 3145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko void Next() override; 3245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko void Get(HistogramBase::Sample* min, 3345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko HistogramBase::Sample* max, 3445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko HistogramBase::Count* count) const override; 3545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 3645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko private: 3745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko void SkipEmptyBuckets(); 3845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 3945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko SampleToCountMap::const_iterator iter_; 4045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const SampleToCountMap::const_iterator end_; 4145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko}; 4245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 4345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoSampleMapIterator::SampleMapIterator(const SampleToCountMap& sample_counts) 4445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko : iter_(sample_counts.begin()), 4545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko end_(sample_counts.end()) { 4645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko SkipEmptyBuckets(); 4745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 4845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 4945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex VakulenkoSampleMapIterator::~SampleMapIterator() {} 5045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 5145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkobool SampleMapIterator::Done() const { 5245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko return iter_ == end_; 5345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 5445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 5545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid SampleMapIterator::Next() { 5645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko DCHECK(!Done()); 5745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ++iter_; 5845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko SkipEmptyBuckets(); 5945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 6045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 6145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid SampleMapIterator::Get(Sample* min, Sample* max, Count* count) const { 6245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko DCHECK(!Done()); 6345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko if (min) 6445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko *min = iter_->first; 6545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko if (max) 6645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko *max = iter_->first + 1; 6745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko if (count) 6845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko *count = iter_->second; 6945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 7045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 7145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkovoid SampleMapIterator::SkipEmptyBuckets() { 7245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko while (!Done() && iter_->second == 0) { 7345779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ++iter_; 7445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko } 7545779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} 7645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 7745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko} // namespace 7845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 790d205d712abd16eeed2f5d5b1052a367d23a223fAlex VakulenkoSampleMap::SampleMap() : SampleMap(0) {} 800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 810d205d712abd16eeed2f5d5b1052a367d23a223fAlex VakulenkoSampleMap::SampleMap(uint64_t id) : HistogramSamples(id) {} 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratSampleMap::~SampleMap() {} 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratvoid SampleMap::Accumulate(Sample value, Count count) { 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat sample_counts_[value] += count; 8745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko IncreaseSum(static_cast<int64_t>(count) * value); 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat IncreaseRedundantCount(count); 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratCount SampleMap::GetCount(Sample value) const { 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat std::map<Sample, Count>::const_iterator it = sample_counts_.find(value); 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (it == sample_counts_.end()) 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return 0; 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return it->second; 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratCount SampleMap::TotalCount() const { 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Count count = 0; 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat for (const auto& entry : sample_counts_) { 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat count += entry.second; 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return count; 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 10694ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavezstd::unique_ptr<SampleCountIterator> SampleMap::Iterator() const { 10794ffa55491333f3dcc701befd0d2652922916d99Luis Hector Chavez return WrapUnique(new SampleMapIterator(sample_counts_)); 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 11045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkobool SampleMap::AddSubtractImpl(SampleCountIterator* iter, Operator op) { 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Sample min; 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Sample max; 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Count count; 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat for (; !iter->Done(); iter->Next()) { 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat iter->Get(&min, &max, &count); 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (min + 1 != max) 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return false; // SparseHistogram only supports bucket with size 1. 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat sample_counts_[min] += (op == HistogramSamples::ADD) ? count : -count; 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return true; 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 125