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