| 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 |