| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/metrics/sparse_histogram.h" | |
| 6 | |
| 7 #include "base/metrics/sample_map.h" | |
| 8 #include "base/metrics/statistics_recorder.h" | |
| 9 #include "base/pickle.h" | |
| 10 #include "base/strings/stringprintf.h" | |
| 11 #include "base/synchronization/lock.h" | |
| 12 | |
| 13 namespace base { | |
| 14 | |
| 15 typedef HistogramBase::Count Count; | |
| 16 typedef HistogramBase::Sample Sample; | |
| 17 | |
| 18 // static | |
| 19 HistogramBase* SparseHistogram::FactoryGet(const std::string& name, | |
| 20 int32 flags) { | |
| 21 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); | |
| 22 | |
| 23 if (!histogram) { | |
| 24 // To avoid racy destruction at shutdown, the following will be leaked. | |
| 25 HistogramBase* tentative_histogram = new SparseHistogram(name); | |
| 26 tentative_histogram->SetFlags(flags); | |
| 27 histogram = | |
| 28 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | |
| 29 } | |
| 30 DCHECK_EQ(SPARSE_HISTOGRAM, histogram->GetHistogramType()); | |
| 31 return histogram; | |
| 32 } | |
| 33 | |
| 34 SparseHistogram::~SparseHistogram() {} | |
| 35 | |
| 36 HistogramType SparseHistogram::GetHistogramType() const { | |
| 37 return SPARSE_HISTOGRAM; | |
| 38 } | |
| 39 | |
| 40 bool SparseHistogram::HasConstructionArguments( | |
| 41 Sample expected_minimum, | |
| 42 Sample expected_maximum, | |
| 43 size_t expected_bucket_count) const { | |
| 44 // SparseHistogram never has min/max/bucket_count limit. | |
| 45 return false; | |
| 46 } | |
| 47 | |
| 48 void SparseHistogram::Add(Sample value) { | |
| 49 { | |
| 50 base::AutoLock auto_lock(lock_); | |
| 51 samples_.Accumulate(value, 1); | |
| 52 } | |
| 53 | |
| 54 FindAndRunCallback(value); | |
| 55 } | |
| 56 | |
| 57 scoped_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const { | |
| 58 scoped_ptr<SampleMap> snapshot(new SampleMap()); | |
| 59 | |
| 60 base::AutoLock auto_lock(lock_); | |
| 61 snapshot->Add(samples_); | |
| 62 return snapshot.Pass(); | |
| 63 } | |
| 64 | |
| 65 void SparseHistogram::AddSamples(const HistogramSamples& samples) { | |
| 66 base::AutoLock auto_lock(lock_); | |
| 67 samples_.Add(samples); | |
| 68 } | |
| 69 | |
| 70 bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) { | |
| 71 base::AutoLock auto_lock(lock_); | |
| 72 return samples_.AddFromPickle(iter); | |
| 73 } | |
| 74 | |
| 75 void SparseHistogram::WriteHTMLGraph(std::string* output) const { | |
| 76 output->append("<PRE>"); | |
| 77 WriteAsciiImpl(true, "<br>", output); | |
| 78 output->append("</PRE>"); | |
| 79 } | |
| 80 | |
| 81 void SparseHistogram::WriteAscii(std::string* output) const { | |
| 82 WriteAsciiImpl(true, "\n", output); | |
| 83 } | |
| 84 | |
| 85 bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const { | |
| 86 return pickle->WriteString(histogram_name()) && pickle->WriteInt(flags()); | |
| 87 } | |
| 88 | |
| 89 SparseHistogram::SparseHistogram(const std::string& name) | |
| 90 : HistogramBase(name) {} | |
| 91 | |
| 92 HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) { | |
| 93 std::string histogram_name; | |
| 94 int flags; | |
| 95 if (!iter->ReadString(&histogram_name) || !iter->ReadInt(&flags)) { | |
| 96 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; | |
| 97 return NULL; | |
| 98 } | |
| 99 | |
| 100 DCHECK(flags & HistogramBase::kIPCSerializationSourceFlag); | |
| 101 flags &= ~HistogramBase::kIPCSerializationSourceFlag; | |
| 102 | |
| 103 return SparseHistogram::FactoryGet(histogram_name, flags); | |
| 104 } | |
| 105 | |
| 106 void SparseHistogram::GetParameters(DictionaryValue* params) const { | |
| 107 // TODO(kaiwang): Implement. (See HistogramBase::WriteJSON.) | |
| 108 } | |
| 109 | |
| 110 void SparseHistogram::GetCountAndBucketData(Count* count, | |
| 111 int64* sum, | |
| 112 ListValue* buckets) const { | |
| 113 // TODO(kaiwang): Implement. (See HistogramBase::WriteJSON.) | |
| 114 } | |
| 115 | |
| 116 void SparseHistogram::WriteAsciiImpl(bool graph_it, | |
| 117 const std::string& newline, | |
| 118 std::string* output) const { | |
| 119 // Get a local copy of the data so we are consistent. | |
| 120 scoped_ptr<HistogramSamples> snapshot = SnapshotSamples(); | |
| 121 Count total_count = snapshot->TotalCount(); | |
| 122 double scaled_total_count = total_count / 100.0; | |
| 123 | |
| 124 WriteAsciiHeader(total_count, output); | |
| 125 output->append(newline); | |
| 126 | |
| 127 // Determine how wide the largest bucket range is (how many digits to print), | |
| 128 // so that we'll be able to right-align starts for the graphical bars. | |
| 129 // Determine which bucket has the largest sample count so that we can | |
| 130 // normalize the graphical bar-width relative to that sample count. | |
| 131 Count largest_count = 0; | |
| 132 Sample largest_sample = 0; | |
| 133 scoped_ptr<SampleCountIterator> it = snapshot->Iterator(); | |
| 134 while (!it->Done()) { | |
| 135 Sample min; | |
| 136 Sample max; | |
| 137 Count count; | |
| 138 it->Get(&min, &max, &count); | |
| 139 if (min > largest_sample) | |
| 140 largest_sample = min; | |
| 141 if (count > largest_count) | |
| 142 largest_count = count; | |
| 143 it->Next(); | |
| 144 } | |
| 145 size_t print_width = GetSimpleAsciiBucketRange(largest_sample).size() + 1; | |
| 146 | |
| 147 // iterate over each item and display them | |
| 148 it = snapshot->Iterator(); | |
| 149 while (!it->Done()) { | |
| 150 Sample min; | |
| 151 Sample max; | |
| 152 Count count; | |
| 153 it->Get(&min, &max, &count); | |
| 154 | |
| 155 // value is min, so display it | |
| 156 std::string range = GetSimpleAsciiBucketRange(min); | |
| 157 output->append(range); | |
| 158 for (size_t j = 0; range.size() + j < print_width + 1; ++j) | |
| 159 output->push_back(' '); | |
| 160 | |
| 161 if (graph_it) | |
| 162 WriteAsciiBucketGraph(count, largest_count, output); | |
| 163 WriteAsciiBucketValue(count, scaled_total_count, output); | |
| 164 output->append(newline); | |
| 165 it->Next(); | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 void SparseHistogram::WriteAsciiHeader(const Count total_count, | |
| 170 std::string* output) const { | |
| 171 StringAppendF(output, | |
| 172 "Histogram: %s recorded %d samples", | |
| 173 histogram_name().c_str(), | |
| 174 total_count); | |
| 175 if (flags() & ~kHexRangePrintingFlag) | |
| 176 StringAppendF(output, " (flags = 0x%x)", flags() & ~kHexRangePrintingFlag); | |
| 177 } | |
| 178 | |
| 179 } // namespace base | |
| OLD | NEW |