OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/persistent_sample_map.h" | 5 #include "base/metrics/persistent_sample_map.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
10 #include "base/metrics/persistent_histogram_allocator.h" | 10 #include "base/metrics/persistent_histogram_allocator.h" |
| 11 #include "base/numerics/safe_conversions.h" |
11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
12 | 13 |
13 namespace base { | 14 namespace base { |
14 | 15 |
15 typedef HistogramBase::Count Count; | 16 typedef HistogramBase::Count Count; |
16 typedef HistogramBase::Sample Sample; | 17 typedef HistogramBase::Sample Sample; |
17 | 18 |
18 namespace { | 19 namespace { |
19 | 20 |
20 enum NegativeSampleReason { | 21 enum NegativeSampleReason { |
(...skipping 13 matching lines...) Expand all Loading... |
34 typedef std::map<HistogramBase::Sample, HistogramBase::Count*> | 35 typedef std::map<HistogramBase::Sample, HistogramBase::Count*> |
35 SampleToCountMap; | 36 SampleToCountMap; |
36 | 37 |
37 explicit PersistentSampleMapIterator(const SampleToCountMap& sample_counts); | 38 explicit PersistentSampleMapIterator(const SampleToCountMap& sample_counts); |
38 ~PersistentSampleMapIterator() override; | 39 ~PersistentSampleMapIterator() override; |
39 | 40 |
40 // SampleCountIterator: | 41 // SampleCountIterator: |
41 bool Done() const override; | 42 bool Done() const override; |
42 void Next() override; | 43 void Next() override; |
43 void Get(HistogramBase::Sample* min, | 44 void Get(HistogramBase::Sample* min, |
44 HistogramBase::Sample* max, | 45 int64_t* max, |
45 HistogramBase::Count* count) const override; | 46 HistogramBase::Count* count) const override; |
46 | 47 |
47 private: | 48 private: |
48 void SkipEmptyBuckets(); | 49 void SkipEmptyBuckets(); |
49 | 50 |
50 SampleToCountMap::const_iterator iter_; | 51 SampleToCountMap::const_iterator iter_; |
51 const SampleToCountMap::const_iterator end_; | 52 const SampleToCountMap::const_iterator end_; |
52 }; | 53 }; |
53 | 54 |
54 PersistentSampleMapIterator::PersistentSampleMapIterator( | 55 PersistentSampleMapIterator::PersistentSampleMapIterator( |
55 const SampleToCountMap& sample_counts) | 56 const SampleToCountMap& sample_counts) |
56 : iter_(sample_counts.begin()), | 57 : iter_(sample_counts.begin()), |
57 end_(sample_counts.end()) { | 58 end_(sample_counts.end()) { |
58 SkipEmptyBuckets(); | 59 SkipEmptyBuckets(); |
59 } | 60 } |
60 | 61 |
61 PersistentSampleMapIterator::~PersistentSampleMapIterator() {} | 62 PersistentSampleMapIterator::~PersistentSampleMapIterator() {} |
62 | 63 |
63 bool PersistentSampleMapIterator::Done() const { | 64 bool PersistentSampleMapIterator::Done() const { |
64 return iter_ == end_; | 65 return iter_ == end_; |
65 } | 66 } |
66 | 67 |
67 void PersistentSampleMapIterator::Next() { | 68 void PersistentSampleMapIterator::Next() { |
68 DCHECK(!Done()); | 69 DCHECK(!Done()); |
69 ++iter_; | 70 ++iter_; |
70 SkipEmptyBuckets(); | 71 SkipEmptyBuckets(); |
71 } | 72 } |
72 | 73 |
73 void PersistentSampleMapIterator::Get(Sample* min, | 74 void PersistentSampleMapIterator::Get(Sample* min, |
74 Sample* max, | 75 int64_t* max, |
75 Count* count) const { | 76 Count* count) const { |
76 DCHECK(!Done()); | 77 DCHECK(!Done()); |
77 if (min) | 78 if (min) |
78 *min = iter_->first; | 79 *min = iter_->first; |
79 if (max) | 80 if (max) |
80 *max = iter_->first + 1; | 81 *max = strict_cast<int64_t>(iter_->first) + 1; |
81 if (count) | 82 if (count) |
82 *count = *iter_->second; | 83 *count = *iter_->second; |
83 } | 84 } |
84 | 85 |
85 void PersistentSampleMapIterator::SkipEmptyBuckets() { | 86 void PersistentSampleMapIterator::SkipEmptyBuckets() { |
86 while (!Done() && *iter_->second == 0) { | 87 while (!Done() && *iter_->second == 0) { |
87 ++iter_; | 88 ++iter_; |
88 } | 89 } |
89 } | 90 } |
90 | 91 |
(...skipping 20 matching lines...) Expand all Loading... |
111 Metadata* meta) | 112 Metadata* meta) |
112 : HistogramSamples(id, meta), allocator_(allocator) {} | 113 : HistogramSamples(id, meta), allocator_(allocator) {} |
113 | 114 |
114 PersistentSampleMap::~PersistentSampleMap() { | 115 PersistentSampleMap::~PersistentSampleMap() { |
115 if (records_) | 116 if (records_) |
116 records_->Release(this); | 117 records_->Release(this); |
117 } | 118 } |
118 | 119 |
119 void PersistentSampleMap::Accumulate(Sample value, Count count) { | 120 void PersistentSampleMap::Accumulate(Sample value, Count count) { |
120 *GetOrCreateSampleCountStorage(value) += count; | 121 *GetOrCreateSampleCountStorage(value) += count; |
121 IncreaseSumAndCount(static_cast<int64_t>(count) * value, count); | 122 IncreaseSumAndCount(strict_cast<int64_t>(count) * value, count); |
122 } | 123 } |
123 | 124 |
124 Count PersistentSampleMap::GetCount(Sample value) const { | 125 Count PersistentSampleMap::GetCount(Sample value) const { |
125 // Have to override "const" to make sure all samples have been loaded before | 126 // Have to override "const" to make sure all samples have been loaded before |
126 // being able to know what value to return. | 127 // being able to know what value to return. |
127 Count* count_pointer = | 128 Count* count_pointer = |
128 const_cast<PersistentSampleMap*>(this)->GetSampleCountStorage(value); | 129 const_cast<PersistentSampleMap*>(this)->GetSampleCountStorage(value); |
129 return count_pointer ? *count_pointer : 0; | 130 return count_pointer ? *count_pointer : 0; |
130 } | 131 } |
131 | 132 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 record->count = 0; | 180 record->count = 0; |
180 | 181 |
181 PersistentMemoryAllocator::Reference ref = allocator->GetAsReference(record); | 182 PersistentMemoryAllocator::Reference ref = allocator->GetAsReference(record); |
182 allocator->MakeIterable(ref); | 183 allocator->MakeIterable(ref); |
183 return ref; | 184 return ref; |
184 } | 185 } |
185 | 186 |
186 bool PersistentSampleMap::AddSubtractImpl(SampleCountIterator* iter, | 187 bool PersistentSampleMap::AddSubtractImpl(SampleCountIterator* iter, |
187 Operator op) { | 188 Operator op) { |
188 Sample min; | 189 Sample min; |
189 Sample max; | 190 int64_t max; |
190 Count count; | 191 Count count; |
191 for (; !iter->Done(); iter->Next()) { | 192 for (; !iter->Done(); iter->Next()) { |
192 iter->Get(&min, &max, &count); | 193 iter->Get(&min, &max, &count); |
193 if (count == 0) | 194 if (count == 0) |
194 continue; | 195 continue; |
195 if (min + 1 != max) | 196 if (strict_cast<int64_t>(min) + 1 != max) |
196 return false; // SparseHistogram only supports bucket with size 1. | 197 return false; // SparseHistogram only supports bucket with size 1. |
197 | 198 |
198 #if 0 // TODO(bcwhite) Re-enable efficient version after crbug.com/682680. | 199 #if 0 // TODO(bcwhite) Re-enable efficient version after crbug.com/682680. |
199 *GetOrCreateSampleCountStorage(min) += | 200 *GetOrCreateSampleCountStorage(min) += |
200 (op == HistogramSamples::ADD) ? count : -count; | 201 (op == HistogramSamples::ADD) ? count : -count; |
201 #else | 202 #else |
202 NegativeSampleReason reason = MAX_NEGATIVE_SAMPLE_REASONS; | 203 NegativeSampleReason reason = MAX_NEGATIVE_SAMPLE_REASONS; |
203 if (op == HistogramSamples::ADD) { | 204 if (op == HistogramSamples::ADD) { |
204 // Add should generally be adding only positive values. | 205 // Add should generally be adding only positive values. |
205 Count* local_count_ptr = GetOrCreateSampleCountStorage(min); | 206 Count* local_count_ptr = GetOrCreateSampleCountStorage(min); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 found_count = &record->count; | 328 found_count = &record->count; |
328 if (!import_everything) | 329 if (!import_everything) |
329 break; | 330 break; |
330 } | 331 } |
331 } | 332 } |
332 | 333 |
333 return found_count; | 334 return found_count; |
334 } | 335 } |
335 | 336 |
336 } // namespace base | 337 } // namespace base |
OLD | NEW |