OLD | NEW |
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 | 8 |
9 // It supports calls to accumulate either time intervals (which are processed | 9 // It supports calls to accumulate either time intervals (which are processed |
10 // as integral number of milliseconds), or arbitrary integral units. | 10 // as integral number of milliseconds), or arbitrary integral units. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 #include "base/macros.h" | 79 #include "base/macros.h" |
80 #include "base/metrics/bucket_ranges.h" | 80 #include "base/metrics/bucket_ranges.h" |
81 #include "base/metrics/histogram_base.h" | 81 #include "base/metrics/histogram_base.h" |
82 #include "base/metrics/histogram_samples.h" | 82 #include "base/metrics/histogram_samples.h" |
83 #include "base/time/time.h" | 83 #include "base/time/time.h" |
84 | 84 |
85 namespace base { | 85 namespace base { |
86 | 86 |
87 class BooleanHistogram; | 87 class BooleanHistogram; |
88 class CustomHistogram; | 88 class CustomHistogram; |
| 89 class DelayedPersistentAllocation; |
89 class Histogram; | 90 class Histogram; |
90 class LinearHistogram; | 91 class LinearHistogram; |
91 class Pickle; | 92 class Pickle; |
92 class PickleIterator; | 93 class PickleIterator; |
93 class SampleVector; | 94 class SampleVector; |
| 95 class SampleVectorBase; |
94 | 96 |
95 class BASE_EXPORT Histogram : public HistogramBase { | 97 class BASE_EXPORT Histogram : public HistogramBase { |
96 public: | 98 public: |
97 // Initialize maximum number of buckets in histograms as 16,384. | 99 // Initialize maximum number of buckets in histograms as 16,384. |
98 static const uint32_t kBucketCount_MAX; | 100 static const uint32_t kBucketCount_MAX; |
99 | 101 |
100 typedef std::vector<Count> Counts; | 102 typedef std::vector<Count> Counts; |
101 | 103 |
102 ~Histogram() override; | 104 ~Histogram() override; |
103 | 105 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 base::TimeDelta maximum, | 137 base::TimeDelta maximum, |
136 uint32_t bucket_count, | 138 uint32_t bucket_count, |
137 int32_t flags); | 139 int32_t flags); |
138 | 140 |
139 // Create a histogram using data in persistent storage. | 141 // Create a histogram using data in persistent storage. |
140 static std::unique_ptr<HistogramBase> PersistentCreate( | 142 static std::unique_ptr<HistogramBase> PersistentCreate( |
141 const std::string& name, | 143 const std::string& name, |
142 Sample minimum, | 144 Sample minimum, |
143 Sample maximum, | 145 Sample maximum, |
144 const BucketRanges* ranges, | 146 const BucketRanges* ranges, |
145 HistogramBase::AtomicCount* counts, | 147 const DelayedPersistentAllocation& counts, |
146 HistogramBase::AtomicCount* logged_counts, | 148 const DelayedPersistentAllocation& logged_counts, |
147 uint32_t counts_size, | |
148 HistogramSamples::Metadata* meta, | 149 HistogramSamples::Metadata* meta, |
149 HistogramSamples::Metadata* logged_meta); | 150 HistogramSamples::Metadata* logged_meta); |
150 | 151 |
151 static void InitializeBucketRanges(Sample minimum, | 152 static void InitializeBucketRanges(Sample minimum, |
152 Sample maximum, | 153 Sample maximum, |
153 BucketRanges* ranges); | 154 BucketRanges* ranges); |
154 | 155 |
155 // This constant if for FindCorruption. Since snapshots of histograms are | 156 // This constant if for FindCorruption. Since snapshots of histograms are |
156 // taken asynchronously relative to sampling, and our counting code currently | 157 // taken asynchronously relative to sampling, and our counting code currently |
157 // does not prevent race conditions, it is pretty likely that we'll catch a | 158 // does not prevent race conditions, it is pretty likely that we'll catch a |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 // Traditionally, histograms allocate their own memory for the bucket | 225 // Traditionally, histograms allocate their own memory for the bucket |
225 // vector but "shared" histograms use memory regions allocated from a | 226 // vector but "shared" histograms use memory regions allocated from a |
226 // special memory segment that is passed in here. It is assumed that | 227 // special memory segment that is passed in here. It is assumed that |
227 // the life of this memory is managed externally and exceeds the lifetime | 228 // the life of this memory is managed externally and exceeds the lifetime |
228 // of this object. Practically, this memory is never released until the | 229 // of this object. Practically, this memory is never released until the |
229 // process exits and the OS cleans it up. | 230 // process exits and the OS cleans it up. |
230 Histogram(const std::string& name, | 231 Histogram(const std::string& name, |
231 Sample minimum, | 232 Sample minimum, |
232 Sample maximum, | 233 Sample maximum, |
233 const BucketRanges* ranges, | 234 const BucketRanges* ranges, |
234 HistogramBase::AtomicCount* counts, | 235 const DelayedPersistentAllocation& counts, |
235 HistogramBase::AtomicCount* logged_counts, | 236 const DelayedPersistentAllocation& logged_counts, |
236 uint32_t counts_size, | |
237 HistogramSamples::Metadata* meta, | 237 HistogramSamples::Metadata* meta, |
238 HistogramSamples::Metadata* logged_meta); | 238 HistogramSamples::Metadata* logged_meta); |
239 | 239 |
240 // HistogramBase implementation: | 240 // HistogramBase implementation: |
241 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 241 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
242 | 242 |
243 // Method to override to skip the display of the i'th bucket if it's empty. | 243 // Method to override to skip the display of the i'th bucket if it's empty. |
244 virtual bool PrintEmptyBucket(uint32_t index) const; | 244 virtual bool PrintEmptyBucket(uint32_t index) const; |
245 | 245 |
246 // Get normalized size, relative to the ranges(i). | 246 // Get normalized size, relative to the ranges(i). |
(...skipping 21 matching lines...) Expand all Loading... |
268 std::unique_ptr<SampleVector> SnapshotSampleVector() const; | 268 std::unique_ptr<SampleVector> SnapshotSampleVector() const; |
269 | 269 |
270 //---------------------------------------------------------------------------- | 270 //---------------------------------------------------------------------------- |
271 // Helpers for emitting Ascii graphic. Each method appends data to output. | 271 // Helpers for emitting Ascii graphic. Each method appends data to output. |
272 | 272 |
273 void WriteAsciiImpl(bool graph_it, | 273 void WriteAsciiImpl(bool graph_it, |
274 const std::string& newline, | 274 const std::string& newline, |
275 std::string* output) const; | 275 std::string* output) const; |
276 | 276 |
277 // Find out how large (graphically) the largest bucket will appear to be. | 277 // Find out how large (graphically) the largest bucket will appear to be. |
278 double GetPeakBucketSize(const SampleVector& samples) const; | 278 double GetPeakBucketSize(const SampleVectorBase& samples) const; |
279 | 279 |
280 // Write a common header message describing this histogram. | 280 // Write a common header message describing this histogram. |
281 void WriteAsciiHeader(const SampleVector& samples, | 281 void WriteAsciiHeader(const SampleVectorBase& samples, |
282 Count sample_count, | 282 Count sample_count, |
283 std::string* output) const; | 283 std::string* output) const; |
284 | 284 |
285 // Write information about previous, current, and next buckets. | 285 // Write information about previous, current, and next buckets. |
286 // Information such as cumulative percentage, etc. | 286 // Information such as cumulative percentage, etc. |
287 void WriteAsciiBucketContext(const int64_t past, | 287 void WriteAsciiBucketContext(const int64_t past, |
288 const Count current, | 288 const Count current, |
289 const int64_t remaining, | 289 const int64_t remaining, |
290 const uint32_t i, | 290 const uint32_t i, |
291 std::string* output) const; | 291 std::string* output) const; |
292 | 292 |
293 // WriteJSON calls these. | 293 // WriteJSON calls these. |
294 void GetParameters(DictionaryValue* params) const override; | 294 void GetParameters(DictionaryValue* params) const override; |
295 | 295 |
296 void GetCountAndBucketData(Count* count, | 296 void GetCountAndBucketData(Count* count, |
297 int64_t* sum, | 297 int64_t* sum, |
298 ListValue* buckets) const override; | 298 ListValue* buckets) const override; |
299 | 299 |
300 // Does not own this object. Should get from StatisticsRecorder. | 300 // Does not own this object. Should get from StatisticsRecorder. |
301 const BucketRanges* bucket_ranges_; | 301 const BucketRanges* bucket_ranges_; |
302 | 302 |
303 Sample declared_min_; // Less than this goes into the first bucket. | 303 Sample declared_min_; // Less than this goes into the first bucket. |
304 Sample declared_max_; // Over this goes into the last bucket. | 304 Sample declared_max_; // Over this goes into the last bucket. |
305 | 305 |
306 // Finally, provide the state that changes with the addition of each new | 306 // Finally, provide the state that changes with the addition of each new |
307 // sample. | 307 // sample. |
308 std::unique_ptr<SampleVector> samples_; | 308 std::unique_ptr<SampleVectorBase> samples_; |
309 | 309 |
310 // Also keep a previous uploaded state for calculating deltas. | 310 // Also keep a previous uploaded state for calculating deltas. |
311 std::unique_ptr<HistogramSamples> logged_samples_; | 311 std::unique_ptr<HistogramSamples> logged_samples_; |
312 | 312 |
313 // Flag to indicate if PrepareFinalDelta has been previously called. It is | 313 // Flag to indicate if PrepareFinalDelta has been previously called. It is |
314 // used to DCHECK that a final delta is not created multiple times. | 314 // used to DCHECK that a final delta is not created multiple times. |
315 mutable bool final_delta_created_ = false; | 315 mutable bool final_delta_created_ = false; |
316 | 316 |
317 DISALLOW_COPY_AND_ASSIGN(Histogram); | 317 DISALLOW_COPY_AND_ASSIGN(Histogram); |
318 }; | 318 }; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 TimeDelta maximum, | 351 TimeDelta maximum, |
352 uint32_t bucket_count, | 352 uint32_t bucket_count, |
353 int32_t flags); | 353 int32_t flags); |
354 | 354 |
355 // Create a histogram using data in persistent storage. | 355 // Create a histogram using data in persistent storage. |
356 static std::unique_ptr<HistogramBase> PersistentCreate( | 356 static std::unique_ptr<HistogramBase> PersistentCreate( |
357 const std::string& name, | 357 const std::string& name, |
358 Sample minimum, | 358 Sample minimum, |
359 Sample maximum, | 359 Sample maximum, |
360 const BucketRanges* ranges, | 360 const BucketRanges* ranges, |
361 HistogramBase::AtomicCount* counts, | 361 const DelayedPersistentAllocation& counts, |
362 HistogramBase::AtomicCount* logged_counts, | 362 const DelayedPersistentAllocation& logged_counts, |
363 uint32_t counts_size, | |
364 HistogramSamples::Metadata* meta, | 363 HistogramSamples::Metadata* meta, |
365 HistogramSamples::Metadata* logged_meta); | 364 HistogramSamples::Metadata* logged_meta); |
366 | 365 |
367 struct DescriptionPair { | 366 struct DescriptionPair { |
368 Sample sample; | 367 Sample sample; |
369 const char* description; // Null means end of a list of pairs. | 368 const char* description; // Null means end of a list of pairs. |
370 }; | 369 }; |
371 | 370 |
372 // Create a LinearHistogram and store a list of number/text values for use in | 371 // Create a LinearHistogram and store a list of number/text values for use in |
373 // writing the histogram graph. | 372 // writing the histogram graph. |
(...skipping 20 matching lines...) Expand all Loading... |
394 | 393 |
395 LinearHistogram(const std::string& name, | 394 LinearHistogram(const std::string& name, |
396 Sample minimum, | 395 Sample minimum, |
397 Sample maximum, | 396 Sample maximum, |
398 const BucketRanges* ranges); | 397 const BucketRanges* ranges); |
399 | 398 |
400 LinearHistogram(const std::string& name, | 399 LinearHistogram(const std::string& name, |
401 Sample minimum, | 400 Sample minimum, |
402 Sample maximum, | 401 Sample maximum, |
403 const BucketRanges* ranges, | 402 const BucketRanges* ranges, |
404 HistogramBase::AtomicCount* counts, | 403 const DelayedPersistentAllocation& counts, |
405 HistogramBase::AtomicCount* logged_counts, | 404 const DelayedPersistentAllocation& logged_counts, |
406 uint32_t counts_size, | |
407 HistogramSamples::Metadata* meta, | 405 HistogramSamples::Metadata* meta, |
408 HistogramSamples::Metadata* logged_meta); | 406 HistogramSamples::Metadata* logged_meta); |
409 | 407 |
410 double GetBucketSize(Count current, uint32_t i) const override; | 408 double GetBucketSize(Count current, uint32_t i) const override; |
411 | 409 |
412 // If we have a description for a bucket, then return that. Otherwise | 410 // If we have a description for a bucket, then return that. Otherwise |
413 // let parent class provide a (numeric) description. | 411 // let parent class provide a (numeric) description. |
414 const std::string GetAsciiBucketRange(uint32_t i) const override; | 412 const std::string GetAsciiBucketRange(uint32_t i) const override; |
415 | 413 |
416 // Skip printing of name for numeric range if we have a name (and if this is | 414 // Skip printing of name for numeric range if we have a name (and if this is |
(...skipping 23 matching lines...) Expand all Loading... |
440 | 438 |
441 // Overload of the above function that takes a const char* |name| param, | 439 // Overload of the above function that takes a const char* |name| param, |
442 // to avoid code bloat from the std::string constructor being inlined into | 440 // to avoid code bloat from the std::string constructor being inlined into |
443 // call sites. | 441 // call sites. |
444 static HistogramBase* FactoryGet(const char* name, int32_t flags); | 442 static HistogramBase* FactoryGet(const char* name, int32_t flags); |
445 | 443 |
446 // Create a histogram using data in persistent storage. | 444 // Create a histogram using data in persistent storage. |
447 static std::unique_ptr<HistogramBase> PersistentCreate( | 445 static std::unique_ptr<HistogramBase> PersistentCreate( |
448 const std::string& name, | 446 const std::string& name, |
449 const BucketRanges* ranges, | 447 const BucketRanges* ranges, |
450 HistogramBase::AtomicCount* counts, | 448 const DelayedPersistentAllocation& counts, |
451 HistogramBase::AtomicCount* logged_counts, | 449 const DelayedPersistentAllocation& logged_counts, |
452 HistogramSamples::Metadata* meta, | 450 HistogramSamples::Metadata* meta, |
453 HistogramSamples::Metadata* logged_meta); | 451 HistogramSamples::Metadata* logged_meta); |
454 | 452 |
455 HistogramType GetHistogramType() const override; | 453 HistogramType GetHistogramType() const override; |
456 | 454 |
457 protected: | 455 protected: |
458 class Factory; | 456 class Factory; |
459 | 457 |
460 private: | 458 private: |
461 BooleanHistogram(const std::string& name, const BucketRanges* ranges); | 459 BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
462 BooleanHistogram(const std::string& name, | 460 BooleanHistogram(const std::string& name, |
463 const BucketRanges* ranges, | 461 const BucketRanges* ranges, |
464 HistogramBase::AtomicCount* counts, | 462 const DelayedPersistentAllocation& counts, |
465 HistogramBase::AtomicCount* logged_counts, | 463 const DelayedPersistentAllocation& logged_counts, |
466 HistogramSamples::Metadata* meta, | 464 HistogramSamples::Metadata* meta, |
467 HistogramSamples::Metadata* logged_meta); | 465 HistogramSamples::Metadata* logged_meta); |
468 | 466 |
469 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 467 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
470 base::PickleIterator* iter); | 468 base::PickleIterator* iter); |
471 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 469 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
472 | 470 |
473 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); | 471 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
474 }; | 472 }; |
475 | 473 |
(...skipping 14 matching lines...) Expand all Loading... |
490 // to avoid code bloat from the std::string constructor being inlined into | 488 // to avoid code bloat from the std::string constructor being inlined into |
491 // call sites. | 489 // call sites. |
492 static HistogramBase* FactoryGet(const char* name, | 490 static HistogramBase* FactoryGet(const char* name, |
493 const std::vector<Sample>& custom_ranges, | 491 const std::vector<Sample>& custom_ranges, |
494 int32_t flags); | 492 int32_t flags); |
495 | 493 |
496 // Create a histogram using data in persistent storage. | 494 // Create a histogram using data in persistent storage. |
497 static std::unique_ptr<HistogramBase> PersistentCreate( | 495 static std::unique_ptr<HistogramBase> PersistentCreate( |
498 const std::string& name, | 496 const std::string& name, |
499 const BucketRanges* ranges, | 497 const BucketRanges* ranges, |
500 HistogramBase::AtomicCount* counts, | 498 const DelayedPersistentAllocation& counts, |
501 HistogramBase::AtomicCount* logged_counts, | 499 const DelayedPersistentAllocation& logged_counts, |
502 uint32_t counts_size, | |
503 HistogramSamples::Metadata* meta, | 500 HistogramSamples::Metadata* meta, |
504 HistogramSamples::Metadata* logged_meta); | 501 HistogramSamples::Metadata* logged_meta); |
505 | 502 |
506 // Overridden from Histogram: | 503 // Overridden from Histogram: |
507 HistogramType GetHistogramType() const override; | 504 HistogramType GetHistogramType() const override; |
508 | 505 |
509 // Helper method for transforming an array of valid enumeration values | 506 // Helper method for transforming an array of valid enumeration values |
510 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. | 507 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. |
511 // This function ensures that a guard bucket exists right after any | 508 // This function ensures that a guard bucket exists right after any |
512 // valid sample value (unless the next higher sample is also a valid value), | 509 // valid sample value (unless the next higher sample is also a valid value), |
513 // so that invalid samples never fall into the same bucket as valid samples. | 510 // so that invalid samples never fall into the same bucket as valid samples. |
514 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. | 511 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. |
515 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, | 512 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
516 uint32_t num_values); | 513 uint32_t num_values); |
517 protected: | 514 protected: |
518 class Factory; | 515 class Factory; |
519 | 516 |
520 CustomHistogram(const std::string& name, | 517 CustomHistogram(const std::string& name, |
521 const BucketRanges* ranges); | 518 const BucketRanges* ranges); |
522 | 519 |
523 CustomHistogram(const std::string& name, | 520 CustomHistogram(const std::string& name, |
524 const BucketRanges* ranges, | 521 const BucketRanges* ranges, |
525 HistogramBase::AtomicCount* counts, | 522 const DelayedPersistentAllocation& counts, |
526 HistogramBase::AtomicCount* logged_counts, | 523 const DelayedPersistentAllocation& logged_counts, |
527 uint32_t counts_size, | |
528 HistogramSamples::Metadata* meta, | 524 HistogramSamples::Metadata* meta, |
529 HistogramSamples::Metadata* logged_meta); | 525 HistogramSamples::Metadata* logged_meta); |
530 | 526 |
531 // HistogramBase implementation: | 527 // HistogramBase implementation: |
532 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 528 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
533 | 529 |
534 double GetBucketSize(Count current, uint32_t i) const override; | 530 double GetBucketSize(Count current, uint32_t i) const override; |
535 | 531 |
536 private: | 532 private: |
537 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 533 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
538 base::PickleIterator* iter); | 534 base::PickleIterator* iter); |
539 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 535 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
540 | 536 |
541 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | 537 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
542 | 538 |
543 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 539 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
544 }; | 540 }; |
545 | 541 |
546 } // namespace base | 542 } // namespace base |
547 | 543 |
548 #endif // BASE_METRICS_HISTOGRAM_H_ | 544 #endif // BASE_METRICS_HISTOGRAM_H_ |
OLD | NEW |