OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/metrics/sample_vector.h" | 5 #include "base/metrics/sample_vector.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/metrics/bucket_ranges.h" | 8 #include "base/metrics/bucket_ranges.h" |
9 | 9 |
10 namespace base { | 10 namespace base { |
11 | 11 |
12 typedef HistogramBase::Count Count; | 12 typedef HistogramBase::Count Count; |
13 typedef HistogramBase::Sample Sample; | 13 typedef HistogramBase::Sample Sample; |
14 | 14 |
15 SampleVector::SampleVector(const BucketRanges* bucket_ranges) | 15 SampleVector::SampleVector(const BucketRanges* bucket_ranges) |
16 : counts_(bucket_ranges->bucket_count()), | 16 : HistogramSamples(0), |
17 local_counts_(bucket_ranges->bucket_count()), | |
18 counts_(&local_counts_[0]), | |
19 counts_size_(local_counts_.size()), | |
17 bucket_ranges_(bucket_ranges) { | 20 bucket_ranges_(bucket_ranges) { |
Alexei Svitkine (slow)
2015/12/09 23:03:40
Can you use delegated constructor syntax instead o
bcwhite
2015/12/10 14:51:33
Done, though it's not possible to delegate the 2nd
| |
18 CHECK_GE(bucket_ranges_->bucket_count(), 1u); | 21 CHECK_GE(bucket_ranges_->bucket_count(), 1u); |
19 } | 22 } |
20 | 23 |
24 SampleVector::SampleVector(uint64_t id, const BucketRanges* bucket_ranges) | |
25 : HistogramSamples(id), | |
26 local_counts_(bucket_ranges->bucket_count()), | |
27 counts_(&local_counts_[0]), | |
28 counts_size_(local_counts_.size()), | |
29 bucket_ranges_(bucket_ranges) { | |
30 CHECK_GE(bucket_ranges_->bucket_count(), 1u); | |
31 } | |
32 | |
33 SampleVector::SampleVector(uint64_t id, | |
34 HistogramBase::AtomicCount* counts, | |
35 size_t counts_size, | |
36 Metadata* meta, | |
37 const BucketRanges* bucket_ranges) | |
38 : HistogramSamples(id, meta), | |
39 counts_(counts), | |
40 counts_size_(bucket_ranges->bucket_count()), | |
41 bucket_ranges_(bucket_ranges) { | |
42 CHECK_LE(bucket_ranges_->bucket_count(), counts_size_); | |
43 CHECK_GE(bucket_ranges_->bucket_count(), 1u); | |
44 } | |
45 | |
21 SampleVector::~SampleVector() {} | 46 SampleVector::~SampleVector() {} |
22 | 47 |
23 void SampleVector::Accumulate(Sample value, Count count) { | 48 void SampleVector::Accumulate(Sample value, Count count) { |
24 size_t bucket_index = GetBucketIndex(value); | 49 size_t bucket_index = GetBucketIndex(value); |
25 subtle::NoBarrier_Store(&counts_[bucket_index], | 50 subtle::NoBarrier_Store(&counts_[bucket_index], |
26 subtle::NoBarrier_Load(&counts_[bucket_index]) + count); | 51 subtle::NoBarrier_Load(&counts_[bucket_index]) + count); |
27 IncreaseSum(count * value); | 52 IncreaseSum(count * value); |
28 IncreaseRedundantCount(count); | 53 IncreaseRedundantCount(count); |
29 } | 54 } |
30 | 55 |
31 Count SampleVector::GetCount(Sample value) const { | 56 Count SampleVector::GetCount(Sample value) const { |
32 size_t bucket_index = GetBucketIndex(value); | 57 size_t bucket_index = GetBucketIndex(value); |
33 return subtle::NoBarrier_Load(&counts_[bucket_index]); | 58 return subtle::NoBarrier_Load(&counts_[bucket_index]); |
34 } | 59 } |
35 | 60 |
36 Count SampleVector::TotalCount() const { | 61 Count SampleVector::TotalCount() const { |
37 Count count = 0; | 62 Count count = 0; |
38 for (size_t i = 0; i < counts_.size(); i++) { | 63 for (size_t i = 0; i < counts_size_; i++) { |
39 count += subtle::NoBarrier_Load(&counts_[i]); | 64 count += subtle::NoBarrier_Load(&counts_[i]); |
40 } | 65 } |
41 return count; | 66 return count; |
42 } | 67 } |
43 | 68 |
44 Count SampleVector::GetCountAtIndex(size_t bucket_index) const { | 69 Count SampleVector::GetCountAtIndex(size_t bucket_index) const { |
45 DCHECK(bucket_index < counts_.size()); | 70 DCHECK(bucket_index < counts_size_); |
46 return subtle::NoBarrier_Load(&counts_[bucket_index]); | 71 return subtle::NoBarrier_Load(&counts_[bucket_index]); |
47 } | 72 } |
48 | 73 |
49 scoped_ptr<SampleCountIterator> SampleVector::Iterator() const { | 74 scoped_ptr<SampleCountIterator> SampleVector::Iterator() const { |
50 return scoped_ptr<SampleCountIterator>( | 75 return scoped_ptr<SampleCountIterator>( |
51 new SampleVectorIterator(&counts_, bucket_ranges_)); | 76 new SampleVectorIterator(counts_, counts_size_, bucket_ranges_)); |
52 } | 77 } |
53 | 78 |
54 bool SampleVector::AddSubtractImpl(SampleCountIterator* iter, | 79 bool SampleVector::AddSubtractImpl(SampleCountIterator* iter, |
55 HistogramSamples::Operator op) { | 80 HistogramSamples::Operator op) { |
56 HistogramBase::Sample min; | 81 HistogramBase::Sample min; |
57 HistogramBase::Sample max; | 82 HistogramBase::Sample max; |
58 HistogramBase::Count count; | 83 HistogramBase::Count count; |
59 | 84 |
60 // Go through the iterator and add the counts into correct bucket. | 85 // Go through the iterator and add the counts into correct bucket. |
61 size_t index = 0; | 86 size_t index = 0; |
62 while (index < counts_.size() && !iter->Done()) { | 87 while (index < counts_size_ && !iter->Done()) { |
63 iter->Get(&min, &max, &count); | 88 iter->Get(&min, &max, &count); |
64 if (min == bucket_ranges_->range(index) && | 89 if (min == bucket_ranges_->range(index) && |
65 max == bucket_ranges_->range(index + 1)) { | 90 max == bucket_ranges_->range(index + 1)) { |
66 // Sample matches this bucket! | 91 // Sample matches this bucket! |
67 HistogramBase::Count old_counts = | 92 HistogramBase::Count old_counts = |
68 subtle::NoBarrier_Load(&counts_[index]); | 93 subtle::NoBarrier_Load(&counts_[index]); |
69 subtle::NoBarrier_Store(&counts_[index], | 94 subtle::NoBarrier_Store(&counts_[index], |
70 old_counts + ((op == HistogramSamples::ADD) ? count : -count)); | 95 old_counts + ((op == HistogramSamples::ADD) ? count : -count)); |
71 iter->Next(); | 96 iter->Next(); |
72 } else if (min > bucket_ranges_->range(index)) { | 97 } else if (min > bucket_ranges_->range(index)) { |
(...skipping 29 matching lines...) Expand all Loading... | |
102 under = mid; | 127 under = mid; |
103 else | 128 else |
104 over = mid; | 129 over = mid; |
105 } while (true); | 130 } while (true); |
106 | 131 |
107 DCHECK_LE(bucket_ranges_->range(mid), value); | 132 DCHECK_LE(bucket_ranges_->range(mid), value); |
108 CHECK_GT(bucket_ranges_->range(mid + 1), value); | 133 CHECK_GT(bucket_ranges_->range(mid + 1), value); |
109 return mid; | 134 return mid; |
110 } | 135 } |
111 | 136 |
112 SampleVectorIterator::SampleVectorIterator(const std::vector<Count>* counts, | 137 SampleVectorIterator::SampleVectorIterator( |
113 const BucketRanges* bucket_ranges) | 138 const std::vector<HistogramBase::AtomicCount>* counts, |
114 : counts_(counts), | 139 const BucketRanges* bucket_ranges) |
140 : counts_(&(*counts)[0]), | |
141 counts_size_(counts->size()), | |
115 bucket_ranges_(bucket_ranges), | 142 bucket_ranges_(bucket_ranges), |
116 index_(0) { | 143 index_(0) { |
117 CHECK_GE(bucket_ranges_->bucket_count(), counts_->size()); | 144 CHECK_GE(bucket_ranges_->bucket_count(), counts_size_); |
145 SkipEmptyBuckets(); | |
146 } | |
147 | |
148 SampleVectorIterator::SampleVectorIterator( | |
149 const HistogramBase::AtomicCount* counts, | |
150 size_t counts_size, | |
151 const BucketRanges* bucket_ranges) | |
152 : counts_(counts), | |
153 counts_size_(counts_size), | |
154 bucket_ranges_(bucket_ranges), | |
155 index_(0) { | |
156 CHECK_GE(bucket_ranges_->bucket_count(), counts_size_); | |
118 SkipEmptyBuckets(); | 157 SkipEmptyBuckets(); |
119 } | 158 } |
120 | 159 |
121 SampleVectorIterator::~SampleVectorIterator() {} | 160 SampleVectorIterator::~SampleVectorIterator() {} |
122 | 161 |
123 bool SampleVectorIterator::Done() const { | 162 bool SampleVectorIterator::Done() const { |
124 return index_ >= counts_->size(); | 163 return index_ >= counts_size_; |
125 } | 164 } |
126 | 165 |
127 void SampleVectorIterator::Next() { | 166 void SampleVectorIterator::Next() { |
128 DCHECK(!Done()); | 167 DCHECK(!Done()); |
129 index_++; | 168 index_++; |
130 SkipEmptyBuckets(); | 169 SkipEmptyBuckets(); |
131 } | 170 } |
132 | 171 |
133 void SampleVectorIterator::Get(HistogramBase::Sample* min, | 172 void SampleVectorIterator::Get(HistogramBase::Sample* min, |
134 HistogramBase::Sample* max, | 173 HistogramBase::Sample* max, |
135 HistogramBase::Count* count) const { | 174 HistogramBase::Count* count) const { |
136 DCHECK(!Done()); | 175 DCHECK(!Done()); |
137 if (min != NULL) | 176 if (min != NULL) |
138 *min = bucket_ranges_->range(index_); | 177 *min = bucket_ranges_->range(index_); |
139 if (max != NULL) | 178 if (max != NULL) |
140 *max = bucket_ranges_->range(index_ + 1); | 179 *max = bucket_ranges_->range(index_ + 1); |
141 if (count != NULL) | 180 if (count != NULL) |
142 *count = subtle::NoBarrier_Load(&(*counts_)[index_]); | 181 *count = subtle::NoBarrier_Load(&counts_[index_]); |
143 } | 182 } |
144 | 183 |
145 bool SampleVectorIterator::GetBucketIndex(size_t* index) const { | 184 bool SampleVectorIterator::GetBucketIndex(size_t* index) const { |
146 DCHECK(!Done()); | 185 DCHECK(!Done()); |
147 if (index != NULL) | 186 if (index != NULL) |
148 *index = index_; | 187 *index = index_; |
149 return true; | 188 return true; |
150 } | 189 } |
151 | 190 |
152 void SampleVectorIterator::SkipEmptyBuckets() { | 191 void SampleVectorIterator::SkipEmptyBuckets() { |
153 if (Done()) | 192 if (Done()) |
154 return; | 193 return; |
155 | 194 |
156 while (index_ < counts_->size()) { | 195 while (index_ < counts_size_) { |
157 if (subtle::NoBarrier_Load(&(*counts_)[index_]) != 0) | 196 if (subtle::NoBarrier_Load(&counts_[index_]) != 0) |
158 return; | 197 return; |
159 index_++; | 198 index_++; |
160 } | 199 } |
161 } | 200 } |
162 | 201 |
163 } // namespace base | 202 } // namespace base |
OLD | NEW |