OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 Pickle pickle; | 232 Pickle pickle; |
233 pickle.WriteString(histogram.histogram_name()); | 233 pickle.WriteString(histogram.histogram_name()); |
234 pickle.WriteInt(histogram.declared_min()); | 234 pickle.WriteInt(histogram.declared_min()); |
235 pickle.WriteInt(histogram.declared_max()); | 235 pickle.WriteInt(histogram.declared_max()); |
236 pickle.WriteSize(histogram.bucket_count()); | 236 pickle.WriteSize(histogram.bucket_count()); |
237 pickle.WriteUInt32(histogram.range_checksum()); | 237 pickle.WriteUInt32(histogram.range_checksum()); |
238 pickle.WriteInt(histogram.histogram_type()); | 238 pickle.WriteInt(histogram.histogram_type()); |
239 pickle.WriteInt(histogram.flags()); | 239 pickle.WriteInt(histogram.flags()); |
240 | 240 |
241 snapshot.Serialize(&pickle); | 241 snapshot.Serialize(&pickle); |
| 242 |
| 243 histogram.SerializeRanges(&pickle); |
| 244 |
242 return std::string(static_cast<const char*>(pickle.data()), pickle.size()); | 245 return std::string(static_cast<const char*>(pickle.data()), pickle.size()); |
243 } | 246 } |
244 | 247 |
245 // static | 248 // static |
246 bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { | 249 bool Histogram::DeserializeHistogramInfo(const std::string& histogram_info) { |
247 if (histogram_info.empty()) { | 250 if (histogram_info.empty()) { |
248 return false; | 251 return false; |
249 } | 252 } |
250 | 253 |
251 Pickle pickle(histogram_info.data(), | 254 Pickle pickle(histogram_info.data(), |
252 static_cast<int>(histogram_info.size())); | 255 static_cast<int>(histogram_info.size())); |
253 std::string histogram_name; | 256 std::string histogram_name; |
254 int declared_min; | 257 int declared_min; |
255 int declared_max; | 258 int declared_max; |
256 size_t bucket_count; | 259 size_t bucket_count; |
257 uint32 range_checksum; | 260 uint32 range_checksum; |
258 int histogram_type; | 261 int histogram_type; |
259 int pickle_flags; | 262 int pickle_flags; |
260 SampleSet sample; | 263 SampleSet sample; |
261 | 264 |
262 void* iter = NULL; | 265 void* iter = NULL; |
263 if (!pickle.ReadString(&iter, &histogram_name) || | 266 if (!pickle.ReadString(&iter, &histogram_name) || |
264 !pickle.ReadInt(&iter, &declared_min) || | 267 !pickle.ReadInt(&iter, &declared_min) || |
265 !pickle.ReadInt(&iter, &declared_max) || | 268 !pickle.ReadInt(&iter, &declared_max) || |
266 !pickle.ReadSize(&iter, &bucket_count) || | 269 !pickle.ReadSize(&iter, &bucket_count) || |
267 !pickle.ReadUInt32(&iter, &range_checksum) || | 270 !pickle.ReadUInt32(&iter, &range_checksum) || |
268 !pickle.ReadInt(&iter, &histogram_type) || | 271 !pickle.ReadInt(&iter, &histogram_type) || |
269 !pickle.ReadInt(&iter, &pickle_flags) || | 272 !pickle.ReadInt(&iter, &pickle_flags) || |
270 !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) { | 273 !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) { |
271 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; | 274 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; |
272 return false; | 275 return false; |
273 } | 276 } |
| 277 |
274 DCHECK(pickle_flags & kIPCSerializationSourceFlag); | 278 DCHECK(pickle_flags & kIPCSerializationSourceFlag); |
275 // Since these fields may have come from an untrusted renderer, do additional | 279 // Since these fields may have come from an untrusted renderer, do additional |
276 // checks above and beyond those in Histogram::Initialize() | 280 // checks above and beyond those in Histogram::Initialize() |
277 if (declared_max <= 0 || declared_min <= 0 || declared_max < declared_min || | 281 if (declared_max <= 0 || declared_min <= 0 || declared_max < declared_min || |
278 INT_MAX / sizeof(Count) <= bucket_count || bucket_count < 2) { | 282 INT_MAX / sizeof(Count) <= bucket_count || bucket_count < 2) { |
279 DLOG(ERROR) << "Values error decoding Histogram: " << histogram_name; | 283 DLOG(ERROR) << "Values error decoding Histogram: " << histogram_name; |
280 return false; | 284 return false; |
281 } | 285 } |
282 | 286 |
283 Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag); | 287 Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag); |
284 | 288 |
285 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type); | 289 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram_type); |
286 | 290 |
287 Histogram* render_histogram(NULL); | 291 Histogram* render_histogram(NULL); |
288 | 292 |
289 if (histogram_type == HISTOGRAM) { | 293 if (histogram_type == HISTOGRAM) { |
290 render_histogram = Histogram::FactoryGet( | 294 render_histogram = Histogram::FactoryGet( |
291 histogram_name, declared_min, declared_max, bucket_count, flags); | 295 histogram_name, declared_min, declared_max, bucket_count, flags); |
292 } else if (histogram_type == LINEAR_HISTOGRAM) { | 296 } else if (histogram_type == LINEAR_HISTOGRAM) { |
293 render_histogram = LinearHistogram::FactoryGet( | 297 render_histogram = LinearHistogram::FactoryGet( |
294 histogram_name, declared_min, declared_max, bucket_count, flags); | 298 histogram_name, declared_min, declared_max, bucket_count, flags); |
295 } else if (histogram_type == BOOLEAN_HISTOGRAM) { | 299 } else if (histogram_type == BOOLEAN_HISTOGRAM) { |
296 render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags); | 300 render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags); |
| 301 } else if (histogram_type == CUSTOM_HISTOGRAM) { |
| 302 std::vector<Histogram::Sample> sample_ranges(bucket_count); |
| 303 if (!CustomHistogram::DeserializeRanges(&iter, pickle, &sample_ranges)) { |
| 304 DLOG(ERROR) << "Pickle error decoding ranges: " << histogram_name; |
| 305 return false; |
| 306 } |
| 307 render_histogram = |
| 308 CustomHistogram::FactoryGet(histogram_name, sample_ranges, flags); |
297 } else { | 309 } else { |
298 DLOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " | 310 DLOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " |
299 << histogram_type; | 311 << histogram_type; |
300 return false; | 312 return false; |
301 } | 313 } |
302 | 314 |
303 DCHECK_EQ(render_histogram->declared_min(), declared_min); | 315 DCHECK_EQ(render_histogram->declared_min(), declared_min); |
304 DCHECK_EQ(render_histogram->declared_max(), declared_max); | 316 DCHECK_EQ(render_histogram->declared_max(), declared_max); |
305 DCHECK_EQ(render_histogram->bucket_count(), bucket_count); | 317 DCHECK_EQ(render_histogram->bucket_count(), bucket_count); |
306 DCHECK_EQ(render_histogram->range_checksum(), range_checksum); | 318 DCHECK_EQ(render_histogram->range_checksum(), range_checksum); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 if (StatisticsRecorder::dump_on_exit()) { | 445 if (StatisticsRecorder::dump_on_exit()) { |
434 std::string output; | 446 std::string output; |
435 WriteAscii(true, "\n", &output); | 447 WriteAscii(true, "\n", &output); |
436 DLOG(INFO) << output; | 448 DLOG(INFO) << output; |
437 } | 449 } |
438 | 450 |
439 // Just to make sure most derived class did this properly... | 451 // Just to make sure most derived class did this properly... |
440 DCHECK(ValidateBucketRanges()); | 452 DCHECK(ValidateBucketRanges()); |
441 } | 453 } |
442 | 454 |
| 455 bool Histogram::SerializeRanges(Pickle* pickle) const { |
| 456 return true; |
| 457 } |
| 458 |
443 // Calculate what range of values are held in each bucket. | 459 // Calculate what range of values are held in each bucket. |
444 // We have to be careful that we don't pick a ratio between starting points in | 460 // We have to be careful that we don't pick a ratio between starting points in |
445 // consecutive buckets that is sooo small, that the integer bounds are the same | 461 // consecutive buckets that is sooo small, that the integer bounds are the same |
446 // (effectively making one bucket get no values). We need to avoid: | 462 // (effectively making one bucket get no values). We need to avoid: |
447 // ranges(i) == ranges(i + 1) | 463 // ranges(i) == ranges(i + 1) |
448 // To avoid that, we just do a fine-grained bucket width as far as we need to | 464 // To avoid that, we just do a fine-grained bucket width as far as we need to |
449 // until we get a ratio that moves us along at least 2 units at a time. From | 465 // until we get a ratio that moves us along at least 2 units at a time. From |
450 // that bucket onward we do use the exponential growth of buckets. | 466 // that bucket onward we do use the exponential growth of buckets. |
451 void Histogram::InitializeBucketRange() { | 467 void Histogram::InitializeBucketRange() { |
452 double log_max = log(static_cast<double>(declared_max())); | 468 double log_max = log(static_cast<double>(declared_max())); |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 } | 990 } |
975 | 991 |
976 CustomHistogram::CustomHistogram(const std::string& name, | 992 CustomHistogram::CustomHistogram(const std::string& name, |
977 const std::vector<Sample>& custom_ranges) | 993 const std::vector<Sample>& custom_ranges) |
978 : Histogram(name, custom_ranges[1], custom_ranges.back(), | 994 : Histogram(name, custom_ranges[1], custom_ranges.back(), |
979 custom_ranges.size()) { | 995 custom_ranges.size()) { |
980 DCHECK_GT(custom_ranges.size(), 1u); | 996 DCHECK_GT(custom_ranges.size(), 1u); |
981 DCHECK_EQ(custom_ranges[0], 0); | 997 DCHECK_EQ(custom_ranges[0], 0); |
982 } | 998 } |
983 | 999 |
| 1000 bool CustomHistogram::SerializeRanges(Pickle* pickle) const { |
| 1001 for (size_t i = 0; i < cached_ranges()->size(); ++i) { |
| 1002 if (!pickle->WriteInt(cached_ranges()->ranges(i))) |
| 1003 return false; |
| 1004 } |
| 1005 return true; |
| 1006 } |
| 1007 |
| 1008 // static |
| 1009 bool CustomHistogram::DeserializeRanges( |
| 1010 void** iter, const Pickle& pickle, std::vector<Histogram::Sample>* ranges) { |
| 1011 for (size_t i = 0; i < ranges->size(); ++i) { |
| 1012 if (!pickle.ReadInt(iter, &(*ranges)[i])) |
| 1013 return false; |
| 1014 } |
| 1015 return true; |
| 1016 } |
| 1017 |
984 void CustomHistogram::InitializedCustomBucketRange( | 1018 void CustomHistogram::InitializedCustomBucketRange( |
985 const std::vector<Sample>& custom_ranges) { | 1019 const std::vector<Sample>& custom_ranges) { |
986 DCHECK_GT(custom_ranges.size(), 1u); | 1020 DCHECK_GT(custom_ranges.size(), 1u); |
987 DCHECK_EQ(custom_ranges[0], 0); | 1021 DCHECK_EQ(custom_ranges[0], 0); |
988 DCHECK_LE(custom_ranges.size(), bucket_count()); | 1022 DCHECK_LE(custom_ranges.size(), bucket_count()); |
989 for (size_t index = 0; index < custom_ranges.size(); ++index) | 1023 for (size_t index = 0; index < custom_ranges.size(); ++index) |
990 SetBucketRange(index, custom_ranges[index]); | 1024 SetBucketRange(index, custom_ranges[index]); |
991 ResetRangeChecksum(); | 1025 ResetRangeChecksum(); |
992 } | 1026 } |
993 | 1027 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 | 1316 |
1283 // static | 1317 // static |
1284 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; | 1318 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; |
1285 // static | 1319 // static |
1286 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; | 1320 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = NULL; |
1287 // static | 1321 // static |
1288 base::Lock* StatisticsRecorder::lock_ = NULL; | 1322 base::Lock* StatisticsRecorder::lock_ = NULL; |
1289 // static | 1323 // static |
1290 bool StatisticsRecorder::dump_on_exit_ = false; | 1324 bool StatisticsRecorder::dump_on_exit_ = false; |
1291 } // namespace base | 1325 } // namespace base |
OLD | NEW |