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 |
| 100 struct PersistentHistogramData; |
| 101 |
99 class BASE_EXPORT Histogram : public HistogramBase { | 102 class BASE_EXPORT Histogram : public HistogramBase { |
100 public: | 103 public: |
101 // Initialize maximum number of buckets in histograms as 16,384. | 104 // Initialize maximum number of buckets in histograms as 16,384. |
102 static const size_t kBucketCount_MAX; | 105 static const size_t kBucketCount_MAX; |
103 | 106 |
104 typedef std::vector<Count> Counts; | 107 typedef std::vector<Count> Counts; |
105 | 108 |
106 //---------------------------------------------------------------------------- | 109 //---------------------------------------------------------------------------- |
107 // For a valid histogram, input should follow these restrictions: | 110 // For a valid histogram, input should follow these restrictions: |
108 // minimum > 0 (if a minimum below 1 is specified, it will implicitly be | 111 // minimum > 0 (if a minimum below 1 is specified, it will implicitly be |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 size_t expected_bucket_count) const override; | 189 size_t expected_bucket_count) const override; |
187 void Add(Sample value) override; | 190 void Add(Sample value) override; |
188 void AddCount(Sample value, int count) override; | 191 void AddCount(Sample value, int count) override; |
189 scoped_ptr<HistogramSamples> SnapshotSamples() const override; | 192 scoped_ptr<HistogramSamples> SnapshotSamples() const override; |
190 void AddSamples(const HistogramSamples& samples) override; | 193 void AddSamples(const HistogramSamples& samples) override; |
191 bool AddSamplesFromPickle(base::PickleIterator* iter) override; | 194 bool AddSamplesFromPickle(base::PickleIterator* iter) override; |
192 void WriteHTMLGraph(std::string* output) const override; | 195 void WriteHTMLGraph(std::string* output) const override; |
193 void WriteAscii(std::string* output) const override; | 196 void WriteAscii(std::string* output) const override; |
194 | 197 |
195 protected: | 198 protected: |
| 199 // This class, defined entirely within the .cc file, contains all the |
| 200 // common logic for building a Histogram and can be overridden by more |
| 201 // specific types to alter details of how the creation is done. It is |
| 202 // defined as an embedded class (rather than an anonymous one) so it |
| 203 // can access the protected constructors. |
| 204 class Factory; |
| 205 |
196 // |ranges| should contain the underflow and overflow buckets. See top | 206 // |ranges| should contain the underflow and overflow buckets. See top |
197 // comments for example. | 207 // comments for example. |
198 Histogram(const std::string& name, | 208 Histogram(const std::string& name, |
199 Sample minimum, | 209 Sample minimum, |
200 Sample maximum, | 210 Sample maximum, |
201 const BucketRanges* ranges); | 211 const BucketRanges* ranges); |
202 | 212 |
| 213 // Traditionally, histograms allocate their own memory for the bucket |
| 214 // vector but "shared" histograms use memory regions allocated from a |
| 215 // special memory segment that is passed in here. It is assumed that |
| 216 // the life of this memory is managed externally and exceeds the lifetime |
| 217 // of this object. Practically, this memory is never released until the |
| 218 // process exits and the OS cleans it up. |
| 219 Histogram(const std::string& name, |
| 220 Sample minimum, |
| 221 Sample maximum, |
| 222 const BucketRanges* ranges, |
| 223 HistogramBase::AtomicCount* counts, |
| 224 size_t counts_size, |
| 225 HistogramSamples::Metadata* meta); |
| 226 |
203 ~Histogram() override; | 227 ~Histogram() override; |
204 | 228 |
205 // HistogramBase implementation: | 229 // HistogramBase implementation: |
206 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 230 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
207 | 231 |
208 // Method to override to skip the display of the i'th bucket if it's empty. | 232 // Method to override to skip the display of the i'th bucket if it's empty. |
209 virtual bool PrintEmptyBucket(size_t index) const; | 233 virtual bool PrintEmptyBucket(size_t index) const; |
210 | 234 |
211 // Get normalized size, relative to the ranges(i). | 235 // Get normalized size, relative to the ranges(i). |
212 virtual double GetBucketSize(Count current, size_t i) const; | 236 virtual double GetBucketSize(Count current, size_t i) const; |
213 | 237 |
214 // Return a string description of what goes in a given bucket. | 238 // Return a string description of what goes in a given bucket. |
215 // Most commonly this is the numeric value, but in derived classes it may | 239 // Most commonly this is the numeric value, but in derived classes it may |
216 // be a name (or string description) given to the bucket. | 240 // be a name (or string description) given to the bucket. |
217 virtual const std::string GetAsciiBucketRange(size_t it) const; | 241 virtual const std::string GetAsciiBucketRange(size_t it) const; |
218 | 242 |
219 private: | 243 private: |
220 // Allow tests to corrupt our innards for testing purposes. | 244 // Allow tests to corrupt our innards for testing purposes. |
221 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest); | 245 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest); |
222 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest); | 246 FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest); |
223 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); | 247 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptBucketBounds); |
224 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); | 248 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); |
225 FRIEND_TEST_ALL_PREFIXES(HistogramTest, NameMatchTest); | 249 FRIEND_TEST_ALL_PREFIXES(HistogramTest, NameMatchTest); |
226 FRIEND_TEST_ALL_PREFIXES(HistogramTest, AddCountTest); | 250 FRIEND_TEST_ALL_PREFIXES(HistogramTest, AddCountTest); |
227 | 251 |
228 friend class StatisticsRecorder; // To allow it to delete duplicates. | 252 friend class StatisticsRecorder; // To allow it to delete duplicates. |
229 friend class StatisticsRecorderTest; | 253 friend class StatisticsRecorderTest; |
230 | 254 |
| 255 friend BASE_EXPORT HistogramBase* CreatePersistentHistogram( |
| 256 PersistentMemoryAllocator* allocator, |
| 257 PersistentHistogramData* histogram_data); |
231 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 258 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
232 base::PickleIterator* iter); | 259 base::PickleIterator* iter); |
233 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 260 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
234 | 261 |
235 // Implementation of SnapshotSamples function. | 262 // Implementation of SnapshotSamples function. |
236 scoped_ptr<SampleVector> SnapshotSampleVector() const; | 263 scoped_ptr<SampleVector> SnapshotSampleVector() const; |
237 | 264 |
238 //---------------------------------------------------------------------------- | 265 //---------------------------------------------------------------------------- |
239 // Helpers for emitting Ascii graphic. Each method appends data to output. | 266 // Helpers for emitting Ascii graphic. Each method appends data to output. |
240 | 267 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 const DescriptionPair descriptions[]); | 359 const DescriptionPair descriptions[]); |
333 | 360 |
334 static void InitializeBucketRanges(Sample minimum, | 361 static void InitializeBucketRanges(Sample minimum, |
335 Sample maximum, | 362 Sample maximum, |
336 BucketRanges* ranges); | 363 BucketRanges* ranges); |
337 | 364 |
338 // Overridden from Histogram: | 365 // Overridden from Histogram: |
339 HistogramType GetHistogramType() const override; | 366 HistogramType GetHistogramType() const override; |
340 | 367 |
341 protected: | 368 protected: |
| 369 class Factory; |
| 370 |
342 LinearHistogram(const std::string& name, | 371 LinearHistogram(const std::string& name, |
343 Sample minimum, | 372 Sample minimum, |
344 Sample maximum, | 373 Sample maximum, |
345 const BucketRanges* ranges); | 374 const BucketRanges* ranges); |
346 | 375 |
| 376 LinearHistogram(const std::string& name, |
| 377 Sample minimum, |
| 378 Sample maximum, |
| 379 const BucketRanges* ranges, |
| 380 HistogramBase::AtomicCount* counts, |
| 381 size_t counts_size, |
| 382 HistogramSamples::Metadata* meta); |
| 383 |
347 double GetBucketSize(Count current, size_t i) const override; | 384 double GetBucketSize(Count current, size_t i) const override; |
348 | 385 |
349 // If we have a description for a bucket, then return that. Otherwise | 386 // If we have a description for a bucket, then return that. Otherwise |
350 // let parent class provide a (numeric) description. | 387 // let parent class provide a (numeric) description. |
351 const std::string GetAsciiBucketRange(size_t i) const override; | 388 const std::string GetAsciiBucketRange(size_t i) const override; |
352 | 389 |
353 // Skip printing of name for numeric range if we have a name (and if this is | 390 // Skip printing of name for numeric range if we have a name (and if this is |
354 // an empty bucket). | 391 // an empty bucket). |
355 bool PrintEmptyBucket(size_t index) const override; | 392 bool PrintEmptyBucket(size_t index) const override; |
356 | 393 |
357 private: | 394 private: |
| 395 friend BASE_EXPORT HistogramBase* CreatePersistentHistogram( |
| 396 PersistentMemoryAllocator* allocator, |
| 397 PersistentHistogramData* histogram_data); |
358 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 398 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
359 base::PickleIterator* iter); | 399 base::PickleIterator* iter); |
360 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 400 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
361 | 401 |
362 // For some ranges, we store a printable description of a bucket range. | 402 // For some ranges, we store a printable description of a bucket range. |
363 // If there is no description, then GetAsciiBucketRange() uses parent class | 403 // If there is no description, then GetAsciiBucketRange() uses parent class |
364 // to provide a description. | 404 // to provide a description. |
365 typedef std::map<Sample, std::string> BucketDescriptionMap; | 405 typedef std::map<Sample, std::string> BucketDescriptionMap; |
366 BucketDescriptionMap bucket_description_; | 406 BucketDescriptionMap bucket_description_; |
367 | 407 |
368 DISALLOW_COPY_AND_ASSIGN(LinearHistogram); | 408 DISALLOW_COPY_AND_ASSIGN(LinearHistogram); |
369 }; | 409 }; |
370 | 410 |
371 //------------------------------------------------------------------------------ | 411 //------------------------------------------------------------------------------ |
372 | 412 |
373 // BooleanHistogram is a histogram for booleans. | 413 // BooleanHistogram is a histogram for booleans. |
374 class BASE_EXPORT BooleanHistogram : public LinearHistogram { | 414 class BASE_EXPORT BooleanHistogram : public LinearHistogram { |
375 public: | 415 public: |
376 static HistogramBase* FactoryGet(const std::string& name, int32_t flags); | 416 static HistogramBase* FactoryGet(const std::string& name, int32_t flags); |
377 | 417 |
378 // Overload of the above function that takes a const char* |name| param, | 418 // Overload of the above function that takes a const char* |name| param, |
379 // to avoid code bloat from the std::string constructor being inlined into | 419 // to avoid code bloat from the std::string constructor being inlined into |
380 // call sites. | 420 // call sites. |
381 static HistogramBase* FactoryGet(const char* name, int32_t flags); | 421 static HistogramBase* FactoryGet(const char* name, int32_t flags); |
382 | 422 |
383 HistogramType GetHistogramType() const override; | 423 HistogramType GetHistogramType() const override; |
384 | 424 |
| 425 protected: |
| 426 class Factory; |
| 427 |
385 private: | 428 private: |
386 BooleanHistogram(const std::string& name, const BucketRanges* ranges); | 429 BooleanHistogram(const std::string& name, const BucketRanges* ranges); |
| 430 BooleanHistogram(const std::string& name, |
| 431 const BucketRanges* ranges, |
| 432 HistogramBase::AtomicCount* counts, |
| 433 HistogramSamples::Metadata* meta); |
387 | 434 |
| 435 friend BASE_EXPORT HistogramBase* CreatePersistentHistogram( |
| 436 PersistentMemoryAllocator* allocator, |
| 437 PersistentHistogramData* histogram_data); |
388 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 438 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
389 base::PickleIterator* iter); | 439 base::PickleIterator* iter); |
390 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 440 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
391 | 441 |
392 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); | 442 DISALLOW_COPY_AND_ASSIGN(BooleanHistogram); |
393 }; | 443 }; |
394 | 444 |
395 //------------------------------------------------------------------------------ | 445 //------------------------------------------------------------------------------ |
396 | 446 |
397 // CustomHistogram is a histogram for a set of custom integers. | 447 // CustomHistogram is a histogram for a set of custom integers. |
(...skipping 19 matching lines...) Expand all Loading... |
417 | 467 |
418 // Helper method for transforming an array of valid enumeration values | 468 // Helper method for transforming an array of valid enumeration values |
419 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. | 469 // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION. |
420 // This function ensures that a guard bucket exists right after any | 470 // This function ensures that a guard bucket exists right after any |
421 // valid sample value (unless the next higher sample is also a valid value), | 471 // valid sample value (unless the next higher sample is also a valid value), |
422 // so that invalid samples never fall into the same bucket as valid samples. | 472 // so that invalid samples never fall into the same bucket as valid samples. |
423 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. | 473 // TODO(kaiwang): Change name to ArrayToCustomEnumRanges. |
424 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, | 474 static std::vector<Sample> ArrayToCustomRanges(const Sample* values, |
425 size_t num_values); | 475 size_t num_values); |
426 protected: | 476 protected: |
| 477 class Factory; |
| 478 |
427 CustomHistogram(const std::string& name, | 479 CustomHistogram(const std::string& name, |
428 const BucketRanges* ranges); | 480 const BucketRanges* ranges); |
429 | 481 |
| 482 CustomHistogram(const std::string& name, |
| 483 const BucketRanges* ranges, |
| 484 HistogramBase::AtomicCount* counts, |
| 485 size_t counts_size, |
| 486 HistogramSamples::Metadata* meta); |
| 487 |
430 // HistogramBase implementation: | 488 // HistogramBase implementation: |
431 bool SerializeInfoImpl(base::Pickle* pickle) const override; | 489 bool SerializeInfoImpl(base::Pickle* pickle) const override; |
432 | 490 |
433 double GetBucketSize(Count current, size_t i) const override; | 491 double GetBucketSize(Count current, size_t i) const override; |
434 | 492 |
435 private: | 493 private: |
| 494 friend BASE_EXPORT HistogramBase* CreatePersistentHistogram( |
| 495 PersistentMemoryAllocator* allocator, |
| 496 PersistentHistogramData* histogram_data); |
436 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( | 497 friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo( |
437 base::PickleIterator* iter); | 498 base::PickleIterator* iter); |
438 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); | 499 static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter); |
439 | 500 |
440 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); | 501 static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges); |
441 static BucketRanges* CreateBucketRangesFromCustomRanges( | |
442 const std::vector<Sample>& custom_ranges); | |
443 | 502 |
444 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); | 503 DISALLOW_COPY_AND_ASSIGN(CustomHistogram); |
445 }; | 504 }; |
446 | 505 |
447 } // namespace base | 506 } // namespace base |
448 | 507 |
449 #endif // BASE_METRICS_HISTOGRAM_H_ | 508 #endif // BASE_METRICS_HISTOGRAM_H_ |
OLD | NEW |