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