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

Side by Side Diff: base/metrics/sample_vector.h

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: addressed review comments by asvitkine Created 3 years, 8 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
OLDNEW
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 // SampleVector implements HistogramSamples interface. It is used by all 5 // SampleVector implements HistogramSamples interface. It is used by all
6 // Histogram based classes to store samples. 6 // Histogram based classes to store samples.
7 7
8 #ifndef BASE_METRICS_SAMPLE_VECTOR_H_ 8 #ifndef BASE_METRICS_SAMPLE_VECTOR_H_
9 #define BASE_METRICS_SAMPLE_VECTOR_H_ 9 #define BASE_METRICS_SAMPLE_VECTOR_H_
10 10
11 #include <stddef.h> 11 #include <stddef.h>
12 #include <stdint.h> 12 #include <stdint.h>
13 13
14 #include <memory> 14 #include <memory>
15 #include <vector> 15 #include <vector>
16 16
17 #include "base/atomicops.h"
17 #include "base/compiler_specific.h" 18 #include "base/compiler_specific.h"
18 #include "base/gtest_prod_util.h" 19 #include "base/gtest_prod_util.h"
19 #include "base/macros.h" 20 #include "base/macros.h"
20 #include "base/metrics/histogram_base.h" 21 #include "base/metrics/histogram_base.h"
21 #include "base/metrics/histogram_samples.h" 22 #include "base/metrics/histogram_samples.h"
23 #include "base/metrics/persistent_memory_allocator.h"
22 24
23 namespace base { 25 namespace base {
24 26
25 class BucketRanges; 27 class BucketRanges;
26 28
27 class BASE_EXPORT SampleVector : public HistogramSamples { 29 class BASE_EXPORT SampleVectorBase : public HistogramSamples {
28 public: 30 public:
29 explicit SampleVector(const BucketRanges* bucket_ranges); 31 SampleVectorBase(uint64_t id, const BucketRanges* bucket_ranges);
30 SampleVector(uint64_t id, const BucketRanges* bucket_ranges); 32 SampleVectorBase(uint64_t id,
31 SampleVector(uint64_t id, 33 Metadata* meta,
32 HistogramBase::AtomicCount* counts, 34 const BucketRanges* bucket_ranges);
33 size_t counts_size, 35 ~SampleVectorBase() override;
34 Metadata* meta,
35 const BucketRanges* bucket_ranges);
36 ~SampleVector() override;
37 36
38 // HistogramSamples implementation: 37 // HistogramSamples:
39 void Accumulate(HistogramBase::Sample value, 38 void Accumulate(HistogramBase::Sample value,
40 HistogramBase::Count count) override; 39 HistogramBase::Count count) override;
41 HistogramBase::Count GetCount(HistogramBase::Sample value) const override; 40 HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
42 HistogramBase::Count TotalCount() const override; 41 HistogramBase::Count TotalCount() const override;
43 std::unique_ptr<SampleCountIterator> Iterator() const override; 42 std::unique_ptr<SampleCountIterator> Iterator() const override;
44 43
45 // Get count of a specific bucket. 44 // Get count of a specific bucket.
46 HistogramBase::Count GetCountAtIndex(size_t bucket_index) const; 45 HistogramBase::Count GetCountAtIndex(size_t bucket_index) const;
47 46
48 protected: 47 protected:
49 bool AddSubtractImpl( 48 bool AddSubtractImpl(
50 SampleCountIterator* iter, 49 SampleCountIterator* iter,
51 HistogramSamples::Operator op) override; // |op| is ADD or SUBTRACT. 50 HistogramSamples::Operator op) override; // |op| is ADD or SUBTRACT.
52 51
53 virtual size_t GetBucketIndex(HistogramBase::Sample value) const; 52 virtual size_t GetBucketIndex(HistogramBase::Sample value) const;
54 53
54 void MoveSingleSampleToCounts();
Alexei Svitkine (slow) 2017/04/18 20:52:21 Please add short comments for this and the three f
bcwhite 2017/04/19 18:13:02 Done.
55
56 void MountCountsStorage();
57 virtual bool MountExistingCountsStorage() const = 0;
58 virtual HistogramBase::Count* CreateCountsStorageWhileLocked() = 0;
59
60 HistogramBase::AtomicCount* counts() {
61 return reinterpret_cast<HistogramBase::AtomicCount*>(
62 subtle::NoBarrier_Load(&counts_));
63 }
64
65 const HistogramBase::AtomicCount* counts() const {
66 return reinterpret_cast<HistogramBase::AtomicCount*>(
67 subtle::NoBarrier_Load(&counts_));
68 }
69
70 void set_counts(HistogramBase::AtomicCount* counts) const {
71 subtle::NoBarrier_Store(&counts_, reinterpret_cast<uintptr_t>(counts));
72 }
73
74 size_t counts_size() const { return counts_size_; }
75
55 private: 76 private:
77 friend class SampleVectorTest;
56 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); 78 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
57 FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts); 79 FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts);
58 80
59 // In the case where this class manages the memory, here it is. 81 // |counts_| is actually a pointer to a HistogramBase::AtomicCount array but
60 std::vector<HistogramBase::AtomicCount> local_counts_; 82 // is held as an AtomicWord for concurrency reasons. When combined with the
61 83 // single_sample held in the metadata, there are four possible states:
62 // These are raw pointers rather than objects for flexibility. The actual 84 // 1) single_sample == zero, counts_ == null
63 // memory is either managed by local_counts_ above or by an external object 85 // 2) single_sample != zero, counts_ == null
64 // and passed in directly. 86 // 3) single_sample != zero, counts_ != null BUT IS EMPTY
65 HistogramBase::AtomicCount* counts_; 87 // 4) single_sample == zero, counts_ != null and may have data
66 size_t counts_size_; 88 // Once |counts_| is set, it can never revert and any existing single-sample
89 // must be moved to this storage. It is mutable because changing it doesn't
90 // change the (const) data but must adapt if a non-const object causes the
91 // storage to be allocated and updated.
92 mutable subtle::AtomicWord counts_ = 0;
93 const size_t counts_size_;
67 94
68 // Shares the same BucketRanges with Histogram object. 95 // Shares the same BucketRanges with Histogram object.
69 const BucketRanges* const bucket_ranges_; 96 const BucketRanges* const bucket_ranges_;
70 97
98 DISALLOW_COPY_AND_ASSIGN(SampleVectorBase);
99 };
100
101 // A sample vector that uses local memory for the counts array.
102 class BASE_EXPORT SampleVector : public SampleVectorBase {
103 public:
104 explicit SampleVector(const BucketRanges* bucket_ranges);
105 SampleVector(uint64_t id, const BucketRanges* bucket_ranges);
106 ~SampleVector() override;
107
108 private:
109 // SampleVectorBase:
110 bool MountExistingCountsStorage() const override;
111 HistogramBase::Count* CreateCountsStorageWhileLocked() override;
112
113 // Simple local storage for counts.
114 mutable std::vector<HistogramBase::AtomicCount> local_counts_;
115
71 DISALLOW_COPY_AND_ASSIGN(SampleVector); 116 DISALLOW_COPY_AND_ASSIGN(SampleVector);
72 }; 117 };
73 118
119 // A sample vector that uses persistent memory for the counts array.
120 class BASE_EXPORT PersistentSampleVector : public SampleVectorBase {
121 public:
122 PersistentSampleVector(uint64_t id,
123 const BucketRanges* bucket_ranges,
124 Metadata* meta,
125 const DelayedPersistentAllocation& counts);
126 ~PersistentSampleVector() override;
127
128 private:
129 // SampleVectorBase:
130 bool MountExistingCountsStorage() const override;
131 HistogramBase::Count* CreateCountsStorageWhileLocked() override;
132
133 // Persistent storage for counts.
134 DelayedPersistentAllocation persistent_counts_;
135
136 DISALLOW_COPY_AND_ASSIGN(PersistentSampleVector);
137 };
138
139 // An iterator for sample vectors. This could be defined privately in the .cc
140 // file but is here for easy testing.
74 class BASE_EXPORT SampleVectorIterator : public SampleCountIterator { 141 class BASE_EXPORT SampleVectorIterator : public SampleCountIterator {
75 public: 142 public:
76 SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts, 143 SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts,
77 const BucketRanges* bucket_ranges); 144 const BucketRanges* bucket_ranges);
78 SampleVectorIterator(const HistogramBase::AtomicCount* counts, 145 SampleVectorIterator(const HistogramBase::AtomicCount* counts,
79 size_t counts_size, 146 size_t counts_size,
80 const BucketRanges* bucket_ranges); 147 const BucketRanges* bucket_ranges);
81 ~SampleVectorIterator() override; 148 ~SampleVectorIterator() override;
82 149
83 // SampleCountIterator implementation: 150 // SampleCountIterator implementation:
(...skipping 12 matching lines...) Expand all
96 const HistogramBase::AtomicCount* counts_; 163 const HistogramBase::AtomicCount* counts_;
97 size_t counts_size_; 164 size_t counts_size_;
98 const BucketRanges* bucket_ranges_; 165 const BucketRanges* bucket_ranges_;
99 166
100 size_t index_; 167 size_t index_;
101 }; 168 };
102 169
103 } // namespace base 170 } // namespace base
104 171
105 #endif // BASE_METRICS_SAMPLE_VECTOR_H_ 172 #endif // BASE_METRICS_SAMPLE_VECTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698