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

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

Issue 2853853002: Fix overflow when logging MaxInt32 to a sparse histogram. (Closed)
Patch Set: Address comments. Created 3 years, 7 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
« no previous file with comments | « base/metrics/histogram_samples.cc ('k') | base/metrics/persistent_sample_map_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « base/metrics/histogram_samples.cc ('k') | base/metrics/persistent_sample_map_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698