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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 #include "base/metrics/histogram_macros.h" | 85 #include "base/metrics/histogram_macros.h" |
86 #include "base/metrics/histogram_samples.h" | 86 #include "base/metrics/histogram_samples.h" |
87 #include "base/time/time.h" | 87 #include "base/time/time.h" |
88 | 88 |
89 namespace base { | 89 namespace base { |
90 | 90 |
91 class BooleanHistogram; | 91 class BooleanHistogram; |
92 class CustomHistogram; | 92 class CustomHistogram; |
93 class Histogram; | 93 class Histogram; |
94 class LinearHistogram; | 94 class LinearHistogram; |
| 95 class PersistentMemoryAllocator; |
95 class Pickle; | 96 class Pickle; |
96 class PickleIterator; | 97 class PickleIterator; |
97 class SampleVector; | 98 class SampleVector; |
98 | 99 |
99 class BASE_EXPORT Histogram : public HistogramBase { | 100 class BASE_EXPORT Histogram : public HistogramBase { |
100 public: | 101 public: |
101 // Initialize maximum number of buckets in histograms as 16,384. | 102 // Initialize maximum number of buckets in histograms as 16,384. |
102 static const size_t kBucketCount_MAX; | 103 static const size_t kBucketCount_MAX; |
103 | 104 |
104 typedef std::vector<Count> Counts; | 105 typedef std::vector<Count> Counts; |
(...skipping 26 matching lines...) Expand all Loading... |
131 Sample minimum, | 132 Sample minimum, |
132 Sample maximum, | 133 Sample maximum, |
133 size_t bucket_count, | 134 size_t bucket_count, |
134 int32_t flags); | 135 int32_t flags); |
135 static HistogramBase* FactoryTimeGet(const char* name, | 136 static HistogramBase* FactoryTimeGet(const char* name, |
136 base::TimeDelta minimum, | 137 base::TimeDelta minimum, |
137 base::TimeDelta maximum, | 138 base::TimeDelta maximum, |
138 size_t bucket_count, | 139 size_t bucket_count, |
139 int32_t flags); | 140 int32_t flags); |
140 | 141 |
| 142 // Get a histogram using data in persistent storage. |
| 143 static HistogramBase* PersistentGet(const std::string& name, |
| 144 Sample minimum, |
| 145 Sample maximum, |
| 146 const BucketRanges* ranges, |
| 147 HistogramBase::AtomicCount* counts, |
| 148 size_t counts_size, |
| 149 HistogramSamples::Metadata* meta); |
| 150 |
141 static void InitializeBucketRanges(Sample minimum, | 151 static void InitializeBucketRanges(Sample minimum, |
142 Sample maximum, | 152 Sample maximum, |
143 BucketRanges* ranges); | 153 BucketRanges* ranges); |
144 | 154 |
145 // This constant if for FindCorruption. Since snapshots of histograms are | 155 // This constant if for FindCorruption. Since snapshots of histograms are |
146 // taken asynchronously relative to sampling, and our counting code currently | 156 // taken asynchronously relative to sampling, and our counting code currently |
147 // 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 |
148 // redundant count that doesn't match the sample count. We allow for a | 158 // redundant count that doesn't match the sample count. We allow for a |
149 // certain amount of slop before flagging this as an inconsistency. Even with | 159 // certain amount of slop before flagging this as an inconsistency. Even with |
150 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), | 160 // an inconsistency, we'll snapshot it again (for UMA in about a half hour), |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 size_t expected_bucket_count) const override; | 196 size_t expected_bucket_count) const override; |
187 void Add(Sample value) override; | 197 void Add(Sample value) override; |
188 void AddCount(Sample value, int count) override; | 198 void AddCount(Sample value, int count) override; |
189 scoped_ptr<HistogramSamples> SnapshotSamples() const override; | 199 scoped_ptr<HistogramSamples> SnapshotSamples() const override; |
190 void AddSamples(const HistogramSamples& samples) override; | 200 void AddSamples(const HistogramSamples& samples) override; |
191 bool AddSamplesFromPickle(base::PickleIterator* iter) override; | 201 bool AddSamplesFromPickle(base::PickleIterator* iter) override; |
192 void WriteHTMLGraph(std::string* output) const override; | 202 void WriteHTMLGraph(std::string* output) const override; |
193 void WriteAscii(std::string* output) const override; | 203 void WriteAscii(std::string* output) const override; |
194 | 204 |
195 protected: | 205 protected: |
| 206 // This class, defined entirely within the .cc file, contains all the |
| 207 // 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 |
| 209 // defined as an embedded class (rather than an anonymous one) so it |
| 210 // can access the protected constructors. |
| 211 class Factory; |
| 212 |
196 // |ranges| should contain the underflow and overflow buckets. See top | 213 // |ranges| should contain the underflow and overflow buckets. See top |
197 // comments for example. | 214 // comments for example. |
198 Histogram(const std::string& name, | 215 Histogram(const std::string& name, |
199 Sample minimum, | 216 Sample minimum, |
200 Sample maximum, | 217 Sample maximum, |
201 const BucketRanges* ranges); | 218 const BucketRanges* ranges); |
202 | 219 |
| 220 // Traditionally, histograms allocate their own memory for the bucket |
| 221 // vector but "shared" histograms use memory regions allocated from a |
| 222 // 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 |
| 224 // of this object. Practically, this memory is never released until the |
| 225 // process exits and the OS cleans it up. |
| 226 Histogram(const std::string& name, |
| 227 Sample minimum, |
| 228 Sample maximum, |
| 229 const BucketRanges* ranges, |
| 230 HistogramBase::AtomicCount* counts, |
| 231 size_t counts_size, |
| 232 HistogramSamples::Metadata* meta); |
| 233 |
203 ~Histogram() override; | 234 ~Histogram() override; |
204 | 235 |
205 // HistogramBase implementation: | 236 // HistogramBase implementation: |
206 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 237 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
207 | 238 |
208 // Method to override to skip the display of the i'th bucket if it's empty. | 239 // Method to override to skip the display of the i'th bucket if it's empty. |
209 virtual bool PrintEmptyBucket(size_t index) const; | 240 virtual bool PrintEmptyBucket(size_t index) const; |
210 | 241 |
211 // Get normalized size, relative to the ranges(i). | 242 // Get normalized size, relative to the ranges(i). |
212 virtual double GetBucketSize(Count current, size_t i) const; | 243 virtual double GetBucketSize(Count current, size_t i) const; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 Sample minimum, | 334 Sample minimum, |
304 Sample maximum, | 335 Sample maximum, |
305 size_t bucket_count, | 336 size_t bucket_count, |
306 int32_t flags); | 337 int32_t flags); |
307 static HistogramBase* FactoryTimeGet(const char* name, | 338 static HistogramBase* FactoryTimeGet(const char* name, |
308 TimeDelta minimum, | 339 TimeDelta minimum, |
309 TimeDelta maximum, | 340 TimeDelta maximum, |
310 size_t bucket_count, | 341 size_t bucket_count, |
311 int32_t flags); | 342 int32_t flags); |
312 | 343 |
| 344 // Get a histogram using data in persistent storage. |
| 345 static HistogramBase* PersistentGet(const std::string& name, |
| 346 Sample minimum, |
| 347 Sample maximum, |
| 348 const BucketRanges* ranges, |
| 349 HistogramBase::AtomicCount* counts, |
| 350 size_t counts_size, |
| 351 HistogramSamples::Metadata* meta); |
| 352 |
313 struct DescriptionPair { | 353 struct DescriptionPair { |
314 Sample sample; | 354 Sample sample; |
315 const char* description; // Null means end of a list of pairs. | 355 const char* description; // Null means end of a list of pairs. |
316 }; | 356 }; |
317 | 357 |
318 // Create a LinearHistogram and store a list of number/text values for use in | 358 // Create a LinearHistogram and store a list of number/text values for use in |
319 // writing the histogram graph. | 359 // writing the histogram graph. |
320 // |descriptions| can be NULL, which means no special descriptions to set. If | 360 // |descriptions| can be NULL, which means no special descriptions to set. If |
321 // it's not NULL, the last element in the array must has a NULL in its | 361 // it's not NULL, the last element in the array must has a NULL in its |
322 // "description" field. | 362 // "description" field. |
323 static HistogramBase* FactoryGetWithRangeDescription( | 363 static HistogramBase* FactoryGetWithRangeDescription( |
324 const std::string& name, | 364 const std::string& name, |
325 Sample minimum, | 365 Sample minimum, |
326 Sample maximum, | 366 Sample maximum, |
327 size_t bucket_count, | 367 size_t bucket_count, |
328 int32_t flags, | 368 int32_t flags, |
329 const DescriptionPair descriptions[]); | 369 const DescriptionPair descriptions[]); |
330 | 370 |
331 static void InitializeBucketRanges(Sample minimum, | 371 static void InitializeBucketRanges(Sample minimum, |
332 Sample maximum, | 372 Sample maximum, |
333 BucketRanges* ranges); | 373 BucketRanges* ranges); |
334 | 374 |
335 // Overridden from Histogram: | 375 // Overridden from Histogram: |
336 HistogramType GetHistogramType() const override; | 376 HistogramType GetHistogramType() const override; |
337 | 377 |
338 protected: | 378 protected: |
| 379 class Factory; |
| 380 |
339 LinearHistogram(const std::string& name, | 381 LinearHistogram(const std::string& name, |
340 Sample minimum, | 382 Sample minimum, |
341 Sample maximum, | 383 Sample maximum, |
342 const BucketRanges* ranges); | 384 const BucketRanges* ranges); |
343 | 385 |
| 386 LinearHistogram(const std::string& name, |
| 387 Sample minimum, |
| 388 Sample maximum, |
| 389 const BucketRanges* ranges, |
| 390 HistogramBase::AtomicCount* counts, |
| 391 size_t counts_size, |
| 392 HistogramSamples::Metadata* meta); |
| 393 |
344 double GetBucketSize(Count current, size_t i) const override; | 394 double GetBucketSize(Count current, size_t i) const override; |
345 | 395 |
346 // If we have a description for a bucket, then return that. Otherwise | 396 // If we have a description for a bucket, then return that. Otherwise |
347 // let parent class provide a (numeric) description. | 397 // let parent class provide a (numeric) description. |
348 const std::string GetAsciiBucketRange(size_t i) const override; | 398 const std::string GetAsciiBucketRange(size_t i) const override; |
349 | 399 |
350 // Skip printing of name for numeric range if we have a name (and if this is | 400 // Skip printing of name for numeric range if we have a name (and if this is |
351 // an empty bucket). | 401 // an empty bucket). |
352 bool PrintEmptyBucket(size_t index) const override; | 402 bool PrintEmptyBucket(size_t index) const override; |
353 | 403 |
(...skipping 16 matching lines...) Expand all Loading... |
370 // BooleanHistogram is a histogram for booleans. | 420 // BooleanHistogram is a histogram for booleans. |
371 class BASE_EXPORT BooleanHistogram : public LinearHistogram { | 421 class BASE_EXPORT BooleanHistogram : public LinearHistogram { |
372 public: | 422 public: |
373 static HistogramBase* FactoryGet(const std::string& name, int32_t flags); | 423 static HistogramBase* FactoryGet(const std::string& name, int32_t flags); |
374 | 424 |
375 // Overload of the above function that takes a const char* |name| param, | 425 // Overload of the above function that takes a const char* |name| param, |
376 // to avoid code bloat from the std::string constructor being inlined into | 426 // to avoid code bloat from the std::string constructor being inlined into |
377 // call sites. | 427 // call sites. |
378 static HistogramBase* FactoryGet(const char* name, int32_t flags); | 428 static HistogramBase* FactoryGet(const char* name, int32_t flags); |
379 | 429 |
| 430 // Get a histogram using data in persistent storage. |
| 431 static HistogramBase* PersistentGet(const std::string& name, |
| 432 const BucketRanges* ranges, |
| 433 HistogramBase::AtomicCount* counts, |
| 434 HistogramSamples::Metadata* meta); |
| 435 |
380 HistogramType GetHistogramType() const override; | 436 HistogramType GetHistogramType() const override; |
381 | 437 |
| 438 protected: |
| 439 class Factory; |
| 440 |
382 private: | 441 private: |
383 BooleanHistogram(const std::string& name, const BucketRanges* ranges); | 442 BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
| 443 BooleanHistogram(const std::string& name, |
| 444 const BucketRanges* ranges, |
| 445 HistogramBase::AtomicCount* counts, |
| 446 HistogramSamples::Metadata* meta); |
384 | 447 |
385 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 448 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
386 base::PickleIterator* iter); | 449 base::PickleIterator* iter); |
387 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 450 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
388 | 451 |
389 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); | 452 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
390 }; | 453 }; |
391 | 454 |
392 //------------------------------------------------------------------------------ | 455 //------------------------------------------------------------------------------ |
393 | 456 |
394 // CustomHistogram is a histogram for a set of custom integers. | 457 // CustomHistogram is a histogram for a set of custom integers. |
395 class BASE_EXPORT CustomHistogram : public Histogram { | 458 class BASE_EXPORT CustomHistogram : public Histogram { |
396 public: | 459 public: |
397 // |custom_ranges| contains a vector of limits on ranges. Each limit should be | 460 // |custom_ranges| contains a vector of limits on ranges. Each limit should be |
398 // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward | 461 // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward |
399 // compatibility). The limits can be unordered or contain duplication, but | 462 // compatibility). The limits can be unordered or contain duplication, but |
400 // client should not depend on this. | 463 // client should not depend on this. |
401 static HistogramBase* FactoryGet(const std::string& name, | 464 static HistogramBase* FactoryGet(const std::string& name, |
402 const std::vector<Sample>& custom_ranges, | 465 const std::vector<Sample>& custom_ranges, |
403 int32_t flags); | 466 int32_t flags); |
404 | 467 |
405 // Overload of the above function that takes a const char* |name| param, | 468 // Overload of the above function that takes a const char* |name| param, |
406 // to avoid code bloat from the std::string constructor being inlined into | 469 // to avoid code bloat from the std::string constructor being inlined into |
407 // call sites. | 470 // call sites. |
408 static HistogramBase* FactoryGet(const char* name, | 471 static HistogramBase* FactoryGet(const char* name, |
409 const std::vector<Sample>& custom_ranges, | 472 const std::vector<Sample>& custom_ranges, |
410 int32_t flags); | 473 int32_t flags); |
411 | 474 |
| 475 // Get a histogram using data in persistent storage. |
| 476 static HistogramBase* PersistentGet(const std::string& name, |
| 477 const BucketRanges* ranges, |
| 478 HistogramBase::AtomicCount* counts, |
| 479 size_t counts_size, |
| 480 HistogramSamples::Metadata* meta); |
| 481 |
412 // Overridden from Histogram: | 482 // Overridden from Histogram: |
413 HistogramType GetHistogramType() const override; | 483 HistogramType GetHistogramType() const override; |
414 | 484 |
415 // Helper method for transforming an array of valid enumeration values | 485 // Helper method for transforming an array of valid enumeration values |
416 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. | 486 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. |
417 // This function ensures that a guard bucket exists right after any | 487 // This function ensures that a guard bucket exists right after any |
418 // valid sample value (unless the next higher sample is also a valid value), | 488 // valid sample value (unless the next higher sample is also a valid value), |
419 // so that invalid samples never fall into the same bucket as valid samples. | 489 // so that invalid samples never fall into the same bucket as valid samples. |
420 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. | 490 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. |
421 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, | 491 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
422 size_t num_values); | 492 size_t num_values); |
423 protected: | 493 protected: |
| 494 class Factory; |
| 495 |
424 CustomHistogram(const std::string& name, | 496 CustomHistogram(const std::string& name, |
425 const BucketRanges* ranges); | 497 const BucketRanges* ranges); |
426 | 498 |
| 499 CustomHistogram(const std::string& name, |
| 500 const BucketRanges* ranges, |
| 501 HistogramBase::AtomicCount* counts, |
| 502 size_t counts_size, |
| 503 HistogramSamples::Metadata* meta); |
| 504 |
427 // HistogramBase implementation: | 505 // HistogramBase implementation: |
428 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 506 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
429 | 507 |
430 double GetBucketSize(Count current, size_t i) const override; | 508 double GetBucketSize(Count current, size_t i) const override; |
431 | 509 |
432 private: | 510 private: |
433 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 511 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
434 base::PickleIterator* iter); | 512 base::PickleIterator* iter); |
435 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 513 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
436 | 514 |
437 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | 515 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
438 static BucketRanges* CreateBucketRangesFromCustomRanges( | |
439 const std::vector<Sample>& custom_ranges); | |
440 | 516 |
441 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 517 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
442 }; | 518 }; |
443 | 519 |
444 } // namespace base | 520 } // namespace base |
445 | 521 |
446 #endif // BASE_METRICS_HISTOGRAM_H_ | 522 #endif // BASE_METRICS_HISTOGRAM_H_ |
OLD | NEW |