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

Side by Side Diff: base/histogram.cc

Issue 462027: Use factory to create histograms, and refcounts to track lifetimes... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 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 | Annotate | Revision Log
« no previous file with comments | « base/histogram.h ('k') | base/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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 // Histogram is an object that aggregates statistics, and can summarize them in 5 // Histogram is an object that aggregates statistics, and can summarize them in
6 // various forms, including ASCII graphical, HTML, and numerically (as a 6 // various forms, including ASCII graphical, HTML, and numerically (as a
7 // vector of numbers corresponding to each of the aggregating buckets). 7 // vector of numbers corresponding to each of the aggregating buckets).
8 // See header file for details and examples. 8 // See header file for details and examples.
9 9
10 #include "base/histogram.h" 10 #include "base/histogram.h"
11 11
12 #include <math.h> 12 #include <math.h>
13 #include <string> 13 #include <string>
14 14
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/pickle.h" 16 #include "base/pickle.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 18
19 using base::TimeDelta; 19 using base::TimeDelta;
20 20
21 typedef Histogram::Count Count; 21 typedef Histogram::Count Count;
22 22
23 // static 23 // static
24 const int Histogram::kHexRangePrintingFlag = 0x8000; 24 const int Histogram::kHexRangePrintingFlag = 0x8000;
25 25
26 Histogram::Histogram(const char* name, Sample minimum, 26 scoped_refptr<Histogram> Histogram::HistogramFactoryGet(
27 const std::string& name, Sample minimum, Sample maximum,
28 size_t bucket_count) {
29 scoped_refptr<Histogram> histogram(NULL);
30
31 // Defensive code.
32 if (minimum <= 0)
33 minimum = 1;
34 if (maximum >= kSampleType_MAX)
35 maximum = kSampleType_MAX - 1;
36
37 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
38 DCHECK(histogram.get() != NULL);
39 } else {
40 histogram = new Histogram(name, minimum, maximum, bucket_count);
41 scoped_refptr<Histogram> registered_histogram(NULL);
42 StatisticsRecorder::FindHistogram(name, &registered_histogram);
43 // Allow a NULL return to mean that the StatisticsRecorder was not started.
44 if (registered_histogram.get() != NULL &&
45 registered_histogram.get() != histogram.get())
46 histogram = registered_histogram;
47 }
48
49 DCHECK(HISTOGRAM == histogram->histogram_type());
50 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
51 return histogram;
52 }
53
54 scoped_refptr<Histogram> Histogram::HistogramFactoryGet(
55 const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum,
56 size_t bucket_count) {
57 return HistogramFactoryGet(name,
58 minimum.InMilliseconds(), maximum.InMilliseconds(), bucket_count);
59 }
60
61 Histogram::Histogram(const std::string& name, Sample minimum,
27 Sample maximum, size_t bucket_count) 62 Sample maximum, size_t bucket_count)
28 : histogram_name_(name), 63 : histogram_name_(name),
29 declared_min_(minimum), 64 declared_min_(minimum),
30 declared_max_(maximum), 65 declared_max_(maximum),
31 bucket_count_(bucket_count), 66 bucket_count_(bucket_count),
32 flags_(0), 67 flags_(0),
33 ranges_(bucket_count + 1, 0), 68 ranges_(bucket_count + 1, 0),
34 sample_(), 69 sample_() {
35 registered_(false) {
36 Initialize(); 70 Initialize();
37 } 71 }
38 72
39 Histogram::Histogram(const char* name, TimeDelta minimum, 73 Histogram::Histogram(const std::string& name, TimeDelta minimum,
40 TimeDelta maximum, size_t bucket_count) 74 TimeDelta maximum, size_t bucket_count)
41 : histogram_name_(name), 75 : histogram_name_(name),
42 declared_min_(static_cast<int> (minimum.InMilliseconds())), 76 declared_min_(static_cast<int> (minimum.InMilliseconds())),
43 declared_max_(static_cast<int> (maximum.InMilliseconds())), 77 declared_max_(static_cast<int> (maximum.InMilliseconds())),
44 bucket_count_(bucket_count), 78 bucket_count_(bucket_count),
45 flags_(0), 79 flags_(0),
46 ranges_(bucket_count + 1, 0), 80 ranges_(bucket_count + 1, 0),
47 sample_(), 81 sample_() {
48 registered_(false) {
49 Initialize(); 82 Initialize();
50 } 83 }
51 84
52 Histogram::~Histogram() { 85 Histogram::~Histogram() {
53 if (registered_) 86 DCHECK(!(kPlannedLeakFlag & flags_));
54 StatisticsRecorder::UnRegister(this); 87 if (StatisticsRecorder::dump_on_exit()) {
88 std::string output;
89 WriteAscii(true, "\n", &output);
90 LOG(INFO) << output;
91 }
92
55 // Just to make sure most derived class did this properly... 93 // Just to make sure most derived class did this properly...
56 DCHECK(ValidateBucketRanges()); 94 DCHECK(ValidateBucketRanges());
57 } 95 }
58 96
59 void Histogram::Add(int value) { 97 void Histogram::Add(int value) {
60 if (!registered_)
61 registered_ = StatisticsRecorder::Register(this);
62 if (value >= kSampleType_MAX) 98 if (value >= kSampleType_MAX)
63 value = kSampleType_MAX - 1; 99 value = kSampleType_MAX - 1;
64 if (value < 0) 100 if (value < 0)
65 value = 0; 101 value = 0;
66 size_t index = BucketIndex(value); 102 size_t index = BucketIndex(value);
67 DCHECK(value >= ranges(index)); 103 DCHECK(value >= ranges(index));
68 DCHECK(value < ranges(index + 1)); 104 DCHECK(value < ranges(index + 1));
69 Accumulate(value, 1, index); 105 Accumulate(value, 1, index);
70 } 106 }
71 107
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 declared_max_ = kSampleType_MAX - 1; 199 declared_max_ = kSampleType_MAX - 1;
164 DCHECK(declared_min_ > 0); // We provide underflow bucket. 200 DCHECK(declared_min_ > 0); // We provide underflow bucket.
165 DCHECK(declared_min_ <= declared_max_); 201 DCHECK(declared_min_ <= declared_max_);
166 DCHECK(1 < bucket_count_); 202 DCHECK(1 < bucket_count_);
167 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; 203 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2;
168 DCHECK(bucket_count_ <= maximal_bucket_count); 204 DCHECK(bucket_count_ <= maximal_bucket_count);
169 DCHECK(0 == ranges_[0]); 205 DCHECK(0 == ranges_[0]);
170 ranges_[bucket_count_] = kSampleType_MAX; 206 ranges_[bucket_count_] = kSampleType_MAX;
171 InitializeBucketRange(); 207 InitializeBucketRange();
172 DCHECK(ValidateBucketRanges()); 208 DCHECK(ValidateBucketRanges());
173 registered_ = StatisticsRecorder::Register(this); 209 StatisticsRecorder::Register(this);
174 } 210 }
175 211
176 // Calculate what range of values are held in each bucket. 212 // Calculate what range of values are held in each bucket.
177 // We have to be careful that we don't pick a ratio between starting points in 213 // We have to be careful that we don't pick a ratio between starting points in
178 // consecutive buckets that is sooo small, that the integer bounds are the same 214 // consecutive buckets that is sooo small, that the integer bounds are the same
179 // (effectively making one bucket get no values). We need to avoid: 215 // (effectively making one bucket get no values). We need to avoid:
180 // (ranges_[i] == ranges_[i + 1] 216 // (ranges_[i] == ranges_[i + 1]
181 // To avoid that, we just do a fine-grained bucket width as far as we need to 217 // To avoid that, we just do a fine-grained bucket width as far as we need to
182 // until we get a ratio that moves us along at least 2 units at a time. From 218 // until we get a ratio that moves us along at least 2 units at a time. From
183 // that bucket onward we do use the exponential growth of buckets. 219 // that bucket onward we do use the exponential growth of buckets.
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 while (0 < x_count--) 382 while (0 < x_count--)
347 output->append("-"); 383 output->append("-");
348 output->append("O"); 384 output->append("O");
349 while (0 < x_remainder--) 385 while (0 < x_remainder--)
350 output->append(" "); 386 output->append(" ");
351 } 387 }
352 388
353 // static 389 // static
354 std::string Histogram::SerializeHistogramInfo(const Histogram& histogram, 390 std::string Histogram::SerializeHistogramInfo(const Histogram& histogram,
355 const SampleSet& snapshot) { 391 const SampleSet& snapshot) {
392 DCHECK(histogram.histogram_type() != NOT_VALID_IN_RENDERER);
393
356 Pickle pickle; 394 Pickle pickle;
357
358 pickle.WriteString(histogram.histogram_name()); 395 pickle.WriteString(histogram.histogram_name());
359 pickle.WriteInt(histogram.declared_min()); 396 pickle.WriteInt(histogram.declared_min());
360 pickle.WriteInt(histogram.declared_max()); 397 pickle.WriteInt(histogram.declared_max());
361 pickle.WriteSize(histogram.bucket_count()); 398 pickle.WriteSize(histogram.bucket_count());
362 pickle.WriteInt(histogram.histogram_type()); 399 pickle.WriteInt(histogram.histogram_type());
363 pickle.WriteInt(histogram.flags()); 400 pickle.WriteInt(histogram.flags() & ~kIPCSerializationSourceFlag);
364 401
365 snapshot.Serialize(&pickle); 402 snapshot.Serialize(&pickle);
366 return std::string(static_cast<const char*>(pickle.data()), pickle.size()); 403 return std::string(static_cast<const char*>(pickle.data()), pickle.size());
367 } 404 }
368 405
369 // static 406 // static
370 bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { 407 bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) {
371 if (histogram_info.empty()) { 408 if (histogram_info.empty()) {
372 return false; 409 return false;
373 } 410 }
(...skipping 13 matching lines...) Expand all
387 !pickle.ReadInt(&iter, &declared_min) || 424 !pickle.ReadInt(&iter, &declared_min) ||
388 !pickle.ReadInt(&iter, &declared_max) || 425 !pickle.ReadInt(&iter, &declared_max) ||
389 !pickle.ReadSize(&iter, &bucket_count) || 426 !pickle.ReadSize(&iter, &bucket_count) ||
390 !pickle.ReadInt(&iter, &histogram_type) || 427 !pickle.ReadInt(&iter, &histogram_type) ||
391 !pickle.ReadInt(&iter, &flags) || 428 !pickle.ReadInt(&iter, &flags) ||
392 !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) { 429 !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) {
393 LOG(ERROR) << "Picke error decoding Histogram: " << histogram_name; 430 LOG(ERROR) << "Picke error decoding Histogram: " << histogram_name;
394 return false; 431 return false;
395 } 432 }
396 433
397 Histogram* render_histogram = 434 DCHECK(histogram_type != NOT_VALID_IN_RENDERER);
398 StatisticsRecorder::GetHistogram(histogram_name);
399 435
400 if (render_histogram == NULL) { 436 scoped_refptr<Histogram> render_histogram(NULL);
401 if (histogram_type == EXPONENTIAL) { 437
402 render_histogram = new Histogram(histogram_name.c_str(), 438 if (histogram_type == HISTOGRAM) {
403 declared_min, 439 render_histogram = Histogram::HistogramFactoryGet(
404 declared_max, 440 histogram_name, declared_min, declared_max, bucket_count);
405 bucket_count); 441 } else if (histogram_type == LINEAR_HISTOGRAM) {
406 } else if (histogram_type == LINEAR) { 442 render_histogram = LinearHistogram::LinearHistogramFactoryGet(
407 render_histogram = new LinearHistogram(histogram_name.c_str(), 443 histogram_name, declared_min, declared_max, bucket_count);
408 declared_min, 444 } else if (histogram_type == BOOLEAN_HISTOGRAM) {
409 declared_max, 445 render_histogram = BooleanHistogram::BooleanHistogramFactoryGet(
410 bucket_count); 446 histogram_name);
411 } else { 447 } else if (histogram_type == THREAD_SAFE_HISTOGRAM) {
412 LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " << 448 render_histogram =
413 histogram_type; 449 ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(
414 return false; 450 histogram_name, declared_min, declared_max, bucket_count);
415 } 451 } else {
416 DCHECK(!(flags & kRendererHistogramFlag)); 452 LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " <<
417 render_histogram->SetFlags(flags | kRendererHistogramFlag); 453 histogram_type;
454 return false;
418 } 455 }
419 456
420 DCHECK(declared_min == render_histogram->declared_min()); 457 DCHECK(declared_min == render_histogram->declared_min());
421 DCHECK(declared_max == render_histogram->declared_max()); 458 DCHECK(declared_max == render_histogram->declared_max());
422 DCHECK(bucket_count == render_histogram->bucket_count()); 459 DCHECK(bucket_count == render_histogram->bucket_count());
423 DCHECK(histogram_type == render_histogram->histogram_type()); 460 DCHECK(histogram_type == render_histogram->histogram_type());
424 461
425 if (render_histogram->flags() & kRendererHistogramFlag) { 462 if (render_histogram->flags() & kIPCSerializationSourceFlag) {
463 DLOG(INFO) << "Single process mode, histogram observed and not copied: " <<
464 histogram_name;
465 } else {
426 render_histogram->AddSampleSet(sample); 466 render_histogram->AddSampleSet(sample);
427 } else {
428 DLOG(INFO) << "Single thread mode, histogram observed and not copied: " <<
429 histogram_name;
430 } 467 }
431 468
432 return true; 469 return true;
433 } 470 }
434 471
435
436 //------------------------------------------------------------------------------ 472 //------------------------------------------------------------------------------
437 // Methods for the Histogram::SampleSet class 473 // Methods for the Histogram::SampleSet class
438 //------------------------------------------------------------------------------ 474 //------------------------------------------------------------------------------
439 475
440 Histogram::SampleSet::SampleSet() 476 Histogram::SampleSet::SampleSet()
441 : counts_(), 477 : counts_(),
442 sum_(0), 478 sum_(0),
443 square_sum_(0) { 479 square_sum_(0) {
444 } 480 }
445 481
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 } 566 }
531 567
532 return true; 568 return true;
533 } 569 }
534 570
535 //------------------------------------------------------------------------------ 571 //------------------------------------------------------------------------------
536 // LinearHistogram: This histogram uses a traditional set of evenly spaced 572 // LinearHistogram: This histogram uses a traditional set of evenly spaced
537 // buckets. 573 // buckets.
538 //------------------------------------------------------------------------------ 574 //------------------------------------------------------------------------------
539 575
540 LinearHistogram::LinearHistogram(const char* name, Sample minimum, 576 scoped_refptr<Histogram> LinearHistogram::LinearHistogramFactoryGet(
577 const std::string& name, Sample minimum, Sample maximum,
578 size_t bucket_count) {
579 scoped_refptr<Histogram> histogram(NULL);
580
581 if (minimum <= 0)
582 minimum = 1;
583 if (maximum >= kSampleType_MAX)
584 maximum = kSampleType_MAX - 1;
585
586 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
587 DCHECK(histogram.get() != NULL);
588 } else {
589 histogram = new LinearHistogram(name, minimum, maximum, bucket_count);
590 scoped_refptr<Histogram> registered_histogram(NULL);
591 StatisticsRecorder::FindHistogram(name, &registered_histogram);
592 if (registered_histogram.get() != NULL &&
593 registered_histogram.get() != histogram.get())
594 histogram = registered_histogram;
595 }
596
597 DCHECK(LINEAR_HISTOGRAM == histogram->histogram_type());
598 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
599
600 return histogram;
601 }
602
603 scoped_refptr<Histogram> LinearHistogram::LinearHistogramFactoryGet(
604 const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum,
605 size_t bucket_count) {
606 return LinearHistogramFactoryGet(name, minimum.InMilliseconds(),
607 maximum.InMilliseconds(), bucket_count);
608 }
609
610 LinearHistogram::LinearHistogram(const std::string& name, Sample minimum,
541 Sample maximum, size_t bucket_count) 611 Sample maximum, size_t bucket_count)
542 : Histogram(name, minimum >= 1 ? minimum : 1, maximum, bucket_count) { 612 : Histogram(name, minimum >= 1 ? minimum : 1, maximum, bucket_count) {
543 InitializeBucketRange(); 613 InitializeBucketRange();
544 DCHECK(ValidateBucketRanges()); 614 DCHECK(ValidateBucketRanges());
545 } 615 }
546 616
547 LinearHistogram::LinearHistogram(const char* name, 617 LinearHistogram::LinearHistogram(const std::string& name,
548 TimeDelta minimum, TimeDelta maximum, size_t bucket_count) 618 TimeDelta minimum, TimeDelta maximum, size_t bucket_count)
549 : Histogram(name, minimum >= TimeDelta::FromMilliseconds(1) ? 619 : Histogram(name, minimum >= TimeDelta::FromMilliseconds(1) ?
550 minimum : TimeDelta::FromMilliseconds(1), 620 minimum : TimeDelta::FromMilliseconds(1),
551 maximum, bucket_count) { 621 maximum, bucket_count) {
552 // Do a "better" (different) job at init than a base classes did... 622 // Do a "better" (different) job at init than a base classes did...
553 InitializeBucketRange(); 623 InitializeBucketRange();
554 DCHECK(ValidateBucketRanges()); 624 DCHECK(ValidateBucketRanges());
555 } 625 }
556 626
557 void LinearHistogram::SetRangeDescriptions( 627 void LinearHistogram::SetRangeDescriptions(
(...skipping 30 matching lines...) Expand all
588 658
589 double LinearHistogram::GetBucketSize(Count current, size_t i) const { 659 double LinearHistogram::GetBucketSize(Count current, size_t i) const {
590 DCHECK(ranges(i + 1) > ranges(i)); 660 DCHECK(ranges(i + 1) > ranges(i));
591 // Adjacent buckets with different widths would have "surprisingly" many (few) 661 // Adjacent buckets with different widths would have "surprisingly" many (few)
592 // samples in a histogram if we didn't normalize this way. 662 // samples in a histogram if we didn't normalize this way.
593 double denominator = ranges(i + 1) - ranges(i); 663 double denominator = ranges(i + 1) - ranges(i);
594 return current/denominator; 664 return current/denominator;
595 } 665 }
596 666
597 //------------------------------------------------------------------------------ 667 //------------------------------------------------------------------------------
668 // This section provides implementation for BooleanHistogram.
669 //------------------------------------------------------------------------------
670
671 scoped_refptr<Histogram> BooleanHistogram::BooleanHistogramFactoryGet(
672 const std::string& name) {
673 scoped_refptr<Histogram> histogram(NULL);
674
675 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
676 DCHECK(histogram.get() != NULL);
677 } else {
678 histogram = new BooleanHistogram(name);
679 scoped_refptr<Histogram> registered_histogram(NULL);
680 StatisticsRecorder::FindHistogram(name, &registered_histogram);
681 if (registered_histogram.get() != NULL &&
682 registered_histogram.get() != histogram.get())
683 histogram = registered_histogram;
684 }
685
686 DCHECK(BOOLEAN_HISTOGRAM == histogram->histogram_type());
687
688 return histogram;
689 }
690
691 //------------------------------------------------------------------------------
598 // This section provides implementation for ThreadSafeHistogram. 692 // This section provides implementation for ThreadSafeHistogram.
599 //------------------------------------------------------------------------------ 693 //------------------------------------------------------------------------------
600 694
601 ThreadSafeHistogram::ThreadSafeHistogram(const char* name, Sample minimum, 695 scoped_refptr<Histogram> ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(
602 Sample maximum, size_t bucket_count) 696 const std::string& name, Sample minimum, Sample maximum,
697 size_t bucket_count) {
698 scoped_refptr<Histogram> histogram(NULL);
699
700 if (minimum <= 0)
701 minimum = 1;
702 if (maximum >= kSampleType_MAX)
703 maximum = kSampleType_MAX - 1;
704
705 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
706 DCHECK(histogram.get() != NULL);
707 } else {
708 histogram = new ThreadSafeHistogram(name, minimum, maximum, bucket_count);
709 scoped_refptr<Histogram> registered_histogram(NULL);
710 StatisticsRecorder::FindHistogram(name, &registered_histogram);
711 if (registered_histogram.get() != NULL &&
712 registered_histogram.get() != histogram.get())
713 histogram = registered_histogram;
714 }
715
716 DCHECK(THREAD_SAFE_HISTOGRAM == histogram->histogram_type());
717 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
718 return histogram;
719 }
720
721 ThreadSafeHistogram::ThreadSafeHistogram(const std::string& name,
722 Sample minimum, Sample maximum, size_t bucket_count)
603 : Histogram(name, minimum, maximum, bucket_count), 723 : Histogram(name, minimum, maximum, bucket_count),
604 lock_() { 724 lock_() {
605 } 725 }
606 726
607 void ThreadSafeHistogram::Remove(int value) { 727 void ThreadSafeHistogram::Remove(int value) {
608 if (value >= kSampleType_MAX) 728 if (value >= kSampleType_MAX)
609 value = kSampleType_MAX - 1; 729 value = kSampleType_MAX - 1;
610 size_t index = BucketIndex(value); 730 size_t index = BucketIndex(value);
611 Accumulate(value, -1, index); 731 Accumulate(value, -1, index);
612 } 732 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 histograms_ = NULL; 770 histograms_ = NULL;
651 delete lock_; 771 delete lock_;
652 lock_ = NULL; 772 lock_ = NULL;
653 } 773 }
654 774
655 // static 775 // static
656 bool StatisticsRecorder::WasStarted() { 776 bool StatisticsRecorder::WasStarted() {
657 return NULL != histograms_; 777 return NULL != histograms_;
658 } 778 }
659 779
780 // Note: We can't accept a ref_ptr to |histogram| because we *might* not keep a
781 // reference, and we are called while in the Histogram constructor. In that
782 // scenario, a ref_ptr would have incremented the ref count when the histogram
783 // was passed to us, decremented it when we returned, and the instance would be
784 // destroyed before assignment (when value was returned by new).
660 // static 785 // static
661 bool StatisticsRecorder::Register(Histogram* histogram) { 786 void StatisticsRecorder::Register(Histogram* histogram) {
662 if (!histograms_)
663 return false;
664 const std::string name = histogram->histogram_name();
665 AutoLock auto_lock(*lock_);
666
667 if (histograms_->end() != histograms_->find(name)) {
668 // Check to be sure it is compatible.... and if not, then do a CHECK()
669 return false; // This name is already registered.
670 }
671 (*histograms_)[name] = histogram;
672 return true;
673 }
674
675 // static
676 void StatisticsRecorder::UnRegister(Histogram* histogram) {
677 if (!histograms_) 787 if (!histograms_)
678 return; 788 return;
679 const std::string name = histogram->histogram_name(); 789 const std::string name = histogram->histogram_name();
680 AutoLock auto_lock(*lock_); 790 AutoLock auto_lock(*lock_);
681 DCHECK(histograms_->end() != histograms_->find(name)); 791
682 histograms_->erase(name); 792 DCHECK(histograms_->end() == histograms_->find(name));
683 if (dump_on_exit_) { 793
684 std::string output; 794 (*histograms_)[name] = histogram;
685 histogram->WriteAscii(true, "\n", &output); 795 return;
686 LOG(INFO) << output;
687 }
688 } 796 }
689 797
690 // static 798 // static
691 void StatisticsRecorder::WriteHTMLGraph(const std::string& query, 799 void StatisticsRecorder::WriteHTMLGraph(const std::string& query,
692 std::string* output) { 800 std::string* output) {
693 if (!histograms_) 801 if (!histograms_)
694 return; 802 return;
695 output->append("<html><head><title>About Histograms"); 803 output->append("<html><head><title>About Histograms");
696 if (!query.empty()) 804 if (!query.empty())
697 output->append(" - " + query); 805 output->append(" - " + query);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 if (!histograms_) 844 if (!histograms_)
737 return; 845 return;
738 AutoLock auto_lock(*lock_); 846 AutoLock auto_lock(*lock_);
739 for (HistogramMap::iterator it = histograms_->begin(); 847 for (HistogramMap::iterator it = histograms_->begin();
740 histograms_->end() != it; 848 histograms_->end() != it;
741 ++it) { 849 ++it) {
742 output->push_back(it->second); 850 output->push_back(it->second);
743 } 851 }
744 } 852 }
745 853
746 Histogram* StatisticsRecorder::GetHistogram(const std::string& query) { 854 // static
855 void StatisticsRecorder::GetHistogramsForRenderer(Histograms* output) {
747 if (!histograms_) 856 if (!histograms_)
748 return NULL; 857 return;
749 AutoLock auto_lock(*lock_); 858 AutoLock auto_lock(*lock_);
750 for (HistogramMap::iterator it = histograms_->begin(); 859 for (HistogramMap::iterator it = histograms_->begin();
751 histograms_->end() != it; 860 histograms_->end() != it;
752 ++it) { 861 ++it) {
753 if (it->first.find(query) != std::string::npos) 862 scoped_refptr<Histogram> histogram = it->second;
754 return it->second; 863 if (!(histogram->flags() & kIPCSerializationSourceFlag))
864 histogram->SetFlags(kIPCSerializationSourceFlag);
865 output->push_back(histogram);
755 } 866 }
756 return NULL; 867 }
868
869 bool StatisticsRecorder::FindHistogram(const std::string& name,
870 scoped_refptr<Histogram>* histogram) {
871 if (!histograms_)
872 return false;
873 AutoLock auto_lock(*lock_);
874 HistogramMap::iterator it = histograms_->find(name);
875 if (histograms_->end() == it)
876 return false;
877 *histogram = it->second;
878 return true;
757 } 879 }
758 880
759 // private static 881 // private static
760 void StatisticsRecorder::GetSnapshot(const std::string& query, 882 void StatisticsRecorder::GetSnapshot(const std::string& query,
761 Histograms* snapshot) { 883 Histograms* snapshot) {
762 AutoLock auto_lock(*lock_); 884 AutoLock auto_lock(*lock_);
763 for (HistogramMap::iterator it = histograms_->begin(); 885 for (HistogramMap::iterator it = histograms_->begin();
764 histograms_->end() != it; 886 histograms_->end() != it;
765 ++it) { 887 ++it) {
766 if (it->first.find(query) != std::string::npos) 888 if (it->first.find(query) != std::string::npos)
767 snapshot->push_back(it->second); 889 snapshot->push_back(it->second);
768 } 890 }
769 } 891 }
770 892
771 // static 893 // static
772 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 894 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
773 // static 895 // static
774 Lock* StatisticsRecorder::lock_ = NULL; 896 Lock* StatisticsRecorder::lock_ = NULL;
775 // static 897 // static
776 bool StatisticsRecorder::dump_on_exit_ = false; 898 bool StatisticsRecorder::dump_on_exit_ = false;
OLDNEW
« no previous file with comments | « base/histogram.h ('k') | base/histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698