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

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

Issue 11682003: Serialize/Deserialize support in HistogramBase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Some changes about deserializing Created 7 years, 11 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 | Annotate | Revision Log
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"
(...skipping 12 matching lines...) Expand all
23 #include "base/string_util.h" 23 #include "base/string_util.h"
24 #include "base/stringprintf.h" 24 #include "base/stringprintf.h"
25 #include "base/synchronization/lock.h" 25 #include "base/synchronization/lock.h"
26 #include "base/values.h" 26 #include "base/values.h"
27 27
28 using std::string; 28 using std::string;
29 using std::vector; 29 using std::vector;
30 30
31 namespace base { 31 namespace base {
32 32
33 namespace {
34
35 bool ReadHistogramArguments(PickleIterator* iter,
36 string* histogram_name,
37 int* flags,
38 int* declared_min,
39 int* declared_max,
40 uint64* bucket_count,
41 uint32* range_checksum) {
42 if (!iter->ReadString(histogram_name) ||
43 !iter->ReadInt(flags) ||
44 !iter->ReadInt(declared_min) ||
45 !iter->ReadInt(declared_max) ||
46 !iter->ReadUInt64(bucket_count) ||
47 !iter->ReadUInt32(range_checksum)) {
48 DLOG(ERROR) << "Pickle error decoding Histogram: " << *histogram_name;
49 return false;
50 }
51
52 // Since these fields may have come from an untrusted renderer, do additional
53 // checks above and beyond those in Histogram::Initialize()
54 if (*declared_max <= 0 ||
55 *declared_min <= 0 ||
56 *declared_max < *declared_min ||
57 INT_MAX / sizeof(HistogramBase::Count) <= *bucket_count ||
58 *bucket_count < 2) {
59 DLOG(ERROR) << "Values error decoding Histogram: " << histogram_name;
60 return false;
61 }
62
63 // We use the arguments to find or create the local version of the histogram
64 // in this process. So we need to clear the IPC flag.
Ilya Sherman 2013/01/09 05:48:37 nit: "process. So" -> "process, so"
kaiwang 2013/01/10 23:02:24 Done.
65 DCHECK(*flags & HistogramBase::kIPCSerializationSourceFlag);
66 *flags &= ~HistogramBase::kIPCSerializationSourceFlag;
67
68 return true;
69 }
70
71 bool ValidateRangeChecksum(const HistogramBase& histogram,
72 uint32 range_checksum) {
73 const Histogram& casted_histogram =
74 static_cast<const Histogram&>(histogram);
75
76 return casted_histogram.bucket_ranges()->checksum() == range_checksum;
77 }
78
79 } // namespace
80
33 typedef HistogramBase::Count Count; 81 typedef HistogramBase::Count Count;
34 typedef HistogramBase::Sample Sample; 82 typedef HistogramBase::Sample Sample;
35 83
36 // static 84 // static
37 const size_t Histogram::kBucketCount_MAX = 16384u; 85 const size_t Histogram::kBucketCount_MAX = 16384u;
38 86
39 // TODO(rtenneti): delete this code after debugging. 87 // TODO(rtenneti): delete this code after debugging.
40 void CheckCorruption(const Histogram& histogram, bool new_histogram) { 88 void CheckCorruption(const Histogram& histogram, bool new_histogram) {
41 const std::string& histogram_name = histogram.histogram_name(); 89 const std::string& histogram_name = histogram.histogram_name();
42 char histogram_name_buf[128]; 90 char histogram_name_buf[128];
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 ranges->set_range(bucket_index, current); 194 ranges->set_range(bucket_index, current);
147 } 195 }
148 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); 196 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX);
149 ranges->ResetChecksum(); 197 ranges->ResetChecksum();
150 } 198 }
151 199
152 void Histogram::AddBoolean(bool value) { 200 void Histogram::AddBoolean(bool value) {
153 DCHECK(false); 201 DCHECK(false);
154 } 202 }
155 203
156 void Histogram::AddSamples(const HistogramSamples& samples) {
157 samples_->Add(samples);
158 }
159
160 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) {
161 return samples_->AddFromPickle(iter);
162 }
163
164 // static
165 string Histogram::SerializeHistogramInfo(const Histogram& histogram,
166 const HistogramSamples& snapshot) {
167 DCHECK(histogram.bucket_ranges()->HasValidChecksum());
168
169 Pickle pickle;
170 pickle.WriteString(histogram.histogram_name());
171 pickle.WriteInt(histogram.declared_min());
172 pickle.WriteInt(histogram.declared_max());
173 pickle.WriteUInt64(histogram.bucket_count());
174 pickle.WriteUInt32(histogram.bucket_ranges()->checksum());
175 pickle.WriteInt(histogram.GetHistogramType());
176 pickle.WriteInt(histogram.flags());
177
178 histogram.SerializeRanges(&pickle);
179
180 snapshot.Serialize(&pickle);
181
182 return string(static_cast<const char*>(pickle.data()), pickle.size());
183 }
184
185 // static
186 bool Histogram::DeserializeHistogramInfo(const string& histogram_info) {
187 if (histogram_info.empty()) {
188 return false;
189 }
190
191 Pickle pickle(histogram_info.data(),
192 static_cast<int>(histogram_info.size()));
193 string histogram_name;
194 int declared_min;
195 int declared_max;
196 uint64 bucket_count;
197 uint32 range_checksum;
198 int histogram_type;
199 int pickle_flags;
200
201 PickleIterator iter(pickle);
202 if (!iter.ReadString(&histogram_name) ||
203 !iter.ReadInt(&declared_min) ||
204 !iter.ReadInt(&declared_max) ||
205 !iter.ReadUInt64(&bucket_count) ||
206 !iter.ReadUInt32(&range_checksum) ||
207 !iter.ReadInt(&histogram_type) ||
208 !iter.ReadInt(&pickle_flags)) {
209 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name;
210 return false;
211 }
212
213 DCHECK(pickle_flags & kIPCSerializationSourceFlag);
214 // Since these fields may have come from an untrusted renderer, do additional
215 // checks above and beyond those in Histogram::Initialize()
216 if (declared_max <= 0 || declared_min <= 0 || declared_max < declared_min ||
217 INT_MAX / sizeof(Count) <= bucket_count || bucket_count < 2) {
218 DLOG(ERROR) << "Values error decoding Histogram: " << histogram_name;
219 return false;
220 }
221
222 Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag);
223
224 Histogram* render_histogram(NULL);
225
226 if (histogram_type == HISTOGRAM) {
227 render_histogram = Histogram::FactoryGet(
228 histogram_name, declared_min, declared_max, bucket_count, flags);
229 } else if (histogram_type == LINEAR_HISTOGRAM) {
230 render_histogram = LinearHistogram::FactoryGet(
231 histogram_name, declared_min, declared_max, bucket_count, flags);
232 } else if (histogram_type == BOOLEAN_HISTOGRAM) {
233 render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags);
234 } else if (histogram_type == CUSTOM_HISTOGRAM) {
235 vector<Sample> sample_ranges(bucket_count);
236 if (!CustomHistogram::DeserializeRanges(&iter, &sample_ranges)) {
237 DLOG(ERROR) << "Pickle error decoding ranges: " << histogram_name;
238 return false;
239 }
240 render_histogram =
241 CustomHistogram::FactoryGet(histogram_name, sample_ranges, flags);
242 } else {
243 DLOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: "
244 << histogram_type;
245 return false;
246 }
247
248 DCHECK_EQ(render_histogram->declared_min(), declared_min);
249 DCHECK_EQ(render_histogram->declared_max(), declared_max);
250 DCHECK_EQ(render_histogram->bucket_count(), bucket_count);
251 DCHECK_EQ(render_histogram->GetHistogramType(), histogram_type);
252
253 if (render_histogram->bucket_ranges()->checksum() != range_checksum) {
254 return false;
255 }
256
257 if (render_histogram->flags() & kIPCSerializationSourceFlag) {
258 DVLOG(1) << "Single process mode, histogram observed and not copied: "
259 << histogram_name;
260 return true;
261 }
262
263 DCHECK_EQ(flags & render_histogram->flags(), flags);
264 return render_histogram->AddSamplesFromPickle(&iter);
265 }
266
267 // static 204 // static
268 const int Histogram::kCommonRaceBasedCountMismatch = 5; 205 const int Histogram::kCommonRaceBasedCountMismatch = 5;
269 206
270 Histogram::Inconsistencies Histogram::FindCorruption( 207 Histogram::Inconsistencies Histogram::FindCorruption(
271 const HistogramSamples& samples) const { 208 const HistogramSamples& samples) const {
272 int inconsistencies = NO_INCONSISTENCIES; 209 int inconsistencies = NO_INCONSISTENCIES;
273 Sample previous_range = -1; // Bottom range is always 0. 210 Sample previous_range = -1; // Bottom range is always 0.
274 for (size_t index = 0; index < bucket_count(); ++index) { 211 for (size_t index = 0; index < bucket_count(); ++index) {
275 int new_range = ranges(index); 212 int new_range = ranges(index);
276 if (previous_range >= new_range) 213 if (previous_range >= new_range)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 value = kSampleType_MAX - 1; 293 value = kSampleType_MAX - 1;
357 if (value < 0) 294 if (value < 0)
358 value = 0; 295 value = 0;
359 samples_->Accumulate(value, 1); 296 samples_->Accumulate(value, 1);
360 } 297 }
361 298
362 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { 299 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const {
363 return SnapshotSampleVector().PassAs<HistogramSamples>(); 300 return SnapshotSampleVector().PassAs<HistogramSamples>();
364 } 301 }
365 302
303 void Histogram::AddSamples(const HistogramSamples& samples) {
304 samples_->Add(samples);
305 }
306
307 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) {
308 return samples_->AddFromPickle(iter);
309 }
310
366 // The following methods provide a graphical histogram display. 311 // The following methods provide a graphical histogram display.
367 void Histogram::WriteHTMLGraph(string* output) const { 312 void Histogram::WriteHTMLGraph(string* output) const {
368 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. 313 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc.
369 output->append("<PRE>"); 314 output->append("<PRE>");
370 WriteAsciiImpl(true, "<br>", output); 315 WriteAsciiImpl(true, "<br>", output);
371 output->append("</PRE>"); 316 output->append("</PRE>");
372 } 317 }
373 318
374 void Histogram::WriteAscii(string* output) const { 319 void Histogram::WriteAscii(string* output) const {
375 WriteAsciiImpl(true, "\n", output); 320 WriteAsciiImpl(true, "\n", output);
376 } 321 }
377 322
323 bool Histogram::SerializeInfoImpl(Pickle* pickle) const {
324 DCHECK(bucket_ranges()->HasValidChecksum());
325 return pickle->WriteString(histogram_name()) &&
326 pickle->WriteInt(flags()) &&
327 pickle->WriteInt(declared_min()) &&
328 pickle->WriteInt(declared_max()) &&
329 pickle->WriteUInt64(bucket_count()) &&
330 pickle->WriteUInt32(bucket_ranges()->checksum());
331 }
332
378 Histogram::Histogram(const string& name, 333 Histogram::Histogram(const string& name,
379 Sample minimum, 334 Sample minimum,
380 Sample maximum, 335 Sample maximum,
381 size_t bucket_count, 336 size_t bucket_count,
382 const BucketRanges* ranges) 337 const BucketRanges* ranges)
383 : HistogramBase(name), 338 : HistogramBase(name),
384 bucket_ranges_(ranges), 339 bucket_ranges_(ranges),
385 declared_min_(minimum), 340 declared_min_(minimum),
386 declared_max_(maximum), 341 declared_max_(maximum),
387 bucket_count_(bucket_count) { 342 bucket_count_(bucket_count) {
388 if (ranges) 343 if (ranges)
389 samples_.reset(new SampleVector(ranges)); 344 samples_.reset(new SampleVector(ranges));
390 } 345 }
391 346
392 Histogram::~Histogram() { 347 Histogram::~Histogram() {
393 if (StatisticsRecorder::dump_on_exit()) { 348 if (StatisticsRecorder::dump_on_exit()) {
394 string output; 349 string output;
395 WriteAsciiImpl(true, "\n", &output); 350 WriteAsciiImpl(true, "\n", &output);
396 DLOG(INFO) << output; 351 DLOG(INFO) << output;
397 } 352 }
398 } 353 }
399 354
400 bool Histogram::SerializeRanges(Pickle* pickle) const {
401 return true;
402 }
403
404 bool Histogram::PrintEmptyBucket(size_t index) const { 355 bool Histogram::PrintEmptyBucket(size_t index) const {
405 return true; 356 return true;
406 } 357 }
407 358
408 // Use the actual bucket widths (like a linear histogram) until the widths get 359 // Use the actual bucket widths (like a linear histogram) until the widths get
409 // over some transition value, and then use that transition width. Exponentials 360 // over some transition value, and then use that transition width. Exponentials
410 // get so big so fast (and we don't expect to see a lot of entries in the large 361 // get so big so fast (and we don't expect to see a lot of entries in the large
411 // buckets), so we need this to make it possible to see what is going on and 362 // buckets), so we need this to make it possible to see what is going on and
412 // not have 0-graphical-height buckets. 363 // not have 0-graphical-height buckets.
413 double Histogram::GetBucketSize(Count current, size_t i) const { 364 double Histogram::GetBucketSize(Count current, size_t i) const {
(...skipping 10 matching lines...) Expand all
424 if (kHexRangePrintingFlag & flags()) 375 if (kHexRangePrintingFlag & flags())
425 StringAppendF(&result, "%#x", ranges(i)); 376 StringAppendF(&result, "%#x", ranges(i));
426 else 377 else
427 StringAppendF(&result, "%d", ranges(i)); 378 StringAppendF(&result, "%d", ranges(i));
428 return result; 379 return result;
429 } 380 }
430 381
431 //------------------------------------------------------------------------------ 382 //------------------------------------------------------------------------------
432 // Private methods 383 // Private methods
433 384
385 // static
386 HistogramBase* Histogram::DeserializeInfoImpl(PickleIterator* iter) {
387 string histogram_name;
388 int flags;
389 int declared_min;
390 int declared_max;
391 uint64 bucket_count;
392 uint32 range_checksum;
393
394 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
395 &declared_max, &bucket_count, &range_checksum)) {
396 return NULL;
397 }
398
399 // Find or create the local version of the histogram in this process.
400 HistogramBase* histogram = Histogram::FactoryGet(
401 histogram_name, declared_min, declared_max, bucket_count, flags);
402
403 if (!ValidateRangeChecksum(*histogram, range_checksum)) {
404 // The serialized histogram might be corrupted.
405 return NULL;
406 }
407 return histogram;
408 }
409
434 scoped_ptr<SampleVector> Histogram::SnapshotSampleVector() const { 410 scoped_ptr<SampleVector> Histogram::SnapshotSampleVector() const {
435 scoped_ptr<SampleVector> samples(new SampleVector(bucket_ranges())); 411 scoped_ptr<SampleVector> samples(new SampleVector(bucket_ranges()));
436 samples->Add(*samples_); 412 samples->Add(*samples_);
437 return samples.Pass(); 413 return samples.Pass();
438 } 414 }
439 415
440 void Histogram::WriteAsciiImpl(bool graph_it, 416 void Histogram::WriteAsciiImpl(bool graph_it,
441 const string& newline, 417 const string& newline,
442 string* output) const { 418 string* output) const {
443 // Get local (stack) copies of all effectively volatile class data so that we 419 // Get local (stack) copies of all effectively volatile class data so that we
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 size_t i; 679 size_t i;
704 for (i = 1; i < bucket_count; ++i) { 680 for (i = 1; i < bucket_count; ++i) {
705 double linear_range = 681 double linear_range =
706 (min * (bucket_count -1 - i) + max * (i - 1)) / (bucket_count - 2); 682 (min * (bucket_count -1 - i) + max * (i - 1)) / (bucket_count - 2);
707 ranges->set_range(i, static_cast<Sample>(linear_range + 0.5)); 683 ranges->set_range(i, static_cast<Sample>(linear_range + 0.5));
708 } 684 }
709 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); 685 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX);
710 ranges->ResetChecksum(); 686 ranges->ResetChecksum();
711 } 687 }
712 688
689 // static
690 HistogramBase* LinearHistogram::DeserializeInfoImpl(PickleIterator* iter) {
691 string histogram_name;
692 int flags;
693 int declared_min;
694 int declared_max;
695 uint64 bucket_count;
696 uint32 range_checksum;
697
698 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
699 &declared_max, &bucket_count, &range_checksum)) {
700 return NULL;
701 }
702
703 HistogramBase* histogram = LinearHistogram::FactoryGet(
704 histogram_name, declared_min, declared_max, bucket_count, flags);
705 if (!ValidateRangeChecksum(*histogram, range_checksum)) {
706 // The serialized histogram might be corrupted.
707 return NULL;
708 }
709 return histogram;
710 }
711
713 //------------------------------------------------------------------------------ 712 //------------------------------------------------------------------------------
714 // This section provides implementation for BooleanHistogram. 713 // This section provides implementation for BooleanHistogram.
715 //------------------------------------------------------------------------------ 714 //------------------------------------------------------------------------------
716 715
717 Histogram* BooleanHistogram::FactoryGet(const string& name, int32 flags) { 716 Histogram* BooleanHistogram::FactoryGet(const string& name, int32 flags) {
718 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 717 Histogram* histogram = StatisticsRecorder::FindHistogram(name);
719 if (!histogram) { 718 if (!histogram) {
720 // To avoid racy destruction at shutdown, the following will be leaked. 719 // To avoid racy destruction at shutdown, the following will be leaked.
721 BucketRanges* ranges = new BucketRanges(4); 720 BucketRanges* ranges = new BucketRanges(4);
722 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges); 721 LinearHistogram::InitializeBucketRanges(1, 2, 3, ranges);
(...skipping 20 matching lines...) Expand all
743 } 742 }
744 743
745 void BooleanHistogram::AddBoolean(bool value) { 744 void BooleanHistogram::AddBoolean(bool value) {
746 Add(value ? 1 : 0); 745 Add(value ? 1 : 0);
747 } 746 }
748 747
749 BooleanHistogram::BooleanHistogram(const string& name, 748 BooleanHistogram::BooleanHistogram(const string& name,
750 const BucketRanges* ranges) 749 const BucketRanges* ranges)
751 : LinearHistogram(name, 1, 2, 3, ranges) {} 750 : LinearHistogram(name, 1, 2, 3, ranges) {}
752 751
752 HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
753 string histogram_name;
754 int flags;
755 int declared_min;
756 int declared_max;
757 uint64 bucket_count;
758 uint32 range_checksum;
759
760 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
761 &declared_max, &bucket_count, &range_checksum)) {
762 return NULL;
763 }
764
765 HistogramBase* histogram = BooleanHistogram::FactoryGet(
766 histogram_name, flags);
767 if (!ValidateRangeChecksum(*histogram, range_checksum)) {
768 // The serialized histogram might be corrupted.
769 return NULL;
770 }
771 return histogram;
772 }
773
753 //------------------------------------------------------------------------------ 774 //------------------------------------------------------------------------------
754 // CustomHistogram: 775 // CustomHistogram:
755 //------------------------------------------------------------------------------ 776 //------------------------------------------------------------------------------
756 777
757 Histogram* CustomHistogram::FactoryGet(const string& name, 778 Histogram* CustomHistogram::FactoryGet(const string& name,
758 const vector<Sample>& custom_ranges, 779 const vector<Sample>& custom_ranges,
759 int32 flags) { 780 int32 flags) {
760 CHECK(ValidateCustomRanges(custom_ranges)); 781 CHECK(ValidateCustomRanges(custom_ranges));
761 782
762 Histogram* histogram = StatisticsRecorder::FindHistogram(name); 783 Histogram* histogram = StatisticsRecorder::FindHistogram(name);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 } 823 }
803 824
804 CustomHistogram::CustomHistogram(const string& name, 825 CustomHistogram::CustomHistogram(const string& name,
805 const BucketRanges* ranges) 826 const BucketRanges* ranges)
806 : Histogram(name, 827 : Histogram(name,
807 ranges->range(1), 828 ranges->range(1),
808 ranges->range(ranges->size() - 2), 829 ranges->range(ranges->size() - 2),
809 ranges->size() - 1, 830 ranges->size() - 1,
810 ranges) {} 831 ranges) {}
811 832
812 bool CustomHistogram::SerializeRanges(Pickle* pickle) const { 833 bool CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
813 for (size_t i = 0; i < bucket_ranges()->size(); ++i) { 834 if (!Histogram::SerializeInfoImpl(pickle))
835 return false;
836
837 // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't
838 // write them.
839 for (size_t i = 1; i < bucket_ranges()->size() - 1; ++i) {
814 if (!pickle->WriteInt(bucket_ranges()->range(i))) 840 if (!pickle->WriteInt(bucket_ranges()->range(i)))
815 return false; 841 return false;
816 } 842 }
817 return true; 843 return true;
818 } 844 }
819 845
820 // static
821 bool CustomHistogram::DeserializeRanges(
822 PickleIterator* iter, vector<Sample>* ranges) {
823 for (size_t i = 0; i < ranges->size(); ++i) {
824 if (!iter->ReadInt(&(*ranges)[i]))
825 return false;
826 }
827 return true;
828 }
829
830 double CustomHistogram::GetBucketSize(Count current, size_t i) const { 846 double CustomHistogram::GetBucketSize(Count current, size_t i) const {
831 return 1; 847 return 1;
832 } 848 }
833 849
834 // static 850 // static
851 HistogramBase* CustomHistogram::DeserializeInfoImpl(PickleIterator* iter) {
852 string histogram_name;
853 int flags;
854 int declared_min;
855 int declared_max;
856 uint64 bucket_count;
857 uint32 range_checksum;
858
859 if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
860 &declared_max, &bucket_count, &range_checksum)) {
861 return NULL;
862 }
863
864 // First and last ranges are not serialized.
865 vector<Sample> sample_ranges(bucket_count - 1);
866
867 for (size_t i = 0; i < sample_ranges.size(); ++i) {
868 if (!iter->ReadInt(&sample_ranges[i]))
869 return NULL;
870 }
871
872 HistogramBase* histogram = CustomHistogram::FactoryGet(
873 histogram_name, sample_ranges, flags);
874 if (!ValidateRangeChecksum(*histogram, range_checksum)) {
875 // The serialized histogram might be corrupted.
876 return NULL;
877 }
878 return histogram;
879 }
880
881 // static
835 bool CustomHistogram::ValidateCustomRanges( 882 bool CustomHistogram::ValidateCustomRanges(
836 const vector<Sample>& custom_ranges) { 883 const vector<Sample>& custom_ranges) {
837 bool has_valid_range = false; 884 bool has_valid_range = false;
838 for (size_t i = 0; i < custom_ranges.size(); i++) { 885 for (size_t i = 0; i < custom_ranges.size(); i++) {
839 Sample sample = custom_ranges[i]; 886 Sample sample = custom_ranges[i];
840 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) 887 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
841 return false; 888 return false;
842 if (sample != 0) 889 if (sample != 0)
843 has_valid_range = true; 890 has_valid_range = true;
844 } 891 }
(...skipping 12 matching lines...) Expand all
857 904
858 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); 905 BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
859 for (size_t i = 0; i < ranges.size(); i++) { 906 for (size_t i = 0; i < ranges.size(); i++) {
860 bucket_ranges->set_range(i, ranges[i]); 907 bucket_ranges->set_range(i, ranges[i]);
861 } 908 }
862 bucket_ranges->ResetChecksum(); 909 bucket_ranges->ResetChecksum();
863 return bucket_ranges; 910 return bucket_ranges;
864 } 911 }
865 912
866 } // namespace base 913 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698