| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 base::TimeDelta maximum, | 138 base::TimeDelta maximum, |
| 139 uint32_t bucket_count, | 139 uint32_t bucket_count, |
| 140 int32_t flags); | 140 int32_t flags); |
| 141 | 141 |
| 142 // Get a histogram using data in persistent storage. | 142 // Get a histogram using data in persistent storage. |
| 143 static HistogramBase* PersistentGet(const std::string& name, | 143 static HistogramBase* PersistentGet(const std::string& name, |
| 144 Sample minimum, | 144 Sample minimum, |
| 145 Sample maximum, | 145 Sample maximum, |
| 146 const BucketRanges* ranges, | 146 const BucketRanges* ranges, |
| 147 HistogramBase::AtomicCount* counts, | 147 HistogramBase::AtomicCount* counts, |
| 148 HistogramBase::AtomicCount* logged_counts, |
| 148 uint32_t counts_size, | 149 uint32_t counts_size, |
| 149 HistogramSamples::Metadata* meta); | 150 HistogramSamples::Metadata* meta, |
| 151 HistogramSamples::Metadata* logged_meta); |
| 150 | 152 |
| 151 static void InitializeBucketRanges(Sample minimum, | 153 static void InitializeBucketRanges(Sample minimum, |
| 152 Sample maximum, | 154 Sample maximum, |
| 153 BucketRanges* ranges); | 155 BucketRanges* ranges); |
| 154 | 156 |
| 155 // This constant if for FindCorruption. Since snapshots of histograms are | 157 // This constant if for FindCorruption. Since snapshots of histograms are |
| 156 // taken asynchronously relative to sampling, and our counting code currently | 158 // 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 | 159 // does not prevent race conditions, it is pretty likely that we'll catch a |
| 158 // redundant count that doesn't match the sample count. We allow for a | 160 // redundant count that doesn't match the sample count. We allow for a |
| 159 // certain amount of slop before flagging this as an inconsistency. Even with | 161 // certain amount of slop before flagging this as an inconsistency. Even with |
| 160 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), | 162 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), |
| 161 // so we'll eventually get the data, if it was not the result of a corruption. | 163 // so we'll eventually get the data, if it was not the result of a corruption. |
| 162 static const int kCommonRaceBasedCountMismatch; | 164 static const int kCommonRaceBasedCountMismatch; |
| 163 | 165 |
| 164 // Check to see if bucket ranges, counts and tallies in the snapshot are | 166 // Check to see if bucket ranges, counts and tallies in the snapshot are |
| 165 // consistent with the bucket ranges and checksums in our histogram. This can | 167 // consistent with the bucket ranges and checksums in our histogram. This can |
| 166 // produce a false-alarm if a race occurred in the reading of the data during | 168 // produce a false-alarm if a race occurred in the reading of the data during |
| 167 // a SnapShot process, but should otherwise be false at all times (unless we | 169 // a SnapShot process, but should otherwise be false at all times (unless we |
| 168 // have memory over-writes, or DRAM failures). | 170 // have memory over-writes, or DRAM failures). Flag definitions are located |
| 169 int FindCorruption(const HistogramSamples& samples) const override; | 171 // under "enum Inconsistency" in base/metrics/histogram_base.h. |
| 172 uint32_t FindCorruption(const HistogramSamples& samples) const override; |
| 170 | 173 |
| 171 //---------------------------------------------------------------------------- | 174 //---------------------------------------------------------------------------- |
| 172 // Accessors for factory construction, serialization and testing. | 175 // Accessors for factory construction, serialization and testing. |
| 173 //---------------------------------------------------------------------------- | 176 //---------------------------------------------------------------------------- |
| 174 Sample declared_min() const { return declared_min_; } | 177 Sample declared_min() const { return declared_min_; } |
| 175 Sample declared_max() const { return declared_max_; } | 178 Sample declared_max() const { return declared_max_; } |
| 176 virtual Sample ranges(uint32_t i) const; | 179 virtual Sample ranges(uint32_t i) const; |
| 177 virtual uint32_t bucket_count() const; | 180 virtual uint32_t bucket_count() const; |
| 178 const BucketRanges* bucket_ranges() const { return bucket_ranges_; } | 181 const BucketRanges* bucket_ranges() const { return bucket_ranges_; } |
| 179 | 182 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 190 | 193 |
| 191 // HistogramBase implementation: | 194 // HistogramBase implementation: |
| 192 uint64_t name_hash() const override; | 195 uint64_t name_hash() const override; |
| 193 HistogramType GetHistogramType() const override; | 196 HistogramType GetHistogramType() const override; |
| 194 bool HasConstructionArguments(Sample expected_minimum, | 197 bool HasConstructionArguments(Sample expected_minimum, |
| 195 Sample expected_maximum, | 198 Sample expected_maximum, |
| 196 uint32_t expected_bucket_count) const override; | 199 uint32_t expected_bucket_count) const override; |
| 197 void Add(Sample value) override; | 200 void Add(Sample value) override; |
| 198 void AddCount(Sample value, int count) override; | 201 void AddCount(Sample value, int count) override; |
| 199 scoped_ptr<HistogramSamples> SnapshotSamples() const override; | 202 scoped_ptr<HistogramSamples> SnapshotSamples() const override; |
| 203 scoped_ptr<HistogramSamples> SnapshotDelta() override; |
| 200 void AddSamples(const HistogramSamples& samples) override; | 204 void AddSamples(const HistogramSamples& samples) override; |
| 201 bool AddSamplesFromPickle(base::PickleIterator* iter) override; | 205 bool AddSamplesFromPickle(base::PickleIterator* iter) override; |
| 202 void WriteHTMLGraph(std::string* output) const override; | 206 void WriteHTMLGraph(std::string* output) const override; |
| 203 void WriteAscii(std::string* output) const override; | 207 void WriteAscii(std::string* output) const override; |
| 204 | 208 |
| 205 protected: | 209 protected: |
| 206 // This class, defined entirely within the .cc file, contains all the | 210 // This class, defined entirely within the .cc file, contains all the |
| 207 // common logic for building a Histogram and can be overridden by more | 211 // common logic for building a Histogram and can be overridden by more |
| 208 // specific types to alter details of how the creation is done. It is | 212 // specific types to alter details of how the creation is done. It is |
| 209 // defined as an embedded class (rather than an anonymous one) so it | 213 // defined as an embedded class (rather than an anonymous one) so it |
| (...skipping 11 matching lines...) Expand all Loading... |
| 221 // vector but "shared" histograms use memory regions allocated from a | 225 // vector but "shared" histograms use memory regions allocated from a |
| 222 // special memory segment that is passed in here. It is assumed that | 226 // special memory segment that is passed in here. It is assumed that |
| 223 // the life of this memory is managed externally and exceeds the lifetime | 227 // the life of this memory is managed externally and exceeds the lifetime |
| 224 // of this object. Practically, this memory is never released until the | 228 // of this object. Practically, this memory is never released until the |
| 225 // process exits and the OS cleans it up. | 229 // process exits and the OS cleans it up. |
| 226 Histogram(const std::string& name, | 230 Histogram(const std::string& name, |
| 227 Sample minimum, | 231 Sample minimum, |
| 228 Sample maximum, | 232 Sample maximum, |
| 229 const BucketRanges* ranges, | 233 const BucketRanges* ranges, |
| 230 HistogramBase::AtomicCount* counts, | 234 HistogramBase::AtomicCount* counts, |
| 235 HistogramBase::AtomicCount* logged_counts, |
| 231 uint32_t counts_size, | 236 uint32_t counts_size, |
| 232 HistogramSamples::Metadata* meta); | 237 HistogramSamples::Metadata* meta, |
| 238 HistogramSamples::Metadata* logged_meta); |
| 233 | 239 |
| 234 ~Histogram() override; | 240 ~Histogram() override; |
| 235 | 241 |
| 236 // HistogramBase implementation: | 242 // HistogramBase implementation: |
| 237 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 243 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
| 238 | 244 |
| 239 // Method to override to skip the display of the i'th bucket if it's empty. | 245 // Method to override to skip the display of the i'th bucket if it's empty. |
| 240 virtual bool PrintEmptyBucket(uint32_t index) const; | 246 virtual bool PrintEmptyBucket(uint32_t index) const; |
| 241 | 247 |
| 242 // Get normalized size, relative to the ranges(i). | 248 // Get normalized size, relative to the ranges(i). |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 // Does not own this object. Should get from StatisticsRecorder. | 302 // Does not own this object. Should get from StatisticsRecorder. |
| 297 const BucketRanges* bucket_ranges_; | 303 const BucketRanges* bucket_ranges_; |
| 298 | 304 |
| 299 Sample declared_min_; // Less than this goes into the first bucket. | 305 Sample declared_min_; // Less than this goes into the first bucket. |
| 300 Sample declared_max_; // Over this goes into the last bucket. | 306 Sample declared_max_; // Over this goes into the last bucket. |
| 301 | 307 |
| 302 // Finally, provide the state that changes with the addition of each new | 308 // Finally, provide the state that changes with the addition of each new |
| 303 // sample. | 309 // sample. |
| 304 scoped_ptr<SampleVector> samples_; | 310 scoped_ptr<SampleVector> samples_; |
| 305 | 311 |
| 312 // Also keep a previous uploaded state for calculating deltas. |
| 313 scoped_ptr<HistogramSamples> logged_samples_; |
| 314 |
| 306 DISALLOW_COPY_AND_ASSIGN(Histogram); | 315 DISALLOW_COPY_AND_ASSIGN(Histogram); |
| 307 }; | 316 }; |
| 308 | 317 |
| 309 //------------------------------------------------------------------------------ | 318 //------------------------------------------------------------------------------ |
| 310 | 319 |
| 311 // LinearHistogram is a more traditional histogram, with evenly spaced | 320 // LinearHistogram is a more traditional histogram, with evenly spaced |
| 312 // buckets. | 321 // buckets. |
| 313 class BASE_EXPORT LinearHistogram : public Histogram { | 322 class BASE_EXPORT LinearHistogram : public Histogram { |
| 314 public: | 323 public: |
| 315 ~LinearHistogram() override; | 324 ~LinearHistogram() override; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 340 TimeDelta maximum, | 349 TimeDelta maximum, |
| 341 uint32_t bucket_count, | 350 uint32_t bucket_count, |
| 342 int32_t flags); | 351 int32_t flags); |
| 343 | 352 |
| 344 // Get a histogram using data in persistent storage. | 353 // Get a histogram using data in persistent storage. |
| 345 static HistogramBase* PersistentGet(const std::string& name, | 354 static HistogramBase* PersistentGet(const std::string& name, |
| 346 Sample minimum, | 355 Sample minimum, |
| 347 Sample maximum, | 356 Sample maximum, |
| 348 const BucketRanges* ranges, | 357 const BucketRanges* ranges, |
| 349 HistogramBase::AtomicCount* counts, | 358 HistogramBase::AtomicCount* counts, |
| 359 HistogramBase::AtomicCount* logged_counts, |
| 350 uint32_t counts_size, | 360 uint32_t counts_size, |
| 351 HistogramSamples::Metadata* meta); | 361 HistogramSamples::Metadata* meta, |
| 362 HistogramSamples::Metadata* logged_meta); |
| 352 | 363 |
| 353 struct DescriptionPair { | 364 struct DescriptionPair { |
| 354 Sample sample; | 365 Sample sample; |
| 355 const char* description; // Null means end of a list of pairs. | 366 const char* description; // Null means end of a list of pairs. |
| 356 }; | 367 }; |
| 357 | 368 |
| 358 // Create a LinearHistogram and store a list of number/text values for use in | 369 // Create a LinearHistogram and store a list of number/text values for use in |
| 359 // writing the histogram graph. | 370 // writing the histogram graph. |
| 360 // |descriptions| can be NULL, which means no special descriptions to set. If | 371 // |descriptions| can be NULL, which means no special descriptions to set. If |
| 361 // it's not NULL, the last element in the array must has a NULL in its | 372 // it's not NULL, the last element in the array must has a NULL in its |
| (...skipping 19 matching lines...) Expand all Loading... |
| 381 LinearHistogram(const std::string& name, | 392 LinearHistogram(const std::string& name, |
| 382 Sample minimum, | 393 Sample minimum, |
| 383 Sample maximum, | 394 Sample maximum, |
| 384 const BucketRanges* ranges); | 395 const BucketRanges* ranges); |
| 385 | 396 |
| 386 LinearHistogram(const std::string& name, | 397 LinearHistogram(const std::string& name, |
| 387 Sample minimum, | 398 Sample minimum, |
| 388 Sample maximum, | 399 Sample maximum, |
| 389 const BucketRanges* ranges, | 400 const BucketRanges* ranges, |
| 390 HistogramBase::AtomicCount* counts, | 401 HistogramBase::AtomicCount* counts, |
| 402 HistogramBase::AtomicCount* logged_counts, |
| 391 uint32_t counts_size, | 403 uint32_t counts_size, |
| 392 HistogramSamples::Metadata* meta); | 404 HistogramSamples::Metadata* meta, |
| 405 HistogramSamples::Metadata* logged_meta); |
| 393 | 406 |
| 394 double GetBucketSize(Count current, uint32_t i) const override; | 407 double GetBucketSize(Count current, uint32_t i) const override; |
| 395 | 408 |
| 396 // If we have a description for a bucket, then return that. Otherwise | 409 // If we have a description for a bucket, then return that. Otherwise |
| 397 // let parent class provide a (numeric) description. | 410 // let parent class provide a (numeric) description. |
| 398 const std::string GetAsciiBucketRange(uint32_t i) const override; | 411 const std::string GetAsciiBucketRange(uint32_t i) const override; |
| 399 | 412 |
| 400 // Skip printing of name for numeric range if we have a name (and if this is | 413 // Skip printing of name for numeric range if we have a name (and if this is |
| 401 // an empty bucket). | 414 // an empty bucket). |
| 402 bool PrintEmptyBucket(uint32_t index) const override; | 415 bool PrintEmptyBucket(uint32_t index) const override; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 424 | 437 |
| 425 // Overload of the above function that takes a const char* |name| param, | 438 // Overload of the above function that takes a const char* |name| param, |
| 426 // to avoid code bloat from the std::string constructor being inlined into | 439 // to avoid code bloat from the std::string constructor being inlined into |
| 427 // call sites. | 440 // call sites. |
| 428 static HistogramBase* FactoryGet(const char* name, int32_t flags); | 441 static HistogramBase* FactoryGet(const char* name, int32_t flags); |
| 429 | 442 |
| 430 // Get a histogram using data in persistent storage. | 443 // Get a histogram using data in persistent storage. |
| 431 static HistogramBase* PersistentGet(const std::string& name, | 444 static HistogramBase* PersistentGet(const std::string& name, |
| 432 const BucketRanges* ranges, | 445 const BucketRanges* ranges, |
| 433 HistogramBase::AtomicCount* counts, | 446 HistogramBase::AtomicCount* counts, |
| 434 HistogramSamples::Metadata* meta); | 447 HistogramBase::AtomicCount* logged_counts, |
| 448 HistogramSamples::Metadata* meta, |
| 449 HistogramSamples::Metadata* logged_meta); |
| 435 | 450 |
| 436 HistogramType GetHistogramType() const override; | 451 HistogramType GetHistogramType() const override; |
| 437 | 452 |
| 438 protected: | 453 protected: |
| 439 class Factory; | 454 class Factory; |
| 440 | 455 |
| 441 private: | 456 private: |
| 442 BooleanHistogram(const std::string& name, const BucketRanges* ranges); | 457 BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
| 443 BooleanHistogram(const std::string& name, | 458 BooleanHistogram(const std::string& name, |
| 444 const BucketRanges* ranges, | 459 const BucketRanges* ranges, |
| 445 HistogramBase::AtomicCount* counts, | 460 HistogramBase::AtomicCount* counts, |
| 446 HistogramSamples::Metadata* meta); | 461 HistogramBase::AtomicCount* logged_counts, |
| 462 HistogramSamples::Metadata* meta, |
| 463 HistogramSamples::Metadata* logged_meta); |
| 447 | 464 |
| 448 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 465 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
| 449 base::PickleIterator* iter); | 466 base::PickleIterator* iter); |
| 450 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 467 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
| 451 | 468 |
| 452 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); | 469 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
| 453 }; | 470 }; |
| 454 | 471 |
| 455 //------------------------------------------------------------------------------ | 472 //------------------------------------------------------------------------------ |
| 456 | 473 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 469 // to avoid code bloat from the std::string constructor being inlined into | 486 // to avoid code bloat from the std::string constructor being inlined into |
| 470 // call sites. | 487 // call sites. |
| 471 static HistogramBase* FactoryGet(const char* name, | 488 static HistogramBase* FactoryGet(const char* name, |
| 472 const std::vector<Sample>& custom_ranges, | 489 const std::vector<Sample>& custom_ranges, |
| 473 int32_t flags); | 490 int32_t flags); |
| 474 | 491 |
| 475 // Get a histogram using data in persistent storage. | 492 // Get a histogram using data in persistent storage. |
| 476 static HistogramBase* PersistentGet(const std::string& name, | 493 static HistogramBase* PersistentGet(const std::string& name, |
| 477 const BucketRanges* ranges, | 494 const BucketRanges* ranges, |
| 478 HistogramBase::AtomicCount* counts, | 495 HistogramBase::AtomicCount* counts, |
| 496 HistogramBase::AtomicCount* logged_counts, |
| 479 uint32_t counts_size, | 497 uint32_t counts_size, |
| 480 HistogramSamples::Metadata* meta); | 498 HistogramSamples::Metadata* meta, |
| 499 HistogramSamples::Metadata* logged_meta); |
| 481 | 500 |
| 482 // Overridden from Histogram: | 501 // Overridden from Histogram: |
| 483 HistogramType GetHistogramType() const override; | 502 HistogramType GetHistogramType() const override; |
| 484 | 503 |
| 485 // Helper method for transforming an array of valid enumeration values | 504 // Helper method for transforming an array of valid enumeration values |
| 486 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. | 505 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. |
| 487 // This function ensures that a guard bucket exists right after any | 506 // This function ensures that a guard bucket exists right after any |
| 488 // valid sample value (unless the next higher sample is also a valid value), | 507 // valid sample value (unless the next higher sample is also a valid value), |
| 489 // so that invalid samples never fall into the same bucket as valid samples. | 508 // so that invalid samples never fall into the same bucket as valid samples. |
| 490 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. | 509 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. |
| 491 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, | 510 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
| 492 uint32_t num_values); | 511 uint32_t num_values); |
| 493 protected: | 512 protected: |
| 494 class Factory; | 513 class Factory; |
| 495 | 514 |
| 496 CustomHistogram(const std::string& name, | 515 CustomHistogram(const std::string& name, |
| 497 const BucketRanges* ranges); | 516 const BucketRanges* ranges); |
| 498 | 517 |
| 499 CustomHistogram(const std::string& name, | 518 CustomHistogram(const std::string& name, |
| 500 const BucketRanges* ranges, | 519 const BucketRanges* ranges, |
| 501 HistogramBase::AtomicCount* counts, | 520 HistogramBase::AtomicCount* counts, |
| 521 HistogramBase::AtomicCount* logged_counts, |
| 502 uint32_t counts_size, | 522 uint32_t counts_size, |
| 503 HistogramSamples::Metadata* meta); | 523 HistogramSamples::Metadata* meta, |
| 524 HistogramSamples::Metadata* logged_meta); |
| 504 | 525 |
| 505 // HistogramBase implementation: | 526 // HistogramBase implementation: |
| 506 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 527 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
| 507 | 528 |
| 508 double GetBucketSize(Count current, uint32_t i) const override; | 529 double GetBucketSize(Count current, uint32_t i) const override; |
| 509 | 530 |
| 510 private: | 531 private: |
| 511 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 532 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
| 512 base::PickleIterator* iter); | 533 base::PickleIterator* iter); |
| 513 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 534 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
| 514 | 535 |
| 515 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | 536 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
| 516 | 537 |
| 517 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 538 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
| 518 }; | 539 }; |
| 519 | 540 |
| 520 } // namespace base | 541 } // namespace base |
| 521 | 542 |
| 522 #endif // BASE_METRICS_HISTOGRAM_H_ | 543 #endif // BASE_METRICS_HISTOGRAM_H_ |
| OLD | NEW |