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

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

Issue 2867303004: [histogram] Make histograms more resistant to overflows. (Closed)
Patch Set: final final fix 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/sparse_histogram.h ('k') | base/metrics/sparse_histogram_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 (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/sparse_histogram.h" 5 #include "base/metrics/sparse_histogram.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/metrics/metrics_hashes.h" 10 #include "base/metrics/metrics_hashes.h"
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 const std::string& name, 78 const std::string& name,
79 HistogramSamples::Metadata* meta, 79 HistogramSamples::Metadata* meta,
80 HistogramSamples::Metadata* logged_meta) { 80 HistogramSamples::Metadata* logged_meta) {
81 return WrapUnique( 81 return WrapUnique(
82 new SparseHistogram(allocator, name, meta, logged_meta)); 82 new SparseHistogram(allocator, name, meta, logged_meta));
83 } 83 }
84 84
85 SparseHistogram::~SparseHistogram() {} 85 SparseHistogram::~SparseHistogram() {}
86 86
87 uint64_t SparseHistogram::name_hash() const { 87 uint64_t SparseHistogram::name_hash() const {
88 return samples_->id(); 88 return unlogged_samples_->id();
89 } 89 }
90 90
91 HistogramType SparseHistogram::GetHistogramType() const { 91 HistogramType SparseHistogram::GetHistogramType() const {
92 return SPARSE_HISTOGRAM; 92 return SPARSE_HISTOGRAM;
93 } 93 }
94 94
95 bool SparseHistogram::HasConstructionArguments( 95 bool SparseHistogram::HasConstructionArguments(
96 Sample expected_minimum, 96 Sample expected_minimum,
97 Sample expected_maximum, 97 Sample expected_maximum,
98 uint32_t expected_bucket_count) const { 98 uint32_t expected_bucket_count) const {
99 // SparseHistogram never has min/max/bucket_count limit. 99 // SparseHistogram never has min/max/bucket_count limit.
100 return false; 100 return false;
101 } 101 }
102 102
103 void SparseHistogram::Add(Sample value) { 103 void SparseHistogram::Add(Sample value) {
104 AddCount(value, 1); 104 AddCount(value, 1);
105 } 105 }
106 106
107 void SparseHistogram::AddCount(Sample value, int count) { 107 void SparseHistogram::AddCount(Sample value, int count) {
108 if (count <= 0) { 108 if (count <= 0) {
109 NOTREACHED(); 109 NOTREACHED();
110 return; 110 return;
111 } 111 }
112 { 112 {
113 base::AutoLock auto_lock(lock_); 113 base::AutoLock auto_lock(lock_);
114 samples_->Accumulate(value, count); 114 unlogged_samples_->Accumulate(value, count);
115 } 115 }
116 116
117 FindAndRunCallback(value); 117 FindAndRunCallback(value);
118 } 118 }
119 119
120 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const { 120 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const {
121 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); 121 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
122 122
123 base::AutoLock auto_lock(lock_); 123 base::AutoLock auto_lock(lock_);
124 snapshot->Add(*samples_); 124 snapshot->Add(*unlogged_samples_);
125 snapshot->Add(*logged_samples_);
125 return std::move(snapshot); 126 return std::move(snapshot);
126 } 127 }
127 128
128 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotDelta() { 129 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotDelta() {
129 DCHECK(!final_delta_created_); 130 DCHECK(!final_delta_created_);
130 131
131 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); 132 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
132 base::AutoLock auto_lock(lock_); 133 base::AutoLock auto_lock(lock_);
133 snapshot->Add(*samples_); 134 snapshot->Add(*unlogged_samples_);
134 135
135 // Subtract what was previously logged and update that information. 136 unlogged_samples_->Subtract(*snapshot);
136 snapshot->Subtract(*logged_samples_);
137 logged_samples_->Add(*snapshot); 137 logged_samples_->Add(*snapshot);
138 return std::move(snapshot); 138 return std::move(snapshot);
139 } 139 }
140 140
141 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotFinalDelta() const { 141 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotFinalDelta() const {
142 DCHECK(!final_delta_created_); 142 DCHECK(!final_delta_created_);
143 final_delta_created_ = true; 143 final_delta_created_ = true;
144 144
145 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); 145 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
146 base::AutoLock auto_lock(lock_); 146 base::AutoLock auto_lock(lock_);
147 snapshot->Add(*samples_); 147 snapshot->Add(*unlogged_samples_);
148 148
149 // Subtract what was previously logged and then return.
150 snapshot->Subtract(*logged_samples_);
151 return std::move(snapshot); 149 return std::move(snapshot);
152 } 150 }
153 151
154 void SparseHistogram::AddSamples(const HistogramSamples& samples) { 152 void SparseHistogram::AddSamples(const HistogramSamples& samples) {
155 base::AutoLock auto_lock(lock_); 153 base::AutoLock auto_lock(lock_);
156 samples_->Add(samples); 154 unlogged_samples_->Add(samples);
157 } 155 }
158 156
159 bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) { 157 bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) {
160 base::AutoLock auto_lock(lock_); 158 base::AutoLock auto_lock(lock_);
161 return samples_->AddFromPickle(iter); 159 return unlogged_samples_->AddFromPickle(iter);
162 } 160 }
163 161
164 void SparseHistogram::WriteHTMLGraph(std::string* output) const { 162 void SparseHistogram::WriteHTMLGraph(std::string* output) const {
165 output->append("<PRE>"); 163 output->append("<PRE>");
166 WriteAsciiImpl(true, "<br>", output); 164 WriteAsciiImpl(true, "<br>", output);
167 output->append("</PRE>"); 165 output->append("</PRE>");
168 } 166 }
169 167
170 void SparseHistogram::WriteAscii(std::string* output) const { 168 void SparseHistogram::WriteAscii(std::string* output) const {
171 WriteAsciiImpl(true, "\n", output); 169 WriteAsciiImpl(true, "\n", output);
172 } 170 }
173 171
174 bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const { 172 bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
175 return pickle->WriteString(histogram_name()) && pickle->WriteInt(flags()); 173 return pickle->WriteString(histogram_name()) && pickle->WriteInt(flags());
176 } 174 }
177 175
178 SparseHistogram::SparseHistogram(const std::string& name) 176 SparseHistogram::SparseHistogram(const std::string& name)
179 : HistogramBase(name), 177 : HistogramBase(name),
180 samples_(new SampleMap(HashMetricName(name))), 178 unlogged_samples_(new SampleMap(HashMetricName(name))),
181 logged_samples_(new SampleMap(samples_->id())) {} 179 logged_samples_(new SampleMap(unlogged_samples_->id())) {}
182 180
183 SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator, 181 SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
184 const std::string& name, 182 const std::string& name,
185 HistogramSamples::Metadata* meta, 183 HistogramSamples::Metadata* meta,
186 HistogramSamples::Metadata* logged_meta) 184 HistogramSamples::Metadata* logged_meta)
187 : HistogramBase(name), 185 : HistogramBase(name),
188 // While other histogram types maintain a static vector of values with 186 // While other histogram types maintain a static vector of values with
189 // sufficient space for both "active" and "logged" samples, with each 187 // sufficient space for both "active" and "logged" samples, with each
190 // SampleVector being given the appropriate half, sparse histograms 188 // SampleVector being given the appropriate half, sparse histograms
191 // have no such initial allocation. Each sample has its own record 189 // have no such initial allocation. Each sample has its own record
192 // attached to a single PersistentSampleMap by a common 64-bit identifier. 190 // attached to a single PersistentSampleMap by a common 64-bit identifier.
193 // Since a sparse histogram has two sample maps (active and logged), 191 // Since a sparse histogram has two sample maps (active and logged),
194 // there must be two sets of sample records with diffent IDs. The 192 // there must be two sets of sample records with diffent IDs. The
195 // "active" samples use, for convenience purposes, an ID matching 193 // "active" samples use, for convenience purposes, an ID matching
196 // that of the histogram while the "logged" samples use that number 194 // that of the histogram while the "logged" samples use that number
197 // plus 1. 195 // plus 1.
198 samples_(new PersistentSampleMap(HashMetricName(name), allocator, meta)), 196 unlogged_samples_(
199 logged_samples_( 197 new PersistentSampleMap(HashMetricName(name), allocator, meta)),
200 new PersistentSampleMap(samples_->id() + 1, allocator, logged_meta)) { 198 logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1,
201 } 199 allocator,
200 logged_meta)) {}
202 201
203 HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) { 202 HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) {
204 std::string histogram_name; 203 std::string histogram_name;
205 int flags; 204 int flags;
206 if (!iter->ReadString(&histogram_name) || !iter->ReadInt(&flags)) { 205 if (!iter->ReadString(&histogram_name) || !iter->ReadInt(&flags)) {
207 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; 206 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name;
208 return NULL; 207 return NULL;
209 } 208 }
210 209
211 flags &= ~HistogramBase::kIPCSerializationSourceFlag; 210 flags &= ~HistogramBase::kIPCSerializationSourceFlag;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 std::string* output) const { 279 std::string* output) const {
281 StringAppendF(output, 280 StringAppendF(output,
282 "Histogram: %s recorded %d samples", 281 "Histogram: %s recorded %d samples",
283 histogram_name().c_str(), 282 histogram_name().c_str(),
284 total_count); 283 total_count);
285 if (flags()) 284 if (flags())
286 StringAppendF(output, " (flags = 0x%x)", flags()); 285 StringAppendF(output, " (flags = 0x%x)", flags());
287 } 286 }
288 287
289 } // namespace base 288 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/sparse_histogram.h ('k') | base/metrics/sparse_histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698