| 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 #include "base/metrics/sparse_histogram.h" | 5 #include "base/metrics/sparse_histogram.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/metrics_hashes.h" | 10 #include "base/metrics/metrics_hashes.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 const std::string& name, | 78 const std::string& name, |
| 79 HistogramSamples::Metadata* meta, | 79 HistogramSamples::Metadata* meta, |
| 80 HistogramSamples::Metadata* logged_meta) { | 80 HistogramSamples::Metadata* logged_meta) { |
| 81 return WrapUnique( | 81 return WrapUnique( |
| 82 new SparseHistogram(allocator, name, meta, logged_meta)); | 82 new SparseHistogram(allocator, name, meta, logged_meta)); |
| 83 } | 83 } |
| 84 | 84 |
| 85 SparseHistogram::~SparseHistogram() {} | 85 SparseHistogram::~SparseHistogram() {} |
| 86 | 86 |
| 87 uint64_t SparseHistogram::name_hash() const { | 87 uint64_t SparseHistogram::name_hash() const { |
| 88 return samples_->id(); | 88 return unlogged_samples_->id(); |
| 89 } | 89 } |
| 90 | 90 |
| 91 HistogramType SparseHistogram::GetHistogramType() const { | 91 HistogramType SparseHistogram::GetHistogramType() const { |
| 92 return SPARSE_HISTOGRAM; | 92 return SPARSE_HISTOGRAM; |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool SparseHistogram::HasConstructionArguments( | 95 bool SparseHistogram::HasConstructionArguments( |
| 96 Sample expected_minimum, | 96 Sample expected_minimum, |
| 97 Sample expected_maximum, | 97 Sample expected_maximum, |
| 98 uint32_t expected_bucket_count) const { | 98 uint32_t expected_bucket_count) const { |
| 99 // SparseHistogram never has min/max/bucket_count limit. | 99 // SparseHistogram never has min/max/bucket_count limit. |
| 100 return false; | 100 return false; |
| 101 } | 101 } |
| 102 | 102 |
| 103 void SparseHistogram::Add(Sample value) { | 103 void SparseHistogram::Add(Sample value) { |
| 104 AddCount(value, 1); | 104 AddCount(value, 1); |
| 105 } | 105 } |
| 106 | 106 |
| 107 void SparseHistogram::AddCount(Sample value, int count) { | 107 void SparseHistogram::AddCount(Sample value, int count) { |
| 108 if (count <= 0) { | 108 if (count <= 0) { |
| 109 NOTREACHED(); | 109 NOTREACHED(); |
| 110 return; | 110 return; |
| 111 } | 111 } |
| 112 { | 112 { |
| 113 base::AutoLock auto_lock(lock_); | 113 base::AutoLock auto_lock(lock_); |
| 114 samples_->Accumulate(value, count); | 114 unlogged_samples_->Accumulate(value, count); |
| 115 } | 115 } |
| 116 | 116 |
| 117 FindAndRunCallback(value); | 117 FindAndRunCallback(value); |
| 118 } | 118 } |
| 119 | 119 |
| 120 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const { | 120 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const { |
| 121 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); | 121 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); |
| 122 | 122 |
| 123 base::AutoLock auto_lock(lock_); | 123 base::AutoLock auto_lock(lock_); |
| 124 snapshot->Add(*samples_); | 124 snapshot->Add(*unlogged_samples_); |
| 125 snapshot->Add(*logged_samples_); |
| 125 return std::move(snapshot); | 126 return std::move(snapshot); |
| 126 } | 127 } |
| 127 | 128 |
| 128 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotDelta() { | 129 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotDelta() { |
| 129 DCHECK(!final_delta_created_); | 130 DCHECK(!final_delta_created_); |
| 130 | 131 |
| 131 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); | 132 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); |
| 132 base::AutoLock auto_lock(lock_); | 133 base::AutoLock auto_lock(lock_); |
| 133 snapshot->Add(*samples_); | 134 snapshot->Add(*unlogged_samples_); |
| 134 | 135 |
| 135 // Subtract what was previously logged and update that information. | 136 unlogged_samples_->Subtract(*snapshot); |
| 136 snapshot->Subtract(*logged_samples_); | |
| 137 logged_samples_->Add(*snapshot); | 137 logged_samples_->Add(*snapshot); |
| 138 return std::move(snapshot); | 138 return std::move(snapshot); |
| 139 } | 139 } |
| 140 | 140 |
| 141 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotFinalDelta() const { | 141 std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotFinalDelta() const { |
| 142 DCHECK(!final_delta_created_); | 142 DCHECK(!final_delta_created_); |
| 143 final_delta_created_ = true; | 143 final_delta_created_ = true; |
| 144 | 144 |
| 145 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); | 145 std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash())); |
| 146 base::AutoLock auto_lock(lock_); | 146 base::AutoLock auto_lock(lock_); |
| 147 snapshot->Add(*samples_); | 147 snapshot->Add(*unlogged_samples_); |
| 148 | 148 |
| 149 // Subtract what was previously logged and then return. | |
| 150 snapshot->Subtract(*logged_samples_); | |
| 151 return std::move(snapshot); | 149 return std::move(snapshot); |
| 152 } | 150 } |
| 153 | 151 |
| 154 void SparseHistogram::AddSamples(const HistogramSamples& samples) { | 152 void SparseHistogram::AddSamples(const HistogramSamples& samples) { |
| 155 base::AutoLock auto_lock(lock_); | 153 base::AutoLock auto_lock(lock_); |
| 156 samples_->Add(samples); | 154 unlogged_samples_->Add(samples); |
| 157 } | 155 } |
| 158 | 156 |
| 159 bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) { | 157 bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) { |
| 160 base::AutoLock auto_lock(lock_); | 158 base::AutoLock auto_lock(lock_); |
| 161 return samples_->AddFromPickle(iter); | 159 return unlogged_samples_->AddFromPickle(iter); |
| 162 } | 160 } |
| 163 | 161 |
| 164 void SparseHistogram::WriteHTMLGraph(std::string* output) const { | 162 void SparseHistogram::WriteHTMLGraph(std::string* output) const { |
| 165 output->append("<PRE>"); | 163 output->append("<PRE>"); |
| 166 WriteAsciiImpl(true, "<br>", output); | 164 WriteAsciiImpl(true, "<br>", output); |
| 167 output->append("</PRE>"); | 165 output->append("</PRE>"); |
| 168 } | 166 } |
| 169 | 167 |
| 170 void SparseHistogram::WriteAscii(std::string* output) const { | 168 void SparseHistogram::WriteAscii(std::string* output) const { |
| 171 WriteAsciiImpl(true, "\n", output); | 169 WriteAsciiImpl(true, "\n", output); |
| 172 } | 170 } |
| 173 | 171 |
| 174 bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const { | 172 bool SparseHistogram::SerializeInfoImpl(Pickle* pickle) const { |
| 175 return pickle->WriteString(histogram_name()) && pickle->WriteInt(flags()); | 173 return pickle->WriteString(histogram_name()) && pickle->WriteInt(flags()); |
| 176 } | 174 } |
| 177 | 175 |
| 178 SparseHistogram::SparseHistogram(const std::string& name) | 176 SparseHistogram::SparseHistogram(const std::string& name) |
| 179 : HistogramBase(name), | 177 : HistogramBase(name), |
| 180 samples_(new SampleMap(HashMetricName(name))), | 178 unlogged_samples_(new SampleMap(HashMetricName(name))), |
| 181 logged_samples_(new SampleMap(samples_->id())) {} | 179 logged_samples_(new SampleMap(unlogged_samples_->id())) {} |
| 182 | 180 |
| 183 SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator, | 181 SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator, |
| 184 const std::string& name, | 182 const std::string& name, |
| 185 HistogramSamples::Metadata* meta, | 183 HistogramSamples::Metadata* meta, |
| 186 HistogramSamples::Metadata* logged_meta) | 184 HistogramSamples::Metadata* logged_meta) |
| 187 : HistogramBase(name), | 185 : HistogramBase(name), |
| 188 // While other histogram types maintain a static vector of values with | 186 // While other histogram types maintain a static vector of values with |
| 189 // sufficient space for both "active" and "logged" samples, with each | 187 // sufficient space for both "active" and "logged" samples, with each |
| 190 // SampleVector being given the appropriate half, sparse histograms | 188 // SampleVector being given the appropriate half, sparse histograms |
| 191 // have no such initial allocation. Each sample has its own record | 189 // have no such initial allocation. Each sample has its own record |
| 192 // attached to a single PersistentSampleMap by a common 64-bit identifier. | 190 // attached to a single PersistentSampleMap by a common 64-bit identifier. |
| 193 // Since a sparse histogram has two sample maps (active and logged), | 191 // Since a sparse histogram has two sample maps (active and logged), |
| 194 // there must be two sets of sample records with diffent IDs. The | 192 // there must be two sets of sample records with diffent IDs. The |
| 195 // "active" samples use, for convenience purposes, an ID matching | 193 // "active" samples use, for convenience purposes, an ID matching |
| 196 // that of the histogram while the "logged" samples use that number | 194 // that of the histogram while the "logged" samples use that number |
| 197 // plus 1. | 195 // plus 1. |
| 198 samples_(new PersistentSampleMap(HashMetricName(name), allocator, meta)), | 196 unlogged_samples_( |
| 199 logged_samples_( | 197 new PersistentSampleMap(HashMetricName(name), allocator, meta)), |
| 200 new PersistentSampleMap(samples_->id() + 1, allocator, logged_meta)) { | 198 logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1, |
| 201 } | 199 allocator, |
| 200 logged_meta)) {} |
| 202 | 201 |
| 203 HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) { | 202 HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) { |
| 204 std::string histogram_name; | 203 std::string histogram_name; |
| 205 int flags; | 204 int flags; |
| 206 if (!iter->ReadString(&histogram_name) || !iter->ReadInt(&flags)) { | 205 if (!iter->ReadString(&histogram_name) || !iter->ReadInt(&flags)) { |
| 207 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; | 206 DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name; |
| 208 return NULL; | 207 return NULL; |
| 209 } | 208 } |
| 210 | 209 |
| 211 flags &= ~HistogramBase::kIPCSerializationSourceFlag; | 210 flags &= ~HistogramBase::kIPCSerializationSourceFlag; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 std::string* output) const { | 279 std::string* output) const { |
| 281 StringAppendF(output, | 280 StringAppendF(output, |
| 282 "Histogram: %s recorded %d samples", | 281 "Histogram: %s recorded %d samples", |
| 283 histogram_name().c_str(), | 282 histogram_name().c_str(), |
| 284 total_count); | 283 total_count); |
| 285 if (flags()) | 284 if (flags()) |
| 286 StringAppendF(output, " (flags = 0x%x)", flags()); | 285 StringAppendF(output, " (flags = 0x%x)", flags()); |
| 287 } | 286 } |
| 288 | 287 |
| 289 } // namespace base | 288 } // namespace base |
| OLD | NEW |