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 : SampleVector(0, bucket_ranges) {} |
| 17 |
| 18 SampleVector::SampleVector(uint64_t id, const BucketRanges* bucket_ranges) |
| 19 : HistogramSamples(id), |
| 20 local_counts_(bucket_ranges->bucket_count()), |
| 21 counts_(&local_counts_[0]), |
| 22 counts_size_(local_counts_.size()), |
17 bucket_ranges_(bucket_ranges) { | 23 bucket_ranges_(bucket_ranges) { |
18 CHECK_GE(bucket_ranges_->bucket_count(), 1u); | 24 CHECK_GE(bucket_ranges_->bucket_count(), 1u); |
19 } | 25 } |
20 | 26 |
| 27 SampleVector::SampleVector(uint64_t id, |
| 28 HistogramBase::AtomicCount* counts, |
| 29 size_t counts_size, |
| 30 Metadata* meta, |
| 31 const BucketRanges* bucket_ranges) |
| 32 : HistogramSamples(id, meta), |
| 33 counts_(counts), |
| 34 counts_size_(bucket_ranges->bucket_count()), |
| 35 bucket_ranges_(bucket_ranges) { |
| 36 CHECK_LE(bucket_ranges_->bucket_count(), counts_size_); |
| 37 CHECK_GE(bucket_ranges_->bucket_count(), 1u); |
| 38 } |
| 39 |
21 SampleVector::~SampleVector() {} | 40 SampleVector::~SampleVector() {} |
22 | 41 |
23 void SampleVector::Accumulate(Sample value, Count count) { | 42 void SampleVector::Accumulate(Sample value, Count count) { |
24 size_t bucket_index = GetBucketIndex(value); | 43 size_t bucket_index = GetBucketIndex(value); |
25 subtle::NoBarrier_Store(&counts_[bucket_index], | 44 subtle::NoBarrier_Store(&counts_[bucket_index], |
26 subtle::NoBarrier_Load(&counts_[bucket_index]) + count); | 45 subtle::NoBarrier_Load(&counts_[bucket_index]) + count); |
27 IncreaseSum(count * value); | 46 IncreaseSum(count * value); |
28 IncreaseRedundantCount(count); | 47 IncreaseRedundantCount(count); |
29 } | 48 } |
30 | 49 |
31 Count SampleVector::GetCount(Sample value) const { | 50 Count SampleVector::GetCount(Sample value) const { |
32 size_t bucket_index = GetBucketIndex(value); | 51 size_t bucket_index = GetBucketIndex(value); |
33 return subtle::NoBarrier_Load(&counts_[bucket_index]); | 52 return subtle::NoBarrier_Load(&counts_[bucket_index]); |
34 } | 53 } |
35 | 54 |
36 Count SampleVector::TotalCount() const { | 55 Count SampleVector::TotalCount() const { |
37 Count count = 0; | 56 Count count = 0; |
38 for (size_t i = 0; i < counts_.size(); i++) { | 57 for (size_t i = 0; i < counts_size_; i++) { |
39 count += subtle::NoBarrier_Load(&counts_[i]); | 58 count += subtle::NoBarrier_Load(&counts_[i]); |
40 } | 59 } |
41 return count; | 60 return count; |
42 } | 61 } |
43 | 62 |
44 Count SampleVector::GetCountAtIndex(size_t bucket_index) const { | 63 Count SampleVector::GetCountAtIndex(size_t bucket_index) const { |
45 DCHECK(bucket_index < counts_.size()); | 64 DCHECK(bucket_index < counts_size_); |
46 return subtle::NoBarrier_Load(&counts_[bucket_index]); | 65 return subtle::NoBarrier_Load(&counts_[bucket_index]); |
47 } | 66 } |
48 | 67 |
49 scoped_ptr<SampleCountIterator> SampleVector::Iterator() const { | 68 scoped_ptr<SampleCountIterator> SampleVector::Iterator() const { |
50 return scoped_ptr<SampleCountIterator>( | 69 return scoped_ptr<SampleCountIterator>( |
51 new SampleVectorIterator(&counts_, bucket_ranges_)); | 70 new SampleVectorIterator(counts_, counts_size_, bucket_ranges_)); |
52 } | 71 } |
53 | 72 |
54 bool SampleVector::AddSubtractImpl(SampleCountIterator* iter, | 73 bool SampleVector::AddSubtractImpl(SampleCountIterator* iter, |
55 HistogramSamples::Operator op) { | 74 HistogramSamples::Operator op) { |
56 HistogramBase::Sample min; | 75 HistogramBase::Sample min; |
57 HistogramBase::Sample max; | 76 HistogramBase::Sample max; |
58 HistogramBase::Count count; | 77 HistogramBase::Count count; |
59 | 78 |
60 // Go through the iterator and add the counts into correct bucket. | 79 // Go through the iterator and add the counts into correct bucket. |
61 size_t index = 0; | 80 size_t index = 0; |
62 while (index < counts_.size() && !iter->Done()) { | 81 while (index < counts_size_ && !iter->Done()) { |
63 iter->Get(&min, &max, &count); | 82 iter->Get(&min, &max, &count); |
64 if (min == bucket_ranges_->range(index) && | 83 if (min == bucket_ranges_->range(index) && |
65 max == bucket_ranges_->range(index + 1)) { | 84 max == bucket_ranges_->range(index + 1)) { |
66 // Sample matches this bucket! | 85 // Sample matches this bucket! |
67 HistogramBase::Count old_counts = | 86 HistogramBase::Count old_counts = |
68 subtle::NoBarrier_Load(&counts_[index]); | 87 subtle::NoBarrier_Load(&counts_[index]); |
69 subtle::NoBarrier_Store(&counts_[index], | 88 subtle::NoBarrier_Store(&counts_[index], |
70 old_counts + ((op == HistogramSamples::ADD) ? count : -count)); | 89 old_counts + ((op == HistogramSamples::ADD) ? count : -count)); |
71 iter->Next(); | 90 iter->Next(); |
72 } else if (min > bucket_ranges_->range(index)) { | 91 } else if (min > bucket_ranges_->range(index)) { |
(...skipping 29 matching lines...) Expand all Loading... |
102 under = mid; | 121 under = mid; |
103 else | 122 else |
104 over = mid; | 123 over = mid; |
105 } while (true); | 124 } while (true); |
106 | 125 |
107 DCHECK_LE(bucket_ranges_->range(mid), value); | 126 DCHECK_LE(bucket_ranges_->range(mid), value); |
108 CHECK_GT(bucket_ranges_->range(mid + 1), value); | 127 CHECK_GT(bucket_ranges_->range(mid + 1), value); |
109 return mid; | 128 return mid; |
110 } | 129 } |
111 | 130 |
112 SampleVectorIterator::SampleVectorIterator(const std::vector<Count>* counts, | 131 SampleVectorIterator::SampleVectorIterator( |
113 const BucketRanges* bucket_ranges) | 132 const std::vector<HistogramBase::AtomicCount>* counts, |
114 : counts_(counts), | 133 const BucketRanges* bucket_ranges) |
| 134 : counts_(&(*counts)[0]), |
| 135 counts_size_(counts->size()), |
115 bucket_ranges_(bucket_ranges), | 136 bucket_ranges_(bucket_ranges), |
116 index_(0) { | 137 index_(0) { |
117 CHECK_GE(bucket_ranges_->bucket_count(), counts_->size()); | 138 CHECK_GE(bucket_ranges_->bucket_count(), counts_size_); |
| 139 SkipEmptyBuckets(); |
| 140 } |
| 141 |
| 142 SampleVectorIterator::SampleVectorIterator( |
| 143 const HistogramBase::AtomicCount* counts, |
| 144 size_t counts_size, |
| 145 const BucketRanges* bucket_ranges) |
| 146 : counts_(counts), |
| 147 counts_size_(counts_size), |
| 148 bucket_ranges_(bucket_ranges), |
| 149 index_(0) { |
| 150 CHECK_GE(bucket_ranges_->bucket_count(), counts_size_); |
118 SkipEmptyBuckets(); | 151 SkipEmptyBuckets(); |
119 } | 152 } |
120 | 153 |
121 SampleVectorIterator::~SampleVectorIterator() {} | 154 SampleVectorIterator::~SampleVectorIterator() {} |
122 | 155 |
123 bool SampleVectorIterator::Done() const { | 156 bool SampleVectorIterator::Done() const { |
124 return index_ >= counts_->size(); | 157 return index_ >= counts_size_; |
125 } | 158 } |
126 | 159 |
127 void SampleVectorIterator::Next() { | 160 void SampleVectorIterator::Next() { |
128 DCHECK(!Done()); | 161 DCHECK(!Done()); |
129 index_++; | 162 index_++; |
130 SkipEmptyBuckets(); | 163 SkipEmptyBuckets(); |
131 } | 164 } |
132 | 165 |
133 void SampleVectorIterator::Get(HistogramBase::Sample* min, | 166 void SampleVectorIterator::Get(HistogramBase::Sample* min, |
134 HistogramBase::Sample* max, | 167 HistogramBase::Sample* max, |
135 HistogramBase::Count* count) const { | 168 HistogramBase::Count* count) const { |
136 DCHECK(!Done()); | 169 DCHECK(!Done()); |
137 if (min != NULL) | 170 if (min != NULL) |
138 *min = bucket_ranges_->range(index_); | 171 *min = bucket_ranges_->range(index_); |
139 if (max != NULL) | 172 if (max != NULL) |
140 *max = bucket_ranges_->range(index_ + 1); | 173 *max = bucket_ranges_->range(index_ + 1); |
141 if (count != NULL) | 174 if (count != NULL) |
142 *count = subtle::NoBarrier_Load(&(*counts_)[index_]); | 175 *count = subtle::NoBarrier_Load(&counts_[index_]); |
143 } | 176 } |
144 | 177 |
145 bool SampleVectorIterator::GetBucketIndex(size_t* index) const { | 178 bool SampleVectorIterator::GetBucketIndex(size_t* index) const { |
146 DCHECK(!Done()); | 179 DCHECK(!Done()); |
147 if (index != NULL) | 180 if (index != NULL) |
148 *index = index_; | 181 *index = index_; |
149 return true; | 182 return true; |
150 } | 183 } |
151 | 184 |
152 void SampleVectorIterator::SkipEmptyBuckets() { | 185 void SampleVectorIterator::SkipEmptyBuckets() { |
153 if (Done()) | 186 if (Done()) |
154 return; | 187 return; |
155 | 188 |
156 while (index_ < counts_->size()) { | 189 while (index_ < counts_size_) { |
157 if (subtle::NoBarrier_Load(&(*counts_)[index_]) != 0) | 190 if (subtle::NoBarrier_Load(&counts_[index_]) != 0) |
158 return; | 191 return; |
159 index_++; | 192 index_++; |
160 } | 193 } |
161 } | 194 } |
162 | 195 |
163 } // namespace base | 196 } // namespace base |
OLD | NEW |