Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: base/metrics/sample_vector.cc

Issue 10829466: SampleSet -> HistogramSamples (will be reused by SparseHistogram) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/metrics/sample_vector.h ('k') | base/metrics/sample_vector_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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/sample_vector.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/bucket_ranges.h"
9
10 using std::vector;
11
12 namespace base {
13
14 typedef HistogramBase::Count Count;
15 typedef HistogramBase::Sample Sample;
16
17 SampleVector::SampleVector(const BucketRanges* bucket_ranges)
18 : counts_(bucket_ranges->size() - 1),
19 bucket_ranges_(bucket_ranges) {
20 CHECK_GE(bucket_ranges_->size(), 2u);
21 }
22
23 SampleVector::~SampleVector() {}
24
25 void SampleVector::Accumulate(Sample value, Count count) {
26 size_t bucket_index = GetBucketIndex(value);
27 counts_[bucket_index] += count;
28 IncreaseSum(count * value);
29 IncreaseRedundantCount(count);
30 }
31
32 Count SampleVector::GetCount(Sample value) const {
33 size_t bucket_index = GetBucketIndex(value);
34 return counts_[bucket_index];
35 }
36
37 Count SampleVector::TotalCount() const {
38 Count count = 0;
39 for (size_t i = 0; i < counts_.size(); i++) {
40 count += counts_[i];
41 }
42 return count;
43 }
44
45 Count SampleVector::GetCountAtIndex(size_t bucket_index) const {
46 DCHECK(bucket_index >= 0 && bucket_index < counts_.size());
47 return counts_[bucket_index];
48 }
49
50 scoped_ptr<SampleCountIterator> SampleVector::Iterator() const {
51 return scoped_ptr<SampleCountIterator>(
52 new SampleVectorIterator(&counts_, bucket_ranges_));
53 }
54
55 bool SampleVector::AddSubtractImpl(SampleCountIterator* iter,
56 HistogramSamples::Instruction instruction) {
57 HistogramBase::Sample min;
58 HistogramBase::Sample max;
59 HistogramBase::Count count;
60
61 // Go through the iterator and add the counts into correct bucket.
62 size_t index = 0;
63 while (index < counts_.size() && !iter->Done()) {
64 iter->Get(&min, &max, &count);
65 if (min == bucket_ranges_->range(index) &&
66 max == bucket_ranges_->range(index + 1)) {
67 // Sample matches this bucket!
68 counts_[index] +=
69 (instruction == HistogramSamples::ADD) ? count : -count;
70 iter->Next();
71 } else if (min > bucket_ranges_->range(index)) {
72 // Sample is larger than current bucket range. Try next.
73 index++;
74 } else {
75 // Sample is smaller than current bucket range. We scan buckets from
76 // smallest to largest, so the sample value must be invalid.
77 return false;
78 }
79 }
80
81 return iter->Done();
82 }
83
84 // Use simple binary search. This is very general, but there are better
85 // approaches if we knew that the buckets were linearly distributed.
86 size_t SampleVector::GetBucketIndex(Sample value) const {
87 size_t bucket_count = bucket_ranges_->size() - 1;
88 CHECK_GE(bucket_count, 1u);
89 CHECK_GE(value, bucket_ranges_->range(0));
90 CHECK_LT(value, bucket_ranges_->range(bucket_count));
91
92 size_t under = 0;
93 size_t over = bucket_count;
94 size_t mid;
95 do {
96 DCHECK_GE(over, under);
97 mid = under + (over - under)/2;
98 if (mid == under)
99 break;
100 if (bucket_ranges_->range(mid) <= value)
101 under = mid;
102 else
103 over = mid;
104 } while (true);
105
106 DCHECK_LE(bucket_ranges_->range(mid), value);
107 CHECK_GT(bucket_ranges_->range(mid + 1), value);
108 return mid;
109 }
110
111 SampleVectorIterator::SampleVectorIterator(const vector<Count>* counts,
112 const BucketRanges* bucket_ranges)
113 : counts_(counts),
114 bucket_ranges_(bucket_ranges),
115 index_(0) {
116 CHECK_GT(bucket_ranges_->size(), counts_->size());
117 SkipEmptyBuckets();
118 }
119
120 bool SampleVectorIterator::Done() const {
121 return index_ >= counts_->size();
122 }
123
124 void SampleVectorIterator::Next() {
125 DCHECK(!Done());
126 index_++;
127 SkipEmptyBuckets();
128 }
129
130 void SampleVectorIterator::Get(HistogramBase::Sample* min,
131 HistogramBase::Sample* max,
132 HistogramBase::Count* count) const {
133 DCHECK(!Done());
134 if (min != NULL)
135 *min = bucket_ranges_->range(index_);
136 if (max != NULL)
137 *max = bucket_ranges_->range(index_ + 1);
138 if (count != NULL)
139 *count = (*counts_)[index_];
140 }
141
142 bool SampleVectorIterator::GetBucketIndex(size_t* index) const {
143 DCHECK(!Done());
144 if (index != NULL)
145 *index = index_;
146 return true;
147 }
148
149 void SampleVectorIterator::SkipEmptyBuckets() {
150 if (Done())
151 return;
152
153 while (index_ < counts_->size()) {
154 if ((*counts_)[index_] != 0)
155 return;
156 index_++;
157 }
158 }
159
160 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/sample_vector.h ('k') | base/metrics/sample_vector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698