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