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

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

Issue 1425533011: Support "shared" histograms between processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@shmem-alloc
Patch Set: extract common histogram FactoryGet code; extract histogram persistence into seperate files 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
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 // 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/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 11
12 #include <math.h> 12 #include <math.h>
13 13
14 #include <algorithm> 14 #include <algorithm>
15 #include <string> 15 #include <string>
16 16
17 #include "base/compiler_specific.h" 17 #include "base/compiler_specific.h"
18 #include "base/debug/alias.h" 18 #include "base/debug/alias.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/persistent_memory_allocator.h"
20 #include "base/metrics/histogram_macros.h" 21 #include "base/metrics/histogram_macros.h"
22 #include "base/metrics/histogram_persistence.h"
21 #include "base/metrics/metrics_hashes.h" 23 #include "base/metrics/metrics_hashes.h"
22 #include "base/metrics/sample_vector.h" 24 #include "base/metrics/sample_vector.h"
23 #include "base/metrics/statistics_recorder.h" 25 #include "base/metrics/statistics_recorder.h"
24 #include "base/pickle.h" 26 #include "base/pickle.h"
25 #include "base/strings/string_util.h" 27 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h" 28 #include "base/strings/stringprintf.h"
27 #include "base/synchronization/lock.h" 29 #include "base/synchronization/lock.h"
28 #include "base/values.h" 30 #include "base/values.h"
29 31
30 namespace base { 32 namespace base {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } 78 }
77 79
78 } // namespace 80 } // namespace
79 81
80 typedef HistogramBase::Count Count; 82 typedef HistogramBase::Count Count;
81 typedef HistogramBase::Sample Sample; 83 typedef HistogramBase::Sample Sample;
82 84
83 // static 85 // static
84 const size_t Histogram::kBucketCount_MAX = 16384u; 86 const size_t Histogram::kBucketCount_MAX = 16384u;
85 87
86 HistogramBase* Histogram::FactoryGet(const std::string& name, 88 // static
87 Sample minimum, 89 HistogramBase* Histogram::FactoryGet(
88 Sample maximum, 90 std::function<BucketRanges*()> create_ranges,
89 size_t bucket_count, 91 std::function<HistogramBase*(const BucketRanges*)> heap_alloc,
90 int32 flags) { 92 std::function<void(HistogramBase*)> fill_histogram,
91 bool valid_arguments = 93 HistogramType histogram_type,
92 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); 94 const std::string& name,
93 DCHECK(valid_arguments); 95 Sample minimum,
96 Sample maximum,
97 size_t bucket_count,
98 int32 flags) {
99 ImportPersistentHistograms();
94 100
95 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 101 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
96 if (!histogram) { 102 if (!histogram) {
97 // To avoid racy destruction at shutdown, the following will be leaked. 103 // To avoid racy destruction at shutdown, the following will be leaked.
98 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 104 const BucketRanges* created_ranges = create_ranges();
99 InitializeBucketRanges(minimum, maximum, ranges);
100 const BucketRanges* registered_ranges = 105 const BucketRanges* registered_ranges =
101 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 106 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges);
102 107
103 Histogram* tentative_histogram = 108 // Sometimes the bucket info is dynamically determined in create_ranges().
104 new Histogram(name, minimum, maximum, registered_ranges); 109 if (bucket_count == 0) {
110 bucket_count = registered_ranges->bucket_count();
111 minimum = registered_ranges->range(1);
112 maximum = registered_ranges->range(bucket_count - 1);
113 }
114
115 PersistentMemoryAllocator::Reference histogram_ref = 0;
116 HistogramBase* tentative_histogram = nullptr;
117 if (allocator_) {
118 flags |= kIsPersistent;
119 tentative_histogram = AllocatePersistentHistogram(
120 GetPersistentHistogramMemoryAllocator(),
121 histogram_type,
122 name,
123 minimum,
124 maximum,
125 registered_ranges,
126 flags,
127 &histogram_ref);
128 }
129 if (!tentative_histogram) {
130 flags &= ~kIsPersistent;
131 tentative_histogram = heap_alloc(registered_ranges);
132 }
133
134 fill_histogram(tentative_histogram);
105 135
106 tentative_histogram->SetFlags(flags); 136 tentative_histogram->SetFlags(flags);
107 histogram = 137 histogram =
108 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 138 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
139
140 // Persistent histograms need some follow-up processing.
141 if (histogram_ref) {
142 // If the created persistent histogram is canonical then it needs to be
143 // marked as "iterable" in order to be found by other processes.
144 if (histogram == tentative_histogram)
145 GetPersistentHistogramMemoryAllocator()->MakeIterable(histogram_ref);
146 // If it's not the canonical one then a race condition must have caused
147 // two to be created. The allocator does not support releasing the
148 // acquired memory so just change the type to be empty.
149 else
150 GetPersistentHistogramMemoryAllocator()->SetType(histogram_ref, 0);
151 }
109 } 152 }
110 153
111 DCHECK_EQ(HISTOGRAM, histogram->GetHistogramType()); 154 DCHECK_EQ(histogram_type, histogram->GetHistogramType());
112 if (!histogram->HasConstructionArguments(minimum, maximum, bucket_count)) { 155 if (bucket_count != 0 &&
156 !histogram->HasConstructionArguments(minimum, maximum, bucket_count)) {
113 // The construction arguments do not match the existing histogram. This can 157 // The construction arguments do not match the existing histogram. This can
114 // come about if an extension updates in the middle of a chrome run and has 158 // come about if an extension updates in the middle of a chrome run and has
115 // changed one of them, or simply by bad code within Chrome itself. We 159 // changed one of them, or simply by bad code within Chrome itself. We
116 // return NULL here with the expectation that bad code in Chrome will crash 160 // return NULL here with the expectation that bad code in Chrome will crash
117 // on dereference, but extension/Pepper APIs will guard against NULL and not 161 // on dereference, but extension/Pepper APIs will guard against NULL and not
118 // crash. 162 // crash.
119 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments"; 163 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments";
120 return NULL; 164 return NULL;
121 } 165 }
122 return histogram; 166 return histogram;
123 } 167 }
124 168
169 HistogramBase* Histogram::FactoryGet(const std::string& name,
170 Sample minimum,
171 Sample maximum,
172 size_t bucket_count,
173 int32 flags) {
174 bool valid_arguments =
175 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count);
176 DCHECK(valid_arguments);
177
178 return FactoryGet(
179 [=]()->BucketRanges* {
180 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
181 InitializeBucketRanges(minimum, maximum, ranges);
182 return ranges;
183 },
184 [=, &name](const BucketRanges* ranges)->HistogramBase* {
185 return new Histogram(name, minimum, maximum, ranges);
186 },
187 [=](HistogramBase* histogram) {},
188 HISTOGRAM, name, minimum, maximum, bucket_count, flags);
189 }
190
125 HistogramBase* Histogram::FactoryTimeGet(const std::string& name, 191 HistogramBase* Histogram::FactoryTimeGet(const std::string& name,
126 TimeDelta minimum, 192 TimeDelta minimum,
127 TimeDelta maximum, 193 TimeDelta maximum,
128 size_t bucket_count, 194 size_t bucket_count,
129 int32 flags) { 195 int32 flags) {
130 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()), 196 return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()),
131 static_cast<Sample>(maximum.InMilliseconds()), bucket_count, 197 static_cast<Sample>(maximum.InMilliseconds()), bucket_count,
132 flags); 198 flags);
133 } 199 }
134 200
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 Sample maximum, 402 Sample maximum,
337 const BucketRanges* ranges) 403 const BucketRanges* ranges)
338 : HistogramBase(name), 404 : HistogramBase(name),
339 bucket_ranges_(ranges), 405 bucket_ranges_(ranges),
340 declared_min_(minimum), 406 declared_min_(minimum),
341 declared_max_(maximum) { 407 declared_max_(maximum) {
342 if (ranges) 408 if (ranges)
343 samples_.reset(new SampleVector(HashMetricName(name), ranges)); 409 samples_.reset(new SampleVector(HashMetricName(name), ranges));
344 } 410 }
345 411
412 Histogram::Histogram(const std::string& name,
413 Sample minimum,
414 Sample maximum,
415 const BucketRanges* ranges,
416 HistogramBase::AtomicCount* counts,
417 size_t counts_size,
418 HistogramSamples::Metadata* meta)
419 : HistogramBase(name),
420 bucket_ranges_(ranges),
421 declared_min_(minimum),
422 declared_max_(maximum) {
423 if (ranges)
424 samples_.reset(new SampleVector(HashMetricName(name),
425 counts, counts_size, meta, ranges));
426 }
427
346 Histogram::~Histogram() { 428 Histogram::~Histogram() {
347 } 429 }
348 430
349 bool Histogram::PrintEmptyBucket(size_t index) const { 431 bool Histogram::PrintEmptyBucket(size_t index) const {
350 return true; 432 return true;
351 } 433 }
352 434
353 // Use the actual bucket widths (like a linear histogram) until the widths get 435 // Use the actual bucket widths (like a linear histogram) until the widths get
354 // over some transition value, and then use that transition width. Exponentials 436 // over some transition value, and then use that transition width. Exponentials
355 // get so big so fast (and we don't expect to see a lot of entries in the large 437 // get so big so fast (and we don't expect to see a lot of entries in the large
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 const std::string& name, 668 const std::string& name,
587 Sample minimum, 669 Sample minimum,
588 Sample maximum, 670 Sample maximum,
589 size_t bucket_count, 671 size_t bucket_count,
590 int32 flags, 672 int32 flags,
591 const DescriptionPair descriptions[]) { 673 const DescriptionPair descriptions[]) {
592 bool valid_arguments = Histogram::InspectConstructionArguments( 674 bool valid_arguments = Histogram::InspectConstructionArguments(
593 name, &minimum, &maximum, &bucket_count); 675 name, &minimum, &maximum, &bucket_count);
594 DCHECK(valid_arguments); 676 DCHECK(valid_arguments);
595 677
596 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 678 return Histogram::FactoryGet(
597 if (!histogram) { 679 [=]()->BucketRanges* {
598 // To avoid racy destruction at shutdown, the following will be leaked. 680 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
599 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 681 InitializeBucketRanges(minimum, maximum, ranges);
600 InitializeBucketRanges(minimum, maximum, ranges); 682 return ranges;
601 const BucketRanges* registered_ranges = 683 },
602 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 684 [=, &name](const BucketRanges* ranges)->HistogramBase* {
603 685 return new LinearHistogram(name, minimum, maximum, ranges);
604 LinearHistogram* tentative_histogram = 686 },
605 new LinearHistogram(name, minimum, maximum, registered_ranges); 687 [=](HistogramBase* base) {
606 688 LinearHistogram* histogram = static_cast<LinearHistogram*>(base);
607 // Set range descriptions. 689 // Set range descriptions.
608 if (descriptions) { 690 if (descriptions) {
609 for (int i = 0; descriptions[i].description; ++i) { 691 for (int i = 0; descriptions[i].description; ++i) {
610 tentative_histogram->bucket_description_[descriptions[i].sample] = 692 histogram->bucket_description_[descriptions[i].sample] =
611 descriptions[i].description; 693 descriptions[i].description;
694 }
612 } 695 }
613 } 696 },
614 697 LINEAR_HISTOGRAM, name, minimum, maximum, bucket_count, flags);
615 tentative_histogram->SetFlags(flags);
616 histogram =
617 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
618 }
619
620 DCHECK_EQ(LINEAR_HISTOGRAM, histogram->GetHistogramType());
621 if (!histogram->HasConstructionArguments(minimum, maximum, bucket_count)) {
622 // The construction arguments do not match the existing histogram. This can
623 // come about if an extension updates in the middle of a chrome run and has
624 // changed one of them, or simply by bad code within Chrome itself. We
625 // return NULL here with the expectation that bad code in Chrome will crash
626 // on dereference, but extension/Pepper APIs will guard against NULL and not
627 // crash.
628 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments";
629 return NULL;
630 }
631 return histogram;
632 } 698 }
633 699
634 HistogramType LinearHistogram::GetHistogramType() const { 700 HistogramType LinearHistogram::GetHistogramType() const {
635 return LINEAR_HISTOGRAM; 701 return LINEAR_HISTOGRAM;
636 } 702 }
637 703
638 LinearHistogram::LinearHistogram(const std::string& name, 704 LinearHistogram::LinearHistogram(const std::string& name,
639 Sample minimum, 705 Sample minimum,
640 Sample maximum, 706 Sample maximum,
641 const BucketRanges* ranges) 707 const BucketRanges* ranges)
642 : Histogram(name, minimum, maximum, ranges) { 708 : Histogram(name, minimum, maximum, ranges) {
643 } 709 }
644 710
711 LinearHistogram::LinearHistogram(const std::string& name,
712 Sample minimum,
713 Sample maximum,
714 const BucketRanges* ranges,
715 HistogramBase::AtomicCount* counts,
716 size_t counts_size,
717 HistogramSamples::Metadata* meta)
718 : Histogram(name,
719 minimum,
720 maximum,
721 ranges,
722 counts,
723 counts_size,
724 meta) {}
725
645 double LinearHistogram::GetBucketSize(Count current, size_t i) const { 726 double LinearHistogram::GetBucketSize(Count current, size_t i) const {
646 DCHECK_GT(ranges(i + 1), ranges(i)); 727 DCHECK_GT(ranges(i + 1), ranges(i));
647 // Adjacent buckets with different widths would have "surprisingly" many (few) 728 // Adjacent buckets with different widths would have "surprisingly" many (few)
648 // samples in a histogram if we didn't normalize this way. 729 // samples in a histogram if we didn't normalize this way.
649 double denominator = ranges(i + 1) - ranges(i); 730 double denominator = ranges(i + 1) - ranges(i);
650 return current/denominator; 731 return current/denominator;
651 } 732 }
652 733
653 const std::string LinearHistogram::GetAsciiBucketRange(size_t i) const { 734 const std::string LinearHistogram::GetAsciiBucketRange(size_t i) const {
654 int range = ranges(i); 735 int range = ranges(i);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 } 781 }
701 return histogram; 782 return histogram;
702 } 783 }
703 784
704 //------------------------------------------------------------------------------ 785 //------------------------------------------------------------------------------
705 // This section provides implementation for BooleanHistogram. 786 // This section provides implementation for BooleanHistogram.
706 //------------------------------------------------------------------------------ 787 //------------------------------------------------------------------------------
707 788
708 HistogramBase* BooleanHistogram::FactoryGet(const std::string& name, 789 HistogramBase* BooleanHistogram::FactoryGet(const std::string& name,
709 int32 flags) { 790 int32 flags) {
710 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 791 return Histogram::FactoryGet(
711 if (!histogram) { 792 [=]()->BucketRanges* {
712 // To avoid racy destruction at shutdown, the following will be leaked. 793 BucketRanges* ranges = new BucketRanges(3 + 1);
713 BucketRanges* ranges = new BucketRanges(4); 794 LinearHistogram::InitializeBucketRanges(1, 2, ranges);
714 LinearHistogram::InitializeBucketRanges(1, 2, ranges); 795 return ranges;
715 const BucketRanges* registered_ranges = 796 },
716 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 797 [=, &name](const BucketRanges* ranges)->HistogramBase* {
717 798 return new BooleanHistogram(name, ranges);
718 BooleanHistogram* tentative_histogram = 799 },
719 new BooleanHistogram(name, registered_ranges); 800 [=](HistogramBase* histogram) {},
720 801 BOOLEAN_HISTOGRAM, name, 1, 2, 3, flags);
721 tentative_histogram->SetFlags(flags);
722 histogram =
723 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
724 }
725
726 DCHECK_EQ(BOOLEAN_HISTOGRAM, histogram->GetHistogramType());
727 return histogram;
728 } 802 }
729 803
730 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32 flags) { 804 HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32 flags) {
731 return FactoryGet(std::string(name), flags); 805 return FactoryGet(std::string(name), flags);
732 } 806 }
733 807
734 HistogramType BooleanHistogram::GetHistogramType() const { 808 HistogramType BooleanHistogram::GetHistogramType() const {
735 return BOOLEAN_HISTOGRAM; 809 return BOOLEAN_HISTOGRAM;
736 } 810 }
737 811
738 BooleanHistogram::BooleanHistogram(const std::string& name, 812 BooleanHistogram::BooleanHistogram(const std::string& name,
739 const BucketRanges* ranges) 813 const BucketRanges* ranges)
740 : LinearHistogram(name, 1, 2, ranges) {} 814 : LinearHistogram(name, 1, 2, ranges) {}
741 815
816 BooleanHistogram::BooleanHistogram(const std::string& name,
817 const BucketRanges* ranges,
818 HistogramBase::AtomicCount* counts,
819 HistogramSamples::Metadata* meta)
820 : LinearHistogram(name, 1, 2, ranges, counts, 2, meta) {}
821
742 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) { 822 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
743 std::string histogram_name; 823 std::string histogram_name;
744 int flags; 824 int flags;
745 int declared_min; 825 int declared_min;
746 int declared_max; 826 int declared_max;
747 size_t bucket_count; 827 size_t bucket_count;
748 uint32 range_checksum; 828 uint32 range_checksum;
749 829
750 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min, 830 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
751 &declared_max, &bucket_count, &range_checksum)) { 831 &declared_max, &bucket_count, &range_checksum)) {
(...skipping 12 matching lines...) Expand all
764 //------------------------------------------------------------------------------ 844 //------------------------------------------------------------------------------
765 // CustomHistogram: 845 // CustomHistogram:
766 //------------------------------------------------------------------------------ 846 //------------------------------------------------------------------------------
767 847
768 HistogramBase* CustomHistogram::FactoryGet( 848 HistogramBase* CustomHistogram::FactoryGet(
769 const std::string& name, 849 const std::string& name,
770 const std::vector<Sample>& custom_ranges, 850 const std::vector<Sample>& custom_ranges,
771 int32 flags) { 851 int32 flags) {
772 CHECK(ValidateCustomRanges(custom_ranges)); 852 CHECK(ValidateCustomRanges(custom_ranges));
773 853
774 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 854 return Histogram::FactoryGet(
775 if (!histogram) { 855 [&]()->BucketRanges* {
776 BucketRanges* ranges = CreateBucketRangesFromCustomRanges(custom_ranges); 856 // Remove the duplicates in the custom ranges array.
777 const BucketRanges* registered_ranges = 857 std::vector<int> ranges = custom_ranges;
778 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 858 ranges.push_back(0); // Ensure we have a zero value.
859 ranges.push_back(HistogramBase::kSampleType_MAX);
860 std::sort(ranges.begin(), ranges.end());
861 ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end());
779 862
780 // To avoid racy destruction at shutdown, the following will be leaked. 863 BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
781 CustomHistogram* tentative_histogram = 864 for (size_t i = 0; i < ranges.size(); i++) {
782 new CustomHistogram(name, registered_ranges); 865 bucket_ranges->set_range(i, ranges[i]);
783 866 }
784 tentative_histogram->SetFlags(flags); 867 bucket_ranges->ResetChecksum();
785 868 return bucket_ranges;
786 histogram = 869 },
787 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 870 [=, &name](const BucketRanges* ranges)->HistogramBase* {
788 } 871 return new CustomHistogram(name, ranges);
789 872 },
790 DCHECK_EQ(histogram->GetHistogramType(), CUSTOM_HISTOGRAM); 873 [=](HistogramBase* histogram) {},
791 return histogram; 874 CUSTOM_HISTOGRAM, name, 0, 0, 0, flags);
792 } 875 }
793 876
794 HistogramBase* CustomHistogram::FactoryGet( 877 HistogramBase* CustomHistogram::FactoryGet(
795 const char* name, 878 const char* name,
796 const std::vector<Sample>& custom_ranges, 879 const std::vector<Sample>& custom_ranges,
797 int32 flags) { 880 int32 flags) {
798 return FactoryGet(std::string(name), custom_ranges, flags); 881 return FactoryGet(std::string(name), custom_ranges, flags);
799 } 882 }
800 883
801 HistogramType CustomHistogram::GetHistogramType() const { 884 HistogramType CustomHistogram::GetHistogramType() const {
(...skipping 15 matching lines...) Expand all
817 return all_values; 900 return all_values;
818 } 901 }
819 902
820 CustomHistogram::CustomHistogram(const std::string& name, 903 CustomHistogram::CustomHistogram(const std::string& name,
821 const BucketRanges* ranges) 904 const BucketRanges* ranges)
822 : Histogram(name, 905 : Histogram(name,
823 ranges->range(1), 906 ranges->range(1),
824 ranges->range(ranges->bucket_count() - 1), 907 ranges->range(ranges->bucket_count() - 1),
825 ranges) {} 908 ranges) {}
826 909
910 CustomHistogram::CustomHistogram(const std::string& name,
911 const BucketRanges* ranges,
912 HistogramBase::AtomicCount* counts,
913 size_t counts_size,
914 HistogramSamples::Metadata* meta)
915 : Histogram(name,
916 ranges->range(1),
917 ranges->range(ranges->bucket_count() - 1),
918 ranges,
919 counts,
920 counts_size,
921 meta) {}
922
827 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const { 923 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
828 if (!Histogram::SerializeInfoImpl(pickle)) 924 if (!Histogram::SerializeInfoImpl(pickle))
829 return false; 925 return false;
830 926
831 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't 927 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't
832 // write them. 928 // write them.
833 for (size_t i = 1; i < bucket_ranges()->bucket_count(); ++i) { 929 for (size_t i = 1; i < bucket_ranges()->bucket_count(); ++i) {
834 if (!pickle->WriteInt(bucket_ranges()->range(i))) 930 if (!pickle->WriteInt(bucket_ranges()->range(i)))
835 return false; 931 return false;
836 } 932 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 for (size_t i = 0; i < custom_ranges.size(); i++) { 975 for (size_t i = 0; i < custom_ranges.size(); i++) {
880 Sample sample = custom_ranges[i]; 976 Sample sample = custom_ranges[i];
881 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) 977 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
882 return false; 978 return false;
883 if (sample != 0) 979 if (sample != 0)
884 has_valid_range = true; 980 has_valid_range = true;
885 } 981 }
886 return has_valid_range; 982 return has_valid_range;
887 } 983 }
888 984
889 // static
890 BucketRanges* CustomHistogram::CreateBucketRangesFromCustomRanges(
891 const std::vector<Sample>& custom_ranges) {
892 // Remove the duplicates in the custom ranges array.
893 std::vector<int> ranges = custom_ranges;
894 ranges.push_back(0); // Ensure we have a zero value.
895 ranges.push_back(HistogramBase::kSampleType_MAX);
896 std::sort(ranges.begin(), ranges.end());
897 ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end());
898
899 BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
900 for (size_t i = 0; i < ranges.size(); i++) {
901 bucket_ranges->set_range(i, ranges[i]);
902 }
903 bucket_ranges->ResetChecksum();
904 return bucket_ranges;
905 }
906
907 } // namespace base 985 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698