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

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

Issue 2811713003: Embed a single sample in histogram metadata. (Closed)
Patch Set: move single-sample from 'value' to 'bucket' 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 // Moves the single-sample value to a mounted "counts" array.
55 void MoveSingleSampleToCounts();
56
57 // Mounts (creating if necessary) an array of "counts" for multi-value
58 // storage.
59 void MountCountsStorageAndMoveSingleSample();
60
61 // Mounts "counts" storage that already exists. This does not attempt to move
62 // any single-sample information to that storage as that would violate the
63 // "const" restriction that is often used to indicate read-only memory.
64 virtual bool MountExistingCountsStorage() const = 0;
65
66 // Creates "counts" storage and returns a pointer to it. Ownership of the
67 // array remains with the called method but will never change. This must be
68 // called while some sort of lock is held to prevent reentry.
69 virtual HistogramBase::Count* CreateCountsStorageWhileLocked() = 0;
70
71 HistogramBase::AtomicCount* counts() {
72 return reinterpret_cast<HistogramBase::AtomicCount*>(
73 subtle::Acquire_Load(&counts_));
74 }
75
76 const HistogramBase::AtomicCount* counts() const {
77 return reinterpret_cast<HistogramBase::AtomicCount*>(
78 subtle::Acquire_Load(&counts_));
79 }
80
81 void set_counts(const HistogramBase::AtomicCount* counts) const {
82 subtle::Release_Store(&counts_, reinterpret_cast<uintptr_t>(counts));
83 }
84
85 size_t counts_size() const { return counts_size_; }
86
55 private: 87 private:
88 friend class SampleVectorTest;
56 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts); 89 FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
57 FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts); 90 FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts);
58 91
59 // In the case where this class manages the memory, here it is. 92 // |counts_| is actually a pointer to a HistogramBase::AtomicCount array but
60 std::vector<HistogramBase::AtomicCount> local_counts_; 93 // is held as an AtomicWord for concurrency reasons. When combined with the
61 94 // single_sample held in the metadata, there are four possible states:
62 // These are raw pointers rather than objects for flexibility. The actual 95 // 1) single_sample == zero, counts_ == null
63 // memory is either managed by local_counts_ above or by an external object 96 // 2) single_sample != zero, counts_ == null
64 // and passed in directly. 97 // 3) single_sample != zero, counts_ != null BUT IS EMPTY
65 HistogramBase::AtomicCount* counts_; 98 // 4) single_sample == zero, counts_ != null and may have data
66 size_t counts_size_; 99 // Once |counts_| is set, it can never revert and any existing single-sample
100 // must be moved to this storage. It is mutable because changing it doesn't
101 // change the (const) data but must adapt if a non-const object causes the
102 // storage to be allocated and updated.
103 mutable subtle::AtomicWord counts_ = 0;
104 const size_t counts_size_;
Alexei Svitkine (slow) 2017/04/20 19:56:14 Do we need this as a separate field or can we get
bcwhite 2017/04/20 21:18:08 Done.
67 105
68 // Shares the same BucketRanges with Histogram object. 106 // Shares the same BucketRanges with Histogram object.
69 const BucketRanges* const bucket_ranges_; 107 const BucketRanges* const bucket_ranges_;
70 108
109 DISALLOW_COPY_AND_ASSIGN(SampleVectorBase);
110 };
111
112 // A sample vector that uses local memory for the counts array.
113 class BASE_EXPORT SampleVector : public SampleVectorBase {
114 public:
115 explicit SampleVector(const BucketRanges* bucket_ranges);
116 SampleVector(uint64_t id, const BucketRanges* bucket_ranges);
117 ~SampleVector() override;
118
119 private:
120 // SampleVectorBase:
121 bool MountExistingCountsStorage() const override;
122 HistogramBase::Count* CreateCountsStorageWhileLocked() override;
123
124 // Simple local storage for counts.
125 mutable std::vector<HistogramBase::AtomicCount> local_counts_;
126
71 DISALLOW_COPY_AND_ASSIGN(SampleVector); 127 DISALLOW_COPY_AND_ASSIGN(SampleVector);
72 }; 128 };
73 129
130 // A sample vector that uses persistent memory for the counts array.
131 class BASE_EXPORT PersistentSampleVector : public SampleVectorBase {
132 public:
133 PersistentSampleVector(uint64_t id,
134 const BucketRanges* bucket_ranges,
135 Metadata* meta,
136 const DelayedPersistentAllocation& counts);
137 ~PersistentSampleVector() override;
138
139 private:
140 // SampleVectorBase:
141 bool MountExistingCountsStorage() const override;
142 HistogramBase::Count* CreateCountsStorageWhileLocked() override;
143
144 // Persistent storage for counts.
145 DelayedPersistentAllocation persistent_counts_;
146
147 DISALLOW_COPY_AND_ASSIGN(PersistentSampleVector);
148 };
149
150 // An iterator for sample vectors. This could be defined privately in the .cc
151 // file but is here for easy testing.
74 class BASE_EXPORT SampleVectorIterator : public SampleCountIterator { 152 class BASE_EXPORT SampleVectorIterator : public SampleCountIterator {
75 public: 153 public:
76 SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts, 154 SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts,
77 const BucketRanges* bucket_ranges); 155 const BucketRanges* bucket_ranges);
78 SampleVectorIterator(const HistogramBase::AtomicCount* counts, 156 SampleVectorIterator(const HistogramBase::AtomicCount* counts,
79 size_t counts_size, 157 size_t counts_size,
80 const BucketRanges* bucket_ranges); 158 const BucketRanges* bucket_ranges);
81 ~SampleVectorIterator() override; 159 ~SampleVectorIterator() override;
82 160
83 // SampleCountIterator implementation: 161 // SampleCountIterator implementation:
(...skipping 12 matching lines...) Expand all
96 const HistogramBase::AtomicCount* counts_; 174 const HistogramBase::AtomicCount* counts_;
97 size_t counts_size_; 175 size_t counts_size_;
98 const BucketRanges* bucket_ranges_; 176 const BucketRanges* bucket_ranges_;
99 177
100 size_t index_; 178 size_t index_;
101 }; 179 };
102 180
103 } // namespace base 181 } // namespace base
104 182
105 #endif // BASE_METRICS_SAMPLE_VECTOR_H_ 183 #endif // BASE_METRICS_SAMPLE_VECTOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698