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

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

Issue 1471073007: Reorganize histograms for persistence. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shmem-alloc
Patch Set: addressed review comments by Alexei Created 5 years 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/statistics_recorder.h ('k') | base/test/histogram_tester.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/statistics_recorder.h" 5 #include "base/metrics/statistics_recorder.h"
6 6
7 #include "base/at_exit.h" 7 #include "base/at_exit.h"
8 #include "base/debug/leak_annotations.h" 8 #include "base/debug/leak_annotations.h"
9 #include "base/json/string_escape.h" 9 #include "base/json/string_escape.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/metrics/metrics_hashes.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
15 #include "base/synchronization/lock.h" 16 #include "base/synchronization/lock.h"
16 #include "base/values.h" 17 #include "base/values.h"
17 18
18 namespace { 19 namespace {
19 // Initialize histogram statistics gathering system. 20 // Initialize histogram statistics gathering system.
20 base::LazyInstance<base::StatisticsRecorder>::Leaky g_statistics_recorder_ = 21 base::LazyInstance<base::StatisticsRecorder>::Leaky g_statistics_recorder_ =
21 LAZY_INSTANCE_INITIALIZER; 22 LAZY_INSTANCE_INITIALIZER;
22 } // namespace 23 } // namespace
(...skipping 28 matching lines...) Expand all
51 } 52 }
52 53
53 HistogramBase* histogram_to_delete = NULL; 54 HistogramBase* histogram_to_delete = NULL;
54 HistogramBase* histogram_to_return = NULL; 55 HistogramBase* histogram_to_return = NULL;
55 { 56 {
56 base::AutoLock auto_lock(*lock_); 57 base::AutoLock auto_lock(*lock_);
57 if (histograms_ == NULL) { 58 if (histograms_ == NULL) {
58 histogram_to_return = histogram; 59 histogram_to_return = histogram;
59 } else { 60 } else {
60 const std::string& name = histogram->histogram_name(); 61 const std::string& name = histogram->histogram_name();
61 HistogramMap::iterator it = histograms_->find(HistogramNameRef(name)); 62 uint64_t name_hash = histogram->name_hash();
63 HistogramMap::iterator it = histograms_->find(name_hash);
62 if (histograms_->end() == it) { 64 if (histograms_->end() == it) {
63 (*histograms_)[HistogramNameRef(name)] = histogram; 65 (*histograms_)[name_hash] = histogram;
64 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 66 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322
65 // If there are callbacks for this histogram, we set the kCallbackExists 67 // If there are callbacks for this histogram, we set the kCallbackExists
66 // flag. 68 // flag.
67 auto callback_iterator = callbacks_->find(name); 69 auto callback_iterator = callbacks_->find(name);
68 if (callback_iterator != callbacks_->end()) { 70 if (callback_iterator != callbacks_->end()) {
69 if (!callback_iterator->second.is_null()) 71 if (!callback_iterator->second.is_null())
70 histogram->SetFlags(HistogramBase::kCallbackExists); 72 histogram->SetFlags(HistogramBase::kCallbackExists);
71 else 73 else
72 histogram->ClearFlags(HistogramBase::kCallbackExists); 74 histogram->ClearFlags(HistogramBase::kCallbackExists);
73 } 75 }
74 histogram_to_return = histogram; 76 histogram_to_return = histogram;
75 } else if (histogram == it->second) { 77 } else if (histogram == it->second) {
76 // The histogram was registered before. 78 // The histogram was registered before.
77 histogram_to_return = histogram; 79 histogram_to_return = histogram;
78 } else { 80 } else {
79 // We already have one histogram with this name. 81 // We already have one histogram with this name.
82 DCHECK_EQ(histogram->histogram_name(),
83 it->second->histogram_name()) << "hash collision";
80 histogram_to_return = it->second; 84 histogram_to_return = it->second;
81 histogram_to_delete = histogram; 85 histogram_to_delete = histogram;
82 } 86 }
83 } 87 }
84 } 88 }
85 delete histogram_to_delete; 89 delete histogram_to_delete;
86 return histogram_to_return; 90 return histogram_to_return;
87 } 91 }
88 92
89 // static 93 // static
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 197
194 // static 198 // static
195 void StatisticsRecorder::GetHistograms(Histograms* output) { 199 void StatisticsRecorder::GetHistograms(Histograms* output) {
196 if (lock_ == NULL) 200 if (lock_ == NULL)
197 return; 201 return;
198 base::AutoLock auto_lock(*lock_); 202 base::AutoLock auto_lock(*lock_);
199 if (histograms_ == NULL) 203 if (histograms_ == NULL)
200 return; 204 return;
201 205
202 for (const auto& entry : *histograms_) { 206 for (const auto& entry : *histograms_) {
203 DCHECK_EQ(entry.first.name_, entry.second->histogram_name()); 207 DCHECK_EQ(entry.first, entry.second->name_hash());
204 output->push_back(entry.second); 208 output->push_back(entry.second);
205 } 209 }
206 } 210 }
207 211
208 // static 212 // static
209 void StatisticsRecorder::GetBucketRanges( 213 void StatisticsRecorder::GetBucketRanges(
210 std::vector<const BucketRanges*>* output) { 214 std::vector<const BucketRanges*>* output) {
211 if (lock_ == NULL) 215 if (lock_ == NULL)
212 return; 216 return;
213 base::AutoLock auto_lock(*lock_); 217 base::AutoLock auto_lock(*lock_);
214 if (ranges_ == NULL) 218 if (ranges_ == NULL)
215 return; 219 return;
216 220
217 for (const auto& entry : *ranges_) { 221 for (const auto& entry : *ranges_) {
218 for (const auto& range_entry : *entry.second) { 222 for (const auto& range_entry : *entry.second) {
219 output->push_back(range_entry); 223 output->push_back(range_entry);
220 } 224 }
221 } 225 }
222 } 226 }
223 227
224 // static 228 // static
225 HistogramBase* StatisticsRecorder::FindHistogram(const std::string& name) { 229 HistogramBase* StatisticsRecorder::FindHistogram(const std::string& name) {
226 if (lock_ == NULL) 230 if (lock_ == NULL)
227 return NULL; 231 return NULL;
228 base::AutoLock auto_lock(*lock_); 232 base::AutoLock auto_lock(*lock_);
229 if (histograms_ == NULL) 233 if (histograms_ == NULL)
230 return NULL; 234 return NULL;
231 235
232 HistogramMap::iterator it = histograms_->find(HistogramNameRef(name)); 236 HistogramMap::iterator it = histograms_->find(HashMetricName(name));
233 if (histograms_->end() == it) 237 if (histograms_->end() == it)
234 return NULL; 238 return NULL;
239 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision";
235 return it->second; 240 return it->second;
236 } 241 }
237 242
238 // static 243 // static
239 bool StatisticsRecorder::SetCallback( 244 bool StatisticsRecorder::SetCallback(
240 const std::string& name, 245 const std::string& name,
241 const StatisticsRecorder::OnSampleCallback& cb) { 246 const StatisticsRecorder::OnSampleCallback& cb) {
242 DCHECK(!cb.is_null()); 247 DCHECK(!cb.is_null());
243 if (lock_ == NULL) 248 if (lock_ == NULL)
244 return false; 249 return false;
245 base::AutoLock auto_lock(*lock_); 250 base::AutoLock auto_lock(*lock_);
246 if (histograms_ == NULL) 251 if (histograms_ == NULL)
247 return false; 252 return false;
248 253
249 if (ContainsKey(*callbacks_, name)) 254 if (ContainsKey(*callbacks_, name))
250 return false; 255 return false;
251 callbacks_->insert(std::make_pair(name, cb)); 256 callbacks_->insert(std::make_pair(name, cb));
252 257
253 auto histogram_iterator = histograms_->find(HistogramNameRef(name)); 258 HistogramMap::iterator it = histograms_->find(HashMetricName(name));
254 if (histogram_iterator != histograms_->end()) 259 if (it != histograms_->end()) {
255 histogram_iterator->second->SetFlags(HistogramBase::kCallbackExists); 260 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision";
261 it->second->SetFlags(HistogramBase::kCallbackExists);
262 }
256 263
257 return true; 264 return true;
258 } 265 }
259 266
260 // static 267 // static
261 void StatisticsRecorder::ClearCallback(const std::string& name) { 268 void StatisticsRecorder::ClearCallback(const std::string& name) {
262 if (lock_ == NULL) 269 if (lock_ == NULL)
263 return; 270 return;
264 base::AutoLock auto_lock(*lock_); 271 base::AutoLock auto_lock(*lock_);
265 if (histograms_ == NULL) 272 if (histograms_ == NULL)
266 return; 273 return;
267 274
268 callbacks_->erase(name); 275 callbacks_->erase(name);
269 276
270 // We also clear the flag from the histogram (if it exists). 277 // We also clear the flag from the histogram (if it exists).
271 auto histogram_iterator = histograms_->find(HistogramNameRef(name)); 278 HistogramMap::iterator it = histograms_->find(HashMetricName(name));
272 if (histogram_iterator != histograms_->end()) 279 if (it != histograms_->end()) {
273 histogram_iterator->second->ClearFlags(HistogramBase::kCallbackExists); 280 DCHECK_EQ(name, it->second->histogram_name()) << "hash collision";
281 it->second->ClearFlags(HistogramBase::kCallbackExists);
282 }
274 } 283 }
275 284
276 // static 285 // static
277 StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback( 286 StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback(
278 const std::string& name) { 287 const std::string& name) {
279 if (lock_ == NULL) 288 if (lock_ == NULL)
280 return OnSampleCallback(); 289 return OnSampleCallback();
281 base::AutoLock auto_lock(*lock_); 290 base::AutoLock auto_lock(*lock_);
282 if (histograms_ == NULL) 291 if (histograms_ == NULL)
283 return OnSampleCallback(); 292 return OnSampleCallback();
284 293
285 auto callback_iterator = callbacks_->find(name); 294 auto callback_iterator = callbacks_->find(name);
286 return callback_iterator != callbacks_->end() ? callback_iterator->second 295 return callback_iterator != callbacks_->end() ? callback_iterator->second
287 : OnSampleCallback(); 296 : OnSampleCallback();
288 } 297 }
289 298
290 // private static 299 // private static
291 void StatisticsRecorder::GetSnapshot(const std::string& query, 300 void StatisticsRecorder::GetSnapshot(const std::string& query,
292 Histograms* snapshot) { 301 Histograms* snapshot) {
293 if (lock_ == NULL) 302 if (lock_ == NULL)
294 return; 303 return;
295 base::AutoLock auto_lock(*lock_); 304 base::AutoLock auto_lock(*lock_);
296 if (histograms_ == NULL) 305 if (histograms_ == NULL)
297 return; 306 return;
298 307
299 for (const auto& entry : *histograms_) { 308 for (const auto& entry : *histograms_) {
300 if (entry.first.name_.find(query) != std::string::npos) 309 if (entry.second->histogram_name().find(query) != std::string::npos)
301 snapshot->push_back(entry.second); 310 snapshot->push_back(entry.second);
302 } 311 }
303 } 312 }
304 313
305 // This singleton instance should be started during the single threaded portion 314 // This singleton instance should be started during the single threaded portion
306 // of main(), and hence it is not thread safe. It initializes globals to 315 // of main(), and hence it is not thread safe. It initializes globals to
307 // provide support for all future calls. 316 // provide support for all future calls.
308 StatisticsRecorder::StatisticsRecorder() { 317 StatisticsRecorder::StatisticsRecorder() {
309 DCHECK(!histograms_); 318 DCHECK(!histograms_);
310 if (lock_ == NULL) { 319 if (lock_ == NULL) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 // static 366 // static
358 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 367 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
359 // static 368 // static
360 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL; 369 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = NULL;
361 // static 370 // static
362 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; 371 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL;
363 // static 372 // static
364 base::Lock* StatisticsRecorder::lock_ = NULL; 373 base::Lock* StatisticsRecorder::lock_ = NULL;
365 374
366 } // namespace base 375 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/statistics_recorder.h ('k') | base/test/histogram_tester.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698