Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: base/histogram.cc

Issue 515033: Cleanup histogram classes mixing SetFlags into FactoryGet arguments... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/histogram.h ('k') | base/histogram_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/histogram.h" 10 #include "base/histogram.h"
11 11
12 #include <math.h> 12 #include <math.h>
13 #include <string> 13 #include <string>
14 14
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/pickle.h" 16 #include "base/pickle.h"
17 #include "base/string_util.h" 17 #include "base/string_util.h"
18 18
19 using base::TimeDelta; 19 using base::TimeDelta;
20 20
21 typedef Histogram::Count Count; 21 typedef Histogram::Count Count;
22 22
23 // static 23 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
24 const int Histogram::kHexRangePrintingFlag = 0x8000; 24 Sample minimum, Sample maximum, size_t bucket_count, Flags flags) {
25
26 scoped_refptr<Histogram> Histogram::HistogramFactoryGet(
27 const std::string& name, Sample minimum, Sample maximum,
28 size_t bucket_count) {
29 scoped_refptr<Histogram> histogram(NULL); 25 scoped_refptr<Histogram> histogram(NULL);
30 26
31 // Defensive code. 27 // Defensive code.
32 if (minimum <= 0) 28 if (minimum <= 0)
33 minimum = 1; 29 minimum = 1;
34 if (maximum >= kSampleType_MAX) 30 if (maximum >= kSampleType_MAX)
35 maximum = kSampleType_MAX - 1; 31 maximum = kSampleType_MAX - 1;
36 32
37 if (StatisticsRecorder::FindHistogram(name, &histogram)) { 33 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
38 DCHECK(histogram.get() != NULL); 34 DCHECK(histogram.get() != NULL);
39 } else { 35 } else {
40 histogram = new Histogram(name, minimum, maximum, bucket_count); 36 histogram = new Histogram(name, minimum, maximum, bucket_count);
41 scoped_refptr<Histogram> registered_histogram(NULL); 37 scoped_refptr<Histogram> registered_histogram(NULL);
42 StatisticsRecorder::FindHistogram(name, &registered_histogram); 38 StatisticsRecorder::FindHistogram(name, &registered_histogram);
43 // Allow a NULL return to mean that the StatisticsRecorder was not started. 39 // Allow a NULL return to mean that the StatisticsRecorder was not started.
44 if (registered_histogram.get() != NULL && 40 if (registered_histogram.get() != NULL &&
45 registered_histogram.get() != histogram.get()) 41 registered_histogram.get() != histogram.get())
46 histogram = registered_histogram; 42 histogram = registered_histogram;
47 } 43 }
48 44
49 DCHECK(HISTOGRAM == histogram->histogram_type()); 45 DCHECK(HISTOGRAM == histogram->histogram_type());
50 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); 46 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
47 histogram->SetFlags(flags);
51 return histogram; 48 return histogram;
52 } 49 }
53 50
54 scoped_refptr<Histogram> Histogram::HistogramFactoryGet( 51 scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
55 const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum, 52 base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
56 size_t bucket_count) { 53 Flags flags) {
57 return HistogramFactoryGet(name, 54 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
58 minimum.InMilliseconds(), maximum.InMilliseconds(), bucket_count); 55 bucket_count, flags);
59 } 56 }
60 57
61 Histogram::Histogram(const std::string& name, Sample minimum, 58 Histogram::Histogram(const std::string& name, Sample minimum,
62 Sample maximum, size_t bucket_count) 59 Sample maximum, size_t bucket_count)
63 : histogram_name_(name), 60 : histogram_name_(name),
64 declared_min_(minimum), 61 declared_min_(minimum),
65 declared_max_(maximum), 62 declared_max_(maximum),
66 bucket_count_(bucket_count), 63 bucket_count_(bucket_count),
67 flags_(0), 64 flags_(kNoFlags),
68 ranges_(bucket_count + 1, 0), 65 ranges_(bucket_count + 1, 0),
69 sample_() { 66 sample_() {
70 Initialize(); 67 Initialize();
71 } 68 }
72 69
73 Histogram::Histogram(const std::string& name, TimeDelta minimum, 70 Histogram::Histogram(const std::string& name, TimeDelta minimum,
74 TimeDelta maximum, size_t bucket_count) 71 TimeDelta maximum, size_t bucket_count)
75 : histogram_name_(name), 72 : histogram_name_(name),
76 declared_min_(static_cast<int> (minimum.InMilliseconds())), 73 declared_min_(static_cast<int> (minimum.InMilliseconds())),
77 declared_max_(static_cast<int> (maximum.InMilliseconds())), 74 declared_max_(static_cast<int> (maximum.InMilliseconds())),
78 bucket_count_(bucket_count), 75 bucket_count_(bucket_count),
79 flags_(0), 76 flags_(kNoFlags),
80 ranges_(bucket_count + 1, 0), 77 ranges_(bucket_count + 1, 0),
81 sample_() { 78 sample_() {
82 Initialize(); 79 Initialize();
83 } 80 }
84 81
85 Histogram::~Histogram() { 82 Histogram::~Histogram() {
86 DCHECK(!(kPlannedLeakFlag & flags_));
87 if (StatisticsRecorder::dump_on_exit()) { 83 if (StatisticsRecorder::dump_on_exit()) {
88 std::string output; 84 std::string output;
89 WriteAscii(true, "\n", &output); 85 WriteAscii(true, "\n", &output);
90 LOG(INFO) << output; 86 LOG(INFO) << output;
91 } 87 }
92 88
93 // Just to make sure most derived class did this properly... 89 // Just to make sure most derived class did this properly...
94 DCHECK(ValidateBucketRanges()); 90 DCHECK(ValidateBucketRanges());
95 } 91 }
96 92
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 WriteAsciiBucketContext(past, current, remaining, i, output); 173 WriteAsciiBucketContext(past, current, remaining, i, output);
178 output->append(newline); 174 output->append(newline);
179 past += current; 175 past += current;
180 } 176 }
181 DCHECK(past == sample_count); 177 DCHECK(past == sample_count);
182 } 178 }
183 179
184 bool Histogram::ValidateBucketRanges() const { 180 bool Histogram::ValidateBucketRanges() const {
185 // Standard assertions that all bucket ranges should satisfy. 181 // Standard assertions that all bucket ranges should satisfy.
186 DCHECK(ranges_.size() == bucket_count_ + 1); 182 DCHECK(ranges_.size() == bucket_count_ + 1);
187 DCHECK(0 == ranges_[0]); 183 DCHECK_EQ(0, ranges_[0]);
188 DCHECK(declared_min() == ranges_[1]); 184 DCHECK(declared_min() == ranges_[1]);
189 DCHECK(declared_max() == ranges_[bucket_count_ - 1]); 185 DCHECK(declared_max() == ranges_[bucket_count_ - 1]);
190 DCHECK(kSampleType_MAX == ranges_[bucket_count_]); 186 DCHECK(kSampleType_MAX == ranges_[bucket_count_]);
191 return true; 187 return true;
192 } 188 }
193 189
194 void Histogram::Initialize() { 190 void Histogram::Initialize() {
195 sample_.Resize(*this); 191 sample_.Resize(*this);
196 if (declared_min_ <= 0) 192 if (declared_min_ <= 0)
197 declared_min_ = 1; 193 declared_min_ = 1;
198 if (declared_max_ >= kSampleType_MAX) 194 if (declared_max_ >= kSampleType_MAX)
199 declared_max_ = kSampleType_MAX - 1; 195 declared_max_ = kSampleType_MAX - 1;
200 DCHECK(declared_min_ > 0); // We provide underflow bucket. 196 DCHECK_GT(declared_min_, 0); // We provide underflow bucket.
201 DCHECK(declared_min_ <= declared_max_); 197 DCHECK(declared_min_ <= declared_max_);
202 DCHECK(1 < bucket_count_); 198 DCHECK_LT(1u, bucket_count_);
203 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2; 199 size_t maximal_bucket_count = declared_max_ - declared_min_ + 2;
204 DCHECK(bucket_count_ <= maximal_bucket_count); 200 DCHECK(bucket_count_ <= maximal_bucket_count);
205 DCHECK(0 == ranges_[0]); 201 DCHECK_EQ(0, ranges_[0]);
206 ranges_[bucket_count_] = kSampleType_MAX; 202 ranges_[bucket_count_] = kSampleType_MAX;
207 InitializeBucketRange(); 203 InitializeBucketRange();
208 DCHECK(ValidateBucketRanges()); 204 DCHECK(ValidateBucketRanges());
209 StatisticsRecorder::Register(this); 205 StatisticsRecorder::Register(this);
210 } 206 }
211 207
212 // Calculate what range of values are held in each bucket. 208 // Calculate what range of values are held in each bucket.
213 // We have to be careful that we don't pick a ratio between starting points in 209 // We have to be careful that we don't pick a ratio between starting points in
214 // consecutive buckets that is sooo small, that the integer bounds are the same 210 // consecutive buckets that is sooo small, that the integer bounds are the same
215 // (effectively making one bucket get no values). We need to avoid: 211 // (effectively making one bucket get no values). We need to avoid:
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 319 }
324 320
325 void Histogram::WriteAsciiHeader(const SampleSet& snapshot, 321 void Histogram::WriteAsciiHeader(const SampleSet& snapshot,
326 Count sample_count, 322 Count sample_count,
327 std::string* output) const { 323 std::string* output) const {
328 StringAppendF(output, 324 StringAppendF(output,
329 "Histogram: %s recorded %d samples", 325 "Histogram: %s recorded %d samples",
330 histogram_name().c_str(), 326 histogram_name().c_str(),
331 sample_count); 327 sample_count);
332 if (0 == sample_count) { 328 if (0 == sample_count) {
333 DCHECK(0 == snapshot.sum()); 329 DCHECK_EQ(0, snapshot.sum());
334 } else { 330 } else {
335 double average = static_cast<float>(snapshot.sum()) / sample_count; 331 double average = static_cast<float>(snapshot.sum()) / sample_count;
336 double variance = static_cast<float>(snapshot.square_sum())/sample_count 332 double variance = static_cast<float>(snapshot.square_sum())/sample_count
337 - average * average; 333 - average * average;
338 double standard_deviation = sqrt(variance); 334 double standard_deviation = sqrt(variance);
339 335
340 StringAppendF(output, 336 StringAppendF(output,
341 ", average = %.1f, standard deviation = %.1f", 337 ", average = %.1f, standard deviation = %.1f",
342 average, standard_deviation); 338 average, standard_deviation);
343 } 339 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 return false; 405 return false;
410 } 406 }
411 407
412 Pickle pickle(histogram_info.data(), 408 Pickle pickle(histogram_info.data(),
413 static_cast<int>(histogram_info.size())); 409 static_cast<int>(histogram_info.size()));
414 void* iter = NULL; 410 void* iter = NULL;
415 size_t bucket_count; 411 size_t bucket_count;
416 int declared_min; 412 int declared_min;
417 int declared_max; 413 int declared_max;
418 int histogram_type; 414 int histogram_type;
419 int flags; 415 int pickle_flags;
420 std::string histogram_name; 416 std::string histogram_name;
421 SampleSet sample; 417 SampleSet sample;
422 418
423 if (!pickle.ReadString(&iter, &histogram_name) || 419 if (!pickle.ReadString(&iter, &histogram_name) ||
424 !pickle.ReadInt(&iter, &declared_min) || 420 !pickle.ReadInt(&iter, &declared_min) ||
425 !pickle.ReadInt(&iter, &declared_max) || 421 !pickle.ReadInt(&iter, &declared_max) ||
426 !pickle.ReadSize(&iter, &bucket_count) || 422 !pickle.ReadSize(&iter, &bucket_count) ||
427 !pickle.ReadInt(&iter, &histogram_type) || 423 !pickle.ReadInt(&iter, &histogram_type) ||
428 !pickle.ReadInt(&iter, &flags) || 424 !pickle.ReadInt(&iter, &pickle_flags) ||
429 !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) { 425 !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) {
430 LOG(ERROR) << "Picke error decoding Histogram: " << histogram_name; 426 LOG(ERROR) << "Picke error decoding Histogram: " << histogram_name;
431 return false; 427 return false;
432 } 428 }
429 Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag);
433 430
434 DCHECK(histogram_type != NOT_VALID_IN_RENDERER); 431 DCHECK(histogram_type != NOT_VALID_IN_RENDERER);
435 432
436 scoped_refptr<Histogram> render_histogram(NULL); 433 scoped_refptr<Histogram> render_histogram(NULL);
437 434
438 if (histogram_type == HISTOGRAM) { 435 if (histogram_type == HISTOGRAM) {
439 render_histogram = Histogram::HistogramFactoryGet( 436 render_histogram = Histogram::FactoryGet(
440 histogram_name, declared_min, declared_max, bucket_count); 437 histogram_name, declared_min, declared_max, bucket_count, flags);
441 } else if (histogram_type == LINEAR_HISTOGRAM) { 438 } else if (histogram_type == LINEAR_HISTOGRAM) {
442 render_histogram = LinearHistogram::LinearHistogramFactoryGet( 439 render_histogram = LinearHistogram::FactoryGet(
443 histogram_name, declared_min, declared_max, bucket_count); 440 histogram_name, declared_min, declared_max, bucket_count, flags);
444 } else if (histogram_type == BOOLEAN_HISTOGRAM) { 441 } else if (histogram_type == BOOLEAN_HISTOGRAM) {
445 render_histogram = BooleanHistogram::BooleanHistogramFactoryGet( 442 render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags);
446 histogram_name);
447 } else if (histogram_type == THREAD_SAFE_HISTOGRAM) {
448 render_histogram =
449 ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(
450 histogram_name, declared_min, declared_max, bucket_count);
451 } else { 443 } else {
452 LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " << 444 LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " <<
453 histogram_type; 445 histogram_type;
454 return false; 446 return false;
455 } 447 }
456 448
457 DCHECK(declared_min == render_histogram->declared_min()); 449 DCHECK(declared_min == render_histogram->declared_min());
458 DCHECK(declared_max == render_histogram->declared_max()); 450 DCHECK(declared_max == render_histogram->declared_max());
459 DCHECK(bucket_count == render_histogram->bucket_count()); 451 DCHECK(bucket_count == render_histogram->bucket_count());
460 DCHECK(histogram_type == render_histogram->histogram_type()); 452 DCHECK(histogram_type == render_histogram->histogram_type());
461 453
462 if (render_histogram->flags() & kIPCSerializationSourceFlag) { 454 if (render_histogram->flags() & kIPCSerializationSourceFlag) {
463 DLOG(INFO) << "Single process mode, histogram observed and not copied: " << 455 DLOG(INFO) << "Single process mode, histogram observed and not copied: " <<
464 histogram_name; 456 histogram_name;
465 } else { 457 } else {
458 DCHECK(flags == (flags & render_histogram->flags()));
466 render_histogram->AddSampleSet(sample); 459 render_histogram->AddSampleSet(sample);
467 render_histogram->SetFlags(flags & ~kIPCSerializationSourceFlag
468 & ~kPlannedLeakFlag);
469 } 460 }
470 461
471 return true; 462 return true;
472 } 463 }
473 464
474 //------------------------------------------------------------------------------ 465 //------------------------------------------------------------------------------
475 // Methods for the Histogram::SampleSet class 466 // Methods for the Histogram::SampleSet class
476 //------------------------------------------------------------------------------ 467 //------------------------------------------------------------------------------
477 468
478 Histogram::SampleSet::SampleSet() 469 Histogram::SampleSet::SampleSet()
(...skipping 10 matching lines...) Expand all
489 DCHECK(counts_.size() == histogram.bucket_count()); 480 DCHECK(counts_.size() == histogram.bucket_count());
490 } 481 }
491 482
492 483
493 void Histogram::SampleSet::Accumulate(Sample value, Count count, 484 void Histogram::SampleSet::Accumulate(Sample value, Count count,
494 size_t index) { 485 size_t index) {
495 DCHECK(count == 1 || count == -1); 486 DCHECK(count == 1 || count == -1);
496 counts_[index] += count; 487 counts_[index] += count;
497 sum_ += count * value; 488 sum_ += count * value;
498 square_sum_ += (count * value) * static_cast<int64>(value); 489 square_sum_ += (count * value) * static_cast<int64>(value);
499 DCHECK(counts_[index] >= 0); 490 DCHECK_GE(counts_[index], 0);
500 DCHECK(sum_ >= 0); 491 DCHECK_GE(sum_, 0);
501 DCHECK(square_sum_ >= 0); 492 DCHECK_GE(square_sum_, 0);
502 } 493 }
503 494
504 Count Histogram::SampleSet::TotalCount() const { 495 Count Histogram::SampleSet::TotalCount() const {
505 Count total = 0; 496 Count total = 0;
506 for (Counts::const_iterator it = counts_.begin(); 497 for (Counts::const_iterator it = counts_.begin();
507 it != counts_.end(); 498 it != counts_.end();
508 ++it) { 499 ++it) {
509 total += *it; 500 total += *it;
510 } 501 }
511 return total; 502 return total;
512 } 503 }
513 504
514 void Histogram::SampleSet::Add(const SampleSet& other) { 505 void Histogram::SampleSet::Add(const SampleSet& other) {
515 DCHECK(counts_.size() == other.counts_.size()); 506 DCHECK(counts_.size() == other.counts_.size());
516 sum_ += other.sum_; 507 sum_ += other.sum_;
517 square_sum_ += other.square_sum_; 508 square_sum_ += other.square_sum_;
518 for (size_t index = 0; index < counts_.size(); ++index) 509 for (size_t index = 0; index < counts_.size(); ++index)
519 counts_[index] += other.counts_[index]; 510 counts_[index] += other.counts_[index];
520 } 511 }
521 512
522 void Histogram::SampleSet::Subtract(const SampleSet& other) { 513 void Histogram::SampleSet::Subtract(const SampleSet& other) {
523 DCHECK(counts_.size() == other.counts_.size()); 514 DCHECK(counts_.size() == other.counts_.size());
524 // Note: Race conditions in snapshotting a sum or square_sum may lead to 515 // Note: Race conditions in snapshotting a sum or square_sum may lead to
525 // (temporary) negative values when snapshots are later combined (and deltas 516 // (temporary) negative values when snapshots are later combined (and deltas
526 // calculated). As a result, we don't currently CHCEK() for positive values. 517 // calculated). As a result, we don't currently CHCEK() for positive values.
527 sum_ -= other.sum_; 518 sum_ -= other.sum_;
528 square_sum_ -= other.square_sum_; 519 square_sum_ -= other.square_sum_;
529 for (size_t index = 0; index < counts_.size(); ++index) { 520 for (size_t index = 0; index < counts_.size(); ++index) {
530 counts_[index] -= other.counts_[index]; 521 counts_[index] -= other.counts_[index];
531 DCHECK(counts_[index] >= 0); 522 DCHECK_GE(counts_[index], 0);
532 } 523 }
533 } 524 }
534 525
535 bool Histogram::SampleSet::Serialize(Pickle* pickle) const { 526 bool Histogram::SampleSet::Serialize(Pickle* pickle) const {
536 pickle->WriteInt64(sum_); 527 pickle->WriteInt64(sum_);
537 pickle->WriteInt64(square_sum_); 528 pickle->WriteInt64(square_sum_);
538 pickle->WriteSize(counts_.size()); 529 pickle->WriteSize(counts_.size());
539 530
540 for (size_t index = 0; index < counts_.size(); ++index) { 531 for (size_t index = 0; index < counts_.size(); ++index) {
541 pickle->WriteInt(counts_[index]); 532 pickle->WriteInt(counts_[index]);
542 } 533 }
543 534
544 return true; 535 return true;
545 } 536 }
546 537
547 bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) { 538 bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) {
548 DCHECK(counts_.size() == 0); 539 DCHECK_EQ(counts_.size(), 0u);
549 DCHECK(sum_ == 0); 540 DCHECK_EQ(sum_, 0);
550 DCHECK(square_sum_ == 0); 541 DCHECK_EQ(square_sum_, 0);
551 542
552 size_t counts_size; 543 size_t counts_size;
553 544
554 if (!pickle.ReadInt64(iter, &sum_) || 545 if (!pickle.ReadInt64(iter, &sum_) ||
555 !pickle.ReadInt64(iter, &square_sum_) || 546 !pickle.ReadInt64(iter, &square_sum_) ||
556 !pickle.ReadSize(iter, &counts_size)) { 547 !pickle.ReadSize(iter, &counts_size)) {
557 return false; 548 return false;
558 } 549 }
559 550
560 if (counts_size <= 0) 551 if (counts_size <= 0)
561 return false; 552 return false;
562 553
563 counts_.resize(counts_size, 0); 554 counts_.resize(counts_size, 0);
564 for (size_t index = 0; index < counts_size; ++index) { 555 for (size_t index = 0; index < counts_size; ++index) {
565 if (!pickle.ReadInt(iter, &counts_[index])) { 556 if (!pickle.ReadInt(iter, &counts_[index])) {
566 return false; 557 return false;
567 } 558 }
568 } 559 }
569 560
570 return true; 561 return true;
571 } 562 }
572 563
573 //------------------------------------------------------------------------------ 564 //------------------------------------------------------------------------------
574 // LinearHistogram: This histogram uses a traditional set of evenly spaced 565 // LinearHistogram: This histogram uses a traditional set of evenly spaced
575 // buckets. 566 // buckets.
576 //------------------------------------------------------------------------------ 567 //------------------------------------------------------------------------------
577 568
578 scoped_refptr<Histogram> LinearHistogram::LinearHistogramFactoryGet( 569 scoped_refptr<Histogram> LinearHistogram::FactoryGet(
579 const std::string& name, Sample minimum, Sample maximum, 570 const std::string& name, Sample minimum, Sample maximum,
580 size_t bucket_count) { 571 size_t bucket_count, Flags flags) {
581 scoped_refptr<Histogram> histogram(NULL); 572 scoped_refptr<Histogram> histogram(NULL);
582 573
583 if (minimum <= 0) 574 if (minimum <= 0)
584 minimum = 1; 575 minimum = 1;
585 if (maximum >= kSampleType_MAX) 576 if (maximum >= kSampleType_MAX)
586 maximum = kSampleType_MAX - 1; 577 maximum = kSampleType_MAX - 1;
587 578
588 if (StatisticsRecorder::FindHistogram(name, &histogram)) { 579 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
589 DCHECK(histogram.get() != NULL); 580 DCHECK(histogram.get() != NULL);
590 } else { 581 } else {
591 histogram = new LinearHistogram(name, minimum, maximum, bucket_count); 582 histogram = new LinearHistogram(name, minimum, maximum, bucket_count);
592 scoped_refptr<Histogram> registered_histogram(NULL); 583 scoped_refptr<Histogram> registered_histogram(NULL);
593 StatisticsRecorder::FindHistogram(name, &registered_histogram); 584 StatisticsRecorder::FindHistogram(name, &registered_histogram);
594 if (registered_histogram.get() != NULL && 585 if (registered_histogram.get() != NULL &&
595 registered_histogram.get() != histogram.get()) 586 registered_histogram.get() != histogram.get())
596 histogram = registered_histogram; 587 histogram = registered_histogram;
597 } 588 }
598 589
599 DCHECK(LINEAR_HISTOGRAM == histogram->histogram_type()); 590 DCHECK(LINEAR_HISTOGRAM == histogram->histogram_type());
600 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count)); 591 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
601 592 histogram->SetFlags(flags);
602 return histogram; 593 return histogram;
603 } 594 }
604 595
605 scoped_refptr<Histogram> LinearHistogram::LinearHistogramFactoryGet( 596 scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name,
606 const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum, 597 base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
607 size_t bucket_count) { 598 Flags flags) {
608 return LinearHistogramFactoryGet(name, minimum.InMilliseconds(), 599 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
609 maximum.InMilliseconds(), bucket_count); 600 bucket_count, flags);
610 } 601 }
611 602
612 LinearHistogram::LinearHistogram(const std::string& name, Sample minimum, 603 LinearHistogram::LinearHistogram(const std::string& name, Sample minimum,
613 Sample maximum, size_t bucket_count) 604 Sample maximum, size_t bucket_count)
614 : Histogram(name, minimum >= 1 ? minimum : 1, maximum, bucket_count) { 605 : Histogram(name, minimum >= 1 ? minimum : 1, maximum, bucket_count) {
615 InitializeBucketRange(); 606 InitializeBucketRange();
616 DCHECK(ValidateBucketRanges()); 607 DCHECK(ValidateBucketRanges());
617 } 608 }
618 609
619 LinearHistogram::LinearHistogram(const std::string& name, 610 LinearHistogram::LinearHistogram(const std::string& name,
(...skipping 20 matching lines...) Expand all
640 return Histogram::GetAsciiBucketRange(i); 631 return Histogram::GetAsciiBucketRange(i);
641 return it->second; 632 return it->second;
642 } 633 }
643 634
644 bool LinearHistogram::PrintEmptyBucket(size_t index) const { 635 bool LinearHistogram::PrintEmptyBucket(size_t index) const {
645 return bucket_description_.find(ranges(index)) == bucket_description_.end(); 636 return bucket_description_.find(ranges(index)) == bucket_description_.end();
646 } 637 }
647 638
648 639
649 void LinearHistogram::InitializeBucketRange() { 640 void LinearHistogram::InitializeBucketRange() {
650 DCHECK(0 < declared_min()); // 0 is the underflow bucket here. 641 DCHECK_LT(0, declared_min()); // 0 is the underflow bucket here.
651 double min = declared_min(); 642 double min = declared_min();
652 double max = declared_max(); 643 double max = declared_max();
653 size_t i; 644 size_t i;
654 for (i = 1; i < bucket_count(); ++i) { 645 for (i = 1; i < bucket_count(); ++i) {
655 double linear_range = (min * (bucket_count() -1 - i) + max * (i - 1)) / 646 double linear_range = (min * (bucket_count() -1 - i) + max * (i - 1)) /
656 (bucket_count() - 2); 647 (bucket_count() - 2);
657 SetBucketRange(i, static_cast<int> (linear_range + 0.5)); 648 SetBucketRange(i, static_cast<int> (linear_range + 0.5));
658 } 649 }
659 } 650 }
660 651
661 double LinearHistogram::GetBucketSize(Count current, size_t i) const { 652 double LinearHistogram::GetBucketSize(Count current, size_t i) const {
662 DCHECK(ranges(i + 1) > ranges(i)); 653 DCHECK(ranges(i + 1) > ranges(i));
663 // Adjacent buckets with different widths would have "surprisingly" many (few) 654 // Adjacent buckets with different widths would have "surprisingly" many (few)
664 // samples in a histogram if we didn't normalize this way. 655 // samples in a histogram if we didn't normalize this way.
665 double denominator = ranges(i + 1) - ranges(i); 656 double denominator = ranges(i + 1) - ranges(i);
666 return current/denominator; 657 return current/denominator;
667 } 658 }
668 659
669 //------------------------------------------------------------------------------ 660 //------------------------------------------------------------------------------
670 // This section provides implementation for BooleanHistogram. 661 // This section provides implementation for BooleanHistogram.
671 //------------------------------------------------------------------------------ 662 //------------------------------------------------------------------------------
672 663
673 scoped_refptr<Histogram> BooleanHistogram::BooleanHistogramFactoryGet( 664 scoped_refptr<Histogram> BooleanHistogram::FactoryGet(const std::string& name,
674 const std::string& name) { 665 Flags flags) {
675 scoped_refptr<Histogram> histogram(NULL); 666 scoped_refptr<Histogram> histogram(NULL);
676 667
677 if (StatisticsRecorder::FindHistogram(name, &histogram)) { 668 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
678 DCHECK(histogram.get() != NULL); 669 DCHECK(histogram.get() != NULL);
679 } else { 670 } else {
680 histogram = new BooleanHistogram(name); 671 histogram = new BooleanHistogram(name);
681 scoped_refptr<Histogram> registered_histogram(NULL); 672 scoped_refptr<Histogram> registered_histogram(NULL);
682 StatisticsRecorder::FindHistogram(name, &registered_histogram); 673 StatisticsRecorder::FindHistogram(name, &registered_histogram);
683 if (registered_histogram.get() != NULL && 674 if (registered_histogram.get() != NULL &&
684 registered_histogram.get() != histogram.get()) 675 registered_histogram.get() != histogram.get())
685 histogram = registered_histogram; 676 histogram = registered_histogram;
686 } 677 }
687 678
688 DCHECK(BOOLEAN_HISTOGRAM == histogram->histogram_type()); 679 DCHECK(BOOLEAN_HISTOGRAM == histogram->histogram_type());
689 680 histogram->SetFlags(flags);
690 return histogram; 681 return histogram;
691 } 682 }
692 683
693 //------------------------------------------------------------------------------
694 // This section provides implementation for ThreadSafeHistogram.
695 //------------------------------------------------------------------------------
696
697 scoped_refptr<Histogram> ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(
698 const std::string& name, Sample minimum, Sample maximum,
699 size_t bucket_count) {
700 scoped_refptr<Histogram> histogram(NULL);
701
702 if (minimum <= 0)
703 minimum = 1;
704 if (maximum >= kSampleType_MAX)
705 maximum = kSampleType_MAX - 1;
706
707 if (StatisticsRecorder::FindHistogram(name, &histogram)) {
708 DCHECK(histogram.get() != NULL);
709 } else {
710 histogram = new ThreadSafeHistogram(name, minimum, maximum, bucket_count);
711 scoped_refptr<Histogram> registered_histogram(NULL);
712 StatisticsRecorder::FindHistogram(name, &registered_histogram);
713 if (registered_histogram.get() != NULL &&
714 registered_histogram.get() != histogram.get())
715 histogram = registered_histogram;
716 }
717
718 DCHECK(THREAD_SAFE_HISTOGRAM == histogram->histogram_type());
719 DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
720 return histogram;
721 }
722
723 ThreadSafeHistogram::ThreadSafeHistogram(const std::string& name,
724 Sample minimum, Sample maximum, size_t bucket_count)
725 : Histogram(name, minimum, maximum, bucket_count),
726 lock_() {
727 }
728
729 void ThreadSafeHistogram::Remove(int value) {
730 if (value >= kSampleType_MAX)
731 value = kSampleType_MAX - 1;
732 size_t index = BucketIndex(value);
733 Accumulate(value, -1, index);
734 }
735
736 void ThreadSafeHistogram::Accumulate(Sample value, Count count, size_t index) {
737 AutoLock lock(lock_);
738 Histogram::Accumulate(value, count, index);
739 }
740
741 void ThreadSafeHistogram::SnapshotSample(SampleSet* sample) const {
742 AutoLock lock(lock_);
743 Histogram::SnapshotSample(sample);
744 };
745
746 684
747 //------------------------------------------------------------------------------ 685 //------------------------------------------------------------------------------
748 // The next section handles global (central) support for all histograms, as well 686 // The next section handles global (central) support for all histograms, as well
749 // as startup/teardown of this service. 687 // as startup/teardown of this service.
750 //------------------------------------------------------------------------------ 688 //------------------------------------------------------------------------------
751 689
752 // This singleton instance should be started during the single threaded portion 690 // This singleton instance should be started during the single threaded portion
753 // of main(), and hence it is not thread safe. It initializes globals to 691 // of main(), and hence it is not thread safe. It initializes globals to
754 // provide support for all future calls. 692 // provide support for all future calls.
755 StatisticsRecorder::StatisticsRecorder() { 693 StatisticsRecorder::StatisticsRecorder() {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 793
856 // static 794 // static
857 void StatisticsRecorder::GetHistogramsForRenderer(Histograms* output) { 795 void StatisticsRecorder::GetHistogramsForRenderer(Histograms* output) {
858 if (!histograms_) 796 if (!histograms_)
859 return; 797 return;
860 AutoLock auto_lock(*lock_); 798 AutoLock auto_lock(*lock_);
861 for (HistogramMap::iterator it = histograms_->begin(); 799 for (HistogramMap::iterator it = histograms_->begin();
862 histograms_->end() != it; 800 histograms_->end() != it;
863 ++it) { 801 ++it) {
864 scoped_refptr<Histogram> histogram = it->second; 802 scoped_refptr<Histogram> histogram = it->second;
865 if (!(histogram->flags() & kIPCSerializationSourceFlag)) 803 if (!(histogram->flags() & Histogram::kIPCSerializationSourceFlag))
866 histogram->SetFlags(kIPCSerializationSourceFlag); 804 histogram->SetFlags(Histogram::kIPCSerializationSourceFlag);
867 output->push_back(histogram); 805 output->push_back(histogram);
868 } 806 }
869 } 807 }
870 808
871 bool StatisticsRecorder::FindHistogram(const std::string& name, 809 bool StatisticsRecorder::FindHistogram(const std::string& name,
872 scoped_refptr<Histogram>* histogram) { 810 scoped_refptr<Histogram>* histogram) {
873 if (!histograms_) 811 if (!histograms_)
874 return false; 812 return false;
875 AutoLock auto_lock(*lock_); 813 AutoLock auto_lock(*lock_);
876 HistogramMap::iterator it = histograms_->find(name); 814 HistogramMap::iterator it = histograms_->find(name);
(...skipping 14 matching lines...) Expand all
891 snapshot->push_back(it->second); 829 snapshot->push_back(it->second);
892 } 830 }
893 } 831 }
894 832
895 // static 833 // static
896 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL; 834 StatisticsRecorder::HistogramMap* StatisticsRecorder::histograms_ = NULL;
897 // static 835 // static
898 Lock* StatisticsRecorder::lock_ = NULL; 836 Lock* StatisticsRecorder::lock_ = NULL;
899 // static 837 // static
900 bool StatisticsRecorder::dump_on_exit_ = false; 838 bool StatisticsRecorder::dump_on_exit_ = false;
OLDNEW
« no previous file with comments | « base/histogram.h ('k') | base/histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698