| 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 // See header file for details and examples. | 8 // See header file for details and examples. |
| 9 | 9 |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 if (next > current) | 167 if (next > current) |
| 168 current = next; | 168 current = next; |
| 169 else | 169 else |
| 170 ++current; // Just do a narrow bucket, and keep trying. | 170 ++current; // Just do a narrow bucket, and keep trying. |
| 171 ranges->set_range(bucket_index, current); | 171 ranges->set_range(bucket_index, current); |
| 172 } | 172 } |
| 173 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); | 173 ranges->set_range(ranges->size() - 1, HistogramBase::kSampleType_MAX); |
| 174 ranges->ResetChecksum(); | 174 ranges->ResetChecksum(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 void Histogram::Add(int value) { | |
| 178 DCHECK_EQ(0, ranges(0)); | |
| 179 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_)); | |
| 180 | |
| 181 if (value > kSampleType_MAX - 1) | |
| 182 value = kSampleType_MAX - 1; | |
| 183 if (value < 0) | |
| 184 value = 0; | |
| 185 samples_->Accumulate(value, 1); | |
| 186 } | |
| 187 | |
| 188 void Histogram::AddBoolean(bool value) { | 177 void Histogram::AddBoolean(bool value) { |
| 189 DCHECK(false); | 178 DCHECK(false); |
| 190 } | 179 } |
| 191 | 180 |
| 192 void Histogram::AddSamples(const HistogramSamples& samples) { | 181 void Histogram::AddSamples(const HistogramSamples& samples) { |
| 193 samples_->Add(samples); | 182 samples_->Add(samples); |
| 194 } | 183 } |
| 195 | 184 |
| 196 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { | 185 bool Histogram::AddSamplesFromPickle(PickleIterator* iter) { |
| 197 return samples_->AddFromPickle(iter); | 186 return samples_->AddFromPickle(iter); |
| 198 } | 187 } |
| 199 | 188 |
| 200 void Histogram::SetRangeDescriptions(const DescriptionPair descriptions[]) { | 189 void Histogram::SetRangeDescriptions(const DescriptionPair descriptions[]) { |
| 201 DCHECK(false); | 190 DCHECK(false); |
| 202 } | 191 } |
| 203 | 192 |
| 204 // The following methods provide a graphical histogram display. | |
| 205 void Histogram::WriteHTMLGraph(string* output) const { | |
| 206 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. | |
| 207 output->append("<PRE>"); | |
| 208 WriteAsciiImpl(true, "<br>", output); | |
| 209 output->append("</PRE>"); | |
| 210 } | |
| 211 | |
| 212 void Histogram::WriteAscii(string* output) const { | |
| 213 WriteAsciiImpl(true, "\n", output); | |
| 214 } | |
| 215 | |
| 216 // static | 193 // static |
| 217 string Histogram::SerializeHistogramInfo(const Histogram& histogram, | 194 string Histogram::SerializeHistogramInfo(const Histogram& histogram, |
| 218 const HistogramSamples& snapshot) { | 195 const HistogramSamples& snapshot) { |
| 219 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram.histogram_type()); | 196 DCHECK_NE(NOT_VALID_IN_RENDERER, histogram.histogram_type()); |
| 220 DCHECK(histogram.bucket_ranges()->HasValidChecksum()); | 197 DCHECK(histogram.bucket_ranges()->HasValidChecksum()); |
| 221 | 198 |
| 222 Pickle pickle; | 199 Pickle pickle; |
| 223 pickle.WriteString(histogram.histogram_name()); | 200 pickle.WriteString(histogram.histogram_name()); |
| 224 pickle.WriteInt(histogram.declared_min()); | 201 pickle.WriteInt(histogram.declared_min()); |
| 225 pickle.WriteInt(histogram.declared_max()); | 202 pickle.WriteInt(histogram.declared_max()); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 } | 337 } |
| 361 | 338 |
| 362 Sample Histogram::ranges(size_t i) const { | 339 Sample Histogram::ranges(size_t i) const { |
| 363 return bucket_ranges_->range(i); | 340 return bucket_ranges_->range(i); |
| 364 } | 341 } |
| 365 | 342 |
| 366 size_t Histogram::bucket_count() const { | 343 size_t Histogram::bucket_count() const { |
| 367 return bucket_count_; | 344 return bucket_count_; |
| 368 } | 345 } |
| 369 | 346 |
| 347 // static |
| 348 bool Histogram::InspectConstructionArguments(const string& name, |
| 349 Sample* minimum, |
| 350 Sample* maximum, |
| 351 size_t* bucket_count) { |
| 352 // Defensive code for backward compatibility. |
| 353 if (*minimum < 1) { |
| 354 DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum; |
| 355 *minimum = 1; |
| 356 } |
| 357 if (*maximum >= kSampleType_MAX) { |
| 358 DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum; |
| 359 *maximum = kSampleType_MAX - 1; |
| 360 } |
| 361 if (*bucket_count >= kBucketCount_MAX) { |
| 362 DVLOG(1) << "Histogram: " << name << " has bad bucket_count: " |
| 363 << *bucket_count; |
| 364 *bucket_count = kBucketCount_MAX - 1; |
| 365 } |
| 366 |
| 367 if (*minimum >= *maximum) |
| 368 return false; |
| 369 if (*bucket_count < 3) |
| 370 return false; |
| 371 if (*bucket_count > static_cast<size_t>(*maximum - *minimum + 2)) |
| 372 return false; |
| 373 return true; |
| 374 } |
| 375 |
| 376 bool Histogram::HasConstructionArguments(Sample minimum, |
| 377 Sample maximum, |
| 378 size_t bucket_count) const { |
| 379 return ((minimum == declared_min_) && (maximum == declared_max_) && |
| 380 (bucket_count == bucket_count_)); |
| 381 } |
| 382 |
| 383 void Histogram::Add(int value) { |
| 384 DCHECK_EQ(0, ranges(0)); |
| 385 DCHECK_EQ(kSampleType_MAX, ranges(bucket_count_)); |
| 386 |
| 387 if (value > kSampleType_MAX - 1) |
| 388 value = kSampleType_MAX - 1; |
| 389 if (value < 0) |
| 390 value = 0; |
| 391 samples_->Accumulate(value, 1); |
| 392 } |
| 393 |
| 370 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { | 394 scoped_ptr<HistogramSamples> Histogram::SnapshotSamples() const { |
| 371 return SnapshotSampleVector().PassAs<HistogramSamples>(); | 395 return SnapshotSampleVector().PassAs<HistogramSamples>(); |
| 372 } | 396 } |
| 373 | 397 |
| 374 bool Histogram::HasConstructionArguments(Sample minimum, | 398 // The following methods provide a graphical histogram display. |
| 375 Sample maximum, | 399 void Histogram::WriteHTMLGraph(string* output) const { |
| 376 size_t bucket_count) { | 400 // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc. |
| 377 return ((minimum == declared_min_) && (maximum == declared_max_) && | 401 output->append("<PRE>"); |
| 378 (bucket_count == bucket_count_)); | 402 WriteAsciiImpl(true, "<br>", output); |
| 403 output->append("</PRE>"); |
| 404 } |
| 405 |
| 406 void Histogram::WriteAscii(string* output) const { |
| 407 WriteAsciiImpl(true, "\n", output); |
| 379 } | 408 } |
| 380 | 409 |
| 381 Histogram::Histogram(const string& name, | 410 Histogram::Histogram(const string& name, |
| 382 Sample minimum, | 411 Sample minimum, |
| 383 Sample maximum, | 412 Sample maximum, |
| 384 size_t bucket_count, | 413 size_t bucket_count, |
| 385 const BucketRanges* ranges) | 414 const BucketRanges* ranges) |
| 386 : HistogramBase(name), | 415 : HistogramBase(name), |
| 387 bucket_ranges_(ranges), | 416 bucket_ranges_(ranges), |
| 388 declared_min_(minimum), | 417 declared_min_(minimum), |
| 389 declared_max_(maximum), | 418 declared_max_(maximum), |
| 390 bucket_count_(bucket_count) { | 419 bucket_count_(bucket_count) { |
| 391 if (ranges) | 420 if (ranges) |
| 392 samples_.reset(new SampleVector(ranges)); | 421 samples_.reset(new SampleVector(ranges)); |
| 393 } | 422 } |
| 394 | 423 |
| 395 Histogram::~Histogram() { | 424 Histogram::~Histogram() { |
| 396 if (StatisticsRecorder::dump_on_exit()) { | 425 if (StatisticsRecorder::dump_on_exit()) { |
| 397 string output; | 426 string output; |
| 398 WriteAsciiImpl(true, "\n", &output); | 427 WriteAsciiImpl(true, "\n", &output); |
| 399 DLOG(INFO) << output; | 428 DLOG(INFO) << output; |
| 400 } | 429 } |
| 401 } | 430 } |
| 402 | 431 |
| 403 // static | |
| 404 bool Histogram::InspectConstructionArguments(const string& name, | |
| 405 Sample* minimum, | |
| 406 Sample* maximum, | |
| 407 size_t* bucket_count) { | |
| 408 // Defensive code for backward compatibility. | |
| 409 if (*minimum < 1) { | |
| 410 DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum; | |
| 411 *minimum = 1; | |
| 412 } | |
| 413 if (*maximum >= kSampleType_MAX) { | |
| 414 DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum; | |
| 415 *maximum = kSampleType_MAX - 1; | |
| 416 } | |
| 417 if (*bucket_count >= kBucketCount_MAX) { | |
| 418 DVLOG(1) << "Histogram: " << name << " has bad bucket_count: " | |
| 419 << *bucket_count; | |
| 420 *bucket_count = kBucketCount_MAX - 1; | |
| 421 } | |
| 422 | |
| 423 if (*minimum >= *maximum) | |
| 424 return false; | |
| 425 if (*bucket_count < 3) | |
| 426 return false; | |
| 427 if (*bucket_count > static_cast<size_t>(*maximum - *minimum + 2)) | |
| 428 return false; | |
| 429 return true; | |
| 430 } | |
| 431 | |
| 432 bool Histogram::SerializeRanges(Pickle* pickle) const { | 432 bool Histogram::SerializeRanges(Pickle* pickle) const { |
| 433 return true; | 433 return true; |
| 434 } | 434 } |
| 435 | 435 |
| 436 bool Histogram::PrintEmptyBucket(size_t index) const { | 436 bool Histogram::PrintEmptyBucket(size_t index) const { |
| 437 return true; | 437 return true; |
| 438 } | 438 } |
| 439 | 439 |
| 440 // Use the actual bucket widths (like a linear histogram) until the widths get | 440 // Use the actual bucket widths (like a linear histogram) until the widths get |
| 441 // over some transition value, and then use that transition width. Exponentials | 441 // over some transition value, and then use that transition width. Exponentials |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 | 877 |
| 878 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); | 878 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); |
| 879 for (size_t i = 0; i < ranges.size(); i++) { | 879 for (size_t i = 0; i < ranges.size(); i++) { |
| 880 bucket_ranges->set_range(i, ranges[i]); | 880 bucket_ranges->set_range(i, ranges[i]); |
| 881 } | 881 } |
| 882 bucket_ranges->ResetChecksum(); | 882 bucket_ranges->ResetChecksum(); |
| 883 return bucket_ranges; | 883 return bucket_ranges; |
| 884 } | 884 } |
| 885 | 885 |
| 886 } // namespace base | 886 } // namespace base |
| OLD | NEW |