15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/sample_map.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::map;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef HistogramBase::Count Count;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef HistogramBase::Sample Sample;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SampleMap::SampleMap() {}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SampleMap::~SampleMap() {}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SampleMap::Accumulate(Sample value, Count count) {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sample_counts_[value] += count;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IncreaseSum(count * value);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IncreaseRedundantCount(count);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Count SampleMap::GetCount(Sample value) const {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  map<Sample, Count>::const_iterator it = sample_counts_.find(value);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == sample_counts_.end())
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return it->second;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Count SampleMap::TotalCount() const {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Count count = 0;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (map<Sample, Count>::const_iterator it = sample_counts_.begin();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != sample_counts_.end();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++it) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    count += it->second;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return count;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<SampleCountIterator> SampleMap::Iterator() const {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return scoped_ptr<SampleCountIterator>(new SampleMapIterator(sample_counts_));
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SampleMap::AddSubtractImpl(SampleCountIterator* iter,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                HistogramSamples::Operator op) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Sample min;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Sample max;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Count count;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; !iter->Done(); iter->Next()) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iter->Get(&min, &max, &count);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (min + 1 != max)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;  // SparseHistogram only supports bucket with size 1.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sample_counts_[min] += (op ==  HistogramSamples::ADD) ? count : -count;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SampleMapIterator::SampleMapIterator(const SampleToCountMap& sample_counts)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : iter_(sample_counts.begin()),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      end_(sample_counts.end()) {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SampleMapIterator::~SampleMapIterator() {}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SampleMapIterator::Done() const {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return iter_ == end_;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SampleMapIterator::Next() {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!Done());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iter_++;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SampleMapIterator::Get(Sample* min, Sample* max, Count* count) const {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!Done());
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (min != NULL)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *min = iter_->first;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (max != NULL)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *max = iter_->first + 1;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (count != NULL)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *count = iter_->second;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
87