/src/brpc/src/bvar/detail/sampler.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | // Date: Tue Jul 28 18:15:57 CST 2015 |
19 | | |
20 | | #ifndef BVAR_DETAIL_SAMPLER_H |
21 | | #define BVAR_DETAIL_SAMPLER_H |
22 | | |
23 | | #include <vector> |
24 | | #include "butil/containers/linked_list.h"// LinkNode |
25 | | #include "butil/scoped_lock.h" // BAIDU_SCOPED_LOCK |
26 | | #include "butil/logging.h" // LOG() |
27 | | #include "butil/containers/bounded_queue.h"// BoundedQueue |
28 | | #include "butil/type_traits.h" // is_same |
29 | | #include "butil/time.h" // cpuwide_time_us |
30 | | #include "butil/class_name.h" |
31 | | |
32 | | namespace bvar { |
33 | | namespace detail { |
34 | | |
35 | | template <typename T> |
36 | | struct Sample { |
37 | | T data; |
38 | | int64_t time_us; |
39 | | |
40 | 15 | Sample() : data(), time_us(0) {}Unexecuted instantiation: bvar::detail::Sample<bvar::detail::PercentileSamples<254ul> >::Sample() Unexecuted instantiation: bvar::detail::Sample<bvar::Stat>::Sample() bvar::detail::Sample<long>::Sample() Line | Count | Source | 40 | 10 | Sample() : data(), time_us(0) {} |
Unexecuted instantiation: bvar::detail::Sample<double>::Sample() Unexecuted instantiation: bvar::detail::Sample<unsigned long>::Sample() bvar::detail::Sample<int>::Sample() Line | Count | Source | 40 | 5 | Sample() : data(), time_us(0) {} |
|
41 | | Sample(const T& data2, int64_t time2) : data(data2), time_us(time2) {} |
42 | | }; |
43 | | |
44 | | // The base class for all samplers whose take_sample() are called periodically. |
45 | | class Sampler : public butil::LinkNode<Sampler> { |
46 | | public: |
47 | | Sampler(); |
48 | | |
49 | | // This function will be called every second(approximately) in a |
50 | | // dedicated thread if schedule() is called. |
51 | | virtual void take_sample() = 0; |
52 | | |
53 | | // Register this sampler globally so that take_sample() will be called |
54 | | // periodically. |
55 | | void schedule(); |
56 | | |
57 | | // Call this function instead of delete to destroy the sampler. Deletion |
58 | | // of the sampler may be delayed for seconds. |
59 | | void destroy(); |
60 | | |
61 | | protected: |
62 | | virtual ~Sampler(); |
63 | | |
64 | | friend class SamplerCollector; |
65 | | bool _used; |
66 | | // Sync destroy() and take_sample(). |
67 | | butil::Mutex _mutex; |
68 | | }; |
69 | | |
70 | | // Representing a non-existing operator so that we can test |
71 | | // is_same<Op, VoidOp>::value to write code for different branches. |
72 | | // The false branch should be removed by compiler at compile-time. |
73 | | struct VoidOp { |
74 | | template <typename T> |
75 | 0 | T operator()(const T&, const T&) const { |
76 | 0 | CHECK(false) << "This function should never be called, abort"; |
77 | 0 | abort(); |
78 | 0 | } Unexecuted instantiation: long bvar::detail::VoidOp::operator()<long>(long const&, long const&) const Unexecuted instantiation: bvar::detail::PercentileSamples<254ul> bvar::detail::VoidOp::operator()<bvar::detail::PercentileSamples<254ul> >(bvar::detail::PercentileSamples<254ul> const&, bvar::detail::PercentileSamples<254ul> const&) const |
79 | | }; |
80 | | |
81 | | // The sampler for reducer-alike variables. |
82 | | // The R should have following methods: |
83 | | // - T reset(); |
84 | | // - T get_value(); |
85 | | // - Op op(); |
86 | | // - InvOp inv_op(); |
87 | | template <typename R, typename T, typename Op, typename InvOp> |
88 | | class ReducerSampler : public Sampler { |
89 | | public: |
90 | | static const time_t MAX_SECONDS_LIMIT = 3600; |
91 | | |
92 | | explicit ReducerSampler(R* reducer) |
93 | 3 | : _reducer(reducer) |
94 | 3 | , _window_size(1) { |
95 | | |
96 | | // Invoked take_sample at begining so the value of the first second |
97 | | // would not be ignored |
98 | 3 | take_sample(); |
99 | 3 | } Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::ReducerSampler(bvar::PassiveStatus<double>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::ReducerSampler(bvar::PassiveStatus<long>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::ReducerSampler(bvar::PassiveStatus<unsigned long>*) bvar::detail::ReducerSampler<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::ReducerSampler(bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >*) Line | Count | Source | 93 | 1 | : _reducer(reducer) | 94 | 1 | , _window_size(1) { | 95 | | | 96 | | // Invoked take_sample at begining so the value of the first second | 97 | | // would not be ignored | 98 | 1 | take_sample(); | 99 | 1 | } |
bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::ReducerSampler(bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >*) Line | Count | Source | 93 | 2 | : _reducer(reducer) | 94 | 2 | , _window_size(1) { | 95 | | | 96 | | // Invoked take_sample at begining so the value of the first second | 97 | | // would not be ignored | 98 | 2 | take_sample(); | 99 | 2 | } |
Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::ReducerSampler(bvar::IntRecorder*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::ReducerSampler(bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::ReducerSampler(bvar::detail::Percentile*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::ReducerSampler(bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >*) |
100 | 0 | ~ReducerSampler() {}Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::~ReducerSampler() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::~ReducerSampler() |
101 | | |
102 | 6 | void take_sample() override { |
103 | | // Make _q ready. |
104 | | // If _window_size is larger than what _q can hold, e.g. a larger |
105 | | // Window<> is created after running of sampler, make _q larger. |
106 | 6 | if ((size_t)_window_size + 1 > _q.capacity()) { |
107 | 6 | const size_t new_cap = |
108 | 6 | std::max(_q.capacity() * 2, (size_t)_window_size + 1); |
109 | 6 | const size_t memsize = sizeof(Sample<T>) * new_cap; |
110 | 6 | void* mem = malloc(memsize); |
111 | 6 | if (NULL == mem) { |
112 | 0 | return; |
113 | 0 | } |
114 | 6 | butil::BoundedQueue<Sample<T> > new_q( |
115 | 6 | mem, memsize, butil::OWNS_STORAGE); |
116 | 6 | Sample<T> tmp; |
117 | 9 | while (_q.pop(&tmp)) { |
118 | 3 | new_q.push(tmp); |
119 | 3 | } |
120 | 6 | new_q.swap(_q); |
121 | 6 | } |
122 | | |
123 | 6 | Sample<T> latest; |
124 | 6 | if (butil::is_same<InvOp, VoidOp>::value) { |
125 | | // The operator can't be inversed. |
126 | | // We reset the reducer and save the result as a sample. |
127 | | // Suming up samples gives the result within a window. |
128 | | // In this case, get_value() of _reducer gives wrong answer and |
129 | | // should not be called. |
130 | 0 | latest.data = _reducer->reset(); |
131 | 6 | } else { |
132 | | // The operator can be inversed. |
133 | | // We save the result as a sample. |
134 | | // Inversed operation between latest and oldest sample within a |
135 | | // window gives result. |
136 | | // get_value() of _reducer can still be called. |
137 | 6 | latest.data = _reducer->get_value(); |
138 | 6 | } |
139 | 6 | latest.time_us = butil::cpuwide_time_us(); |
140 | 6 | _q.elim_push(latest); |
141 | 6 | } Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::take_sample() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::take_sample() bvar::detail::ReducerSampler<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::take_sample() Line | Count | Source | 102 | 2 | void take_sample() override { | 103 | | // Make _q ready. | 104 | | // If _window_size is larger than what _q can hold, e.g. a larger | 105 | | // Window<> is created after running of sampler, make _q larger. | 106 | 2 | if ((size_t)_window_size + 1 > _q.capacity()) { | 107 | 2 | const size_t new_cap = | 108 | 2 | std::max(_q.capacity() * 2, (size_t)_window_size + 1); | 109 | 2 | const size_t memsize = sizeof(Sample<T>) * new_cap; | 110 | 2 | void* mem = malloc(memsize); | 111 | 2 | if (NULL == mem) { | 112 | 0 | return; | 113 | 0 | } | 114 | 2 | butil::BoundedQueue<Sample<T> > new_q( | 115 | 2 | mem, memsize, butil::OWNS_STORAGE); | 116 | 2 | Sample<T> tmp; | 117 | 3 | while (_q.pop(&tmp)) { | 118 | 1 | new_q.push(tmp); | 119 | 1 | } | 120 | 2 | new_q.swap(_q); | 121 | 2 | } | 122 | | | 123 | 2 | Sample<T> latest; | 124 | 2 | if (butil::is_same<InvOp, VoidOp>::value) { | 125 | | // The operator can't be inversed. | 126 | | // We reset the reducer and save the result as a sample. | 127 | | // Suming up samples gives the result within a window. | 128 | | // In this case, get_value() of _reducer gives wrong answer and | 129 | | // should not be called. | 130 | 0 | latest.data = _reducer->reset(); | 131 | 2 | } else { | 132 | | // The operator can be inversed. | 133 | | // We save the result as a sample. | 134 | | // Inversed operation between latest and oldest sample within a | 135 | | // window gives result. | 136 | | // get_value() of _reducer can still be called. | 137 | 2 | latest.data = _reducer->get_value(); | 138 | 2 | } | 139 | 2 | latest.time_us = butil::cpuwide_time_us(); | 140 | 2 | _q.elim_push(latest); | 141 | 2 | } |
bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::take_sample() Line | Count | Source | 102 | 4 | void take_sample() override { | 103 | | // Make _q ready. | 104 | | // If _window_size is larger than what _q can hold, e.g. a larger | 105 | | // Window<> is created after running of sampler, make _q larger. | 106 | 4 | if ((size_t)_window_size + 1 > _q.capacity()) { | 107 | 4 | const size_t new_cap = | 108 | 4 | std::max(_q.capacity() * 2, (size_t)_window_size + 1); | 109 | 4 | const size_t memsize = sizeof(Sample<T>) * new_cap; | 110 | 4 | void* mem = malloc(memsize); | 111 | 4 | if (NULL == mem) { | 112 | 0 | return; | 113 | 0 | } | 114 | 4 | butil::BoundedQueue<Sample<T> > new_q( | 115 | 4 | mem, memsize, butil::OWNS_STORAGE); | 116 | 4 | Sample<T> tmp; | 117 | 6 | while (_q.pop(&tmp)) { | 118 | 2 | new_q.push(tmp); | 119 | 2 | } | 120 | 4 | new_q.swap(_q); | 121 | 4 | } | 122 | | | 123 | 4 | Sample<T> latest; | 124 | 4 | if (butil::is_same<InvOp, VoidOp>::value) { | 125 | | // The operator can't be inversed. | 126 | | // We reset the reducer and save the result as a sample. | 127 | | // Suming up samples gives the result within a window. | 128 | | // In this case, get_value() of _reducer gives wrong answer and | 129 | | // should not be called. | 130 | 0 | latest.data = _reducer->reset(); | 131 | 4 | } else { | 132 | | // The operator can be inversed. | 133 | | // We save the result as a sample. | 134 | | // Inversed operation between latest and oldest sample within a | 135 | | // window gives result. | 136 | | // get_value() of _reducer can still be called. | 137 | 4 | latest.data = _reducer->get_value(); | 138 | 4 | } | 139 | 4 | latest.time_us = butil::cpuwide_time_us(); | 140 | 4 | _q.elim_push(latest); | 141 | 4 | } |
Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::take_sample() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::take_sample() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::take_sample() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::take_sample() Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::take_sample() |
142 | | |
143 | 3 | bool get_value(time_t window_size, Sample<T>* result) { |
144 | 3 | if (window_size <= 0) { |
145 | 0 | LOG(FATAL) << "Invalid window_size=" << window_size; |
146 | 0 | return false; |
147 | 0 | } |
148 | 3 | BAIDU_SCOPED_LOCK(_mutex); |
149 | 3 | if (_q.size() <= 1UL) { |
150 | | // We need more samples to get reasonable result. |
151 | 0 | return false; |
152 | 0 | } |
153 | 3 | Sample<T>* oldest = _q.bottom(window_size); |
154 | 3 | if (NULL == oldest) { |
155 | 0 | oldest = _q.top(); |
156 | 0 | } |
157 | 3 | Sample<T>* latest = _q.bottom(); |
158 | 3 | DCHECK(latest != oldest); |
159 | 3 | if (butil::is_same<InvOp, VoidOp>::value) { |
160 | | // No inverse op. Sum up all samples within the window. |
161 | 0 | result->data = latest->data; |
162 | 0 | for (int i = 1; true; ++i) { |
163 | 0 | Sample<T>* e = _q.bottom(i); |
164 | 0 | if (e == oldest) { |
165 | 0 | break; |
166 | 0 | } |
167 | 0 | _reducer->op()(result->data, e->data); |
168 | 0 | } |
169 | 3 | } else { |
170 | | // Diff the latest and oldest sample within the window. |
171 | 3 | result->data = latest->data; |
172 | 3 | _reducer->inv_op()(result->data, oldest->data); |
173 | 3 | } |
174 | 3 | result->time_us = latest->time_us - oldest->time_us; |
175 | 3 | return true; |
176 | 3 | } Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::get_value(long, bvar::detail::Sample<bvar::Stat>*) bvar::detail::ReducerSampler<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::get_value(long, bvar::detail::Sample<int>*) Line | Count | Source | 143 | 1 | bool get_value(time_t window_size, Sample<T>* result) { | 144 | 1 | if (window_size <= 0) { | 145 | 0 | LOG(FATAL) << "Invalid window_size=" << window_size; | 146 | 0 | return false; | 147 | 0 | } | 148 | 1 | BAIDU_SCOPED_LOCK(_mutex); | 149 | 1 | if (_q.size() <= 1UL) { | 150 | | // We need more samples to get reasonable result. | 151 | 0 | return false; | 152 | 0 | } | 153 | 1 | Sample<T>* oldest = _q.bottom(window_size); | 154 | 1 | if (NULL == oldest) { | 155 | 0 | oldest = _q.top(); | 156 | 0 | } | 157 | 1 | Sample<T>* latest = _q.bottom(); | 158 | 1 | DCHECK(latest != oldest); | 159 | 1 | if (butil::is_same<InvOp, VoidOp>::value) { | 160 | | // No inverse op. Sum up all samples within the window. | 161 | 0 | result->data = latest->data; | 162 | 0 | for (int i = 1; true; ++i) { | 163 | 0 | Sample<T>* e = _q.bottom(i); | 164 | 0 | if (e == oldest) { | 165 | 0 | break; | 166 | 0 | } | 167 | 0 | _reducer->op()(result->data, e->data); | 168 | 0 | } | 169 | 1 | } else { | 170 | | // Diff the latest and oldest sample within the window. | 171 | 1 | result->data = latest->data; | 172 | 1 | _reducer->inv_op()(result->data, oldest->data); | 173 | 1 | } | 174 | 1 | result->time_us = latest->time_us - oldest->time_us; | 175 | 1 | return true; | 176 | 1 | } |
bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::get_value(long, bvar::detail::Sample<long>*) Line | Count | Source | 143 | 2 | bool get_value(time_t window_size, Sample<T>* result) { | 144 | 2 | if (window_size <= 0) { | 145 | 0 | LOG(FATAL) << "Invalid window_size=" << window_size; | 146 | 0 | return false; | 147 | 0 | } | 148 | 2 | BAIDU_SCOPED_LOCK(_mutex); | 149 | 2 | if (_q.size() <= 1UL) { | 150 | | // We need more samples to get reasonable result. | 151 | 0 | return false; | 152 | 0 | } | 153 | 2 | Sample<T>* oldest = _q.bottom(window_size); | 154 | 2 | if (NULL == oldest) { | 155 | 0 | oldest = _q.top(); | 156 | 0 | } | 157 | 2 | Sample<T>* latest = _q.bottom(); | 158 | 2 | DCHECK(latest != oldest); | 159 | 2 | if (butil::is_same<InvOp, VoidOp>::value) { | 160 | | // No inverse op. Sum up all samples within the window. | 161 | 0 | result->data = latest->data; | 162 | 0 | for (int i = 1; true; ++i) { | 163 | 0 | Sample<T>* e = _q.bottom(i); | 164 | 0 | if (e == oldest) { | 165 | 0 | break; | 166 | 0 | } | 167 | 0 | _reducer->op()(result->data, e->data); | 168 | 0 | } | 169 | 2 | } else { | 170 | | // Diff the latest and oldest sample within the window. | 171 | 2 | result->data = latest->data; | 172 | 2 | _reducer->inv_op()(result->data, oldest->data); | 173 | 2 | } | 174 | 2 | result->time_us = latest->time_us - oldest->time_us; | 175 | 2 | return true; | 176 | 2 | } |
Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::get_value(long, bvar::detail::Sample<long>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::get_value(long, bvar::detail::Sample<bvar::detail::PercentileSamples<254ul> >*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::get_value(long, bvar::detail::Sample<long>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::get_value(long, bvar::detail::Sample<double>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::get_value(long, bvar::detail::Sample<unsigned long>*) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::get_value(long, bvar::detail::Sample<unsigned long>*) |
177 | | |
178 | | // Change the time window which can only go larger. |
179 | 3 | int set_window_size(time_t window_size) { |
180 | 3 | if (window_size <= 0 || window_size > MAX_SECONDS_LIMIT) { |
181 | 0 | LOG(ERROR) << "Invalid window_size=" << window_size; |
182 | 0 | return -1; |
183 | 0 | } |
184 | 3 | BAIDU_SCOPED_LOCK(_mutex); |
185 | 3 | if (window_size > _window_size) { |
186 | 3 | _window_size = window_size; |
187 | 3 | } |
188 | 3 | return 0; |
189 | 3 | } bvar::detail::ReducerSampler<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::set_window_size(long) Line | Count | Source | 179 | 1 | int set_window_size(time_t window_size) { | 180 | 1 | if (window_size <= 0 || window_size > MAX_SECONDS_LIMIT) { | 181 | 0 | LOG(ERROR) << "Invalid window_size=" << window_size; | 182 | 0 | return -1; | 183 | 0 | } | 184 | 1 | BAIDU_SCOPED_LOCK(_mutex); | 185 | 1 | if (window_size > _window_size) { | 186 | 1 | _window_size = window_size; | 187 | 1 | } | 188 | 1 | return 0; | 189 | 1 | } |
bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::set_window_size(long) Line | Count | Source | 179 | 2 | int set_window_size(time_t window_size) { | 180 | 2 | if (window_size <= 0 || window_size > MAX_SECONDS_LIMIT) { | 181 | 0 | LOG(ERROR) << "Invalid window_size=" << window_size; | 182 | 0 | return -1; | 183 | 0 | } | 184 | 2 | BAIDU_SCOPED_LOCK(_mutex); | 185 | 2 | if (window_size > _window_size) { | 186 | 2 | _window_size = window_size; | 187 | 2 | } | 188 | 2 | return 0; | 189 | 2 | } |
Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::set_window_size(long) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::set_window_size(long) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::set_window_size(long) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::set_window_size(long) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::set_window_size(long) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::set_window_size(long) Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::set_window_size(long) |
190 | | |
191 | 0 | void get_samples(std::vector<T> *samples, time_t window_size) { |
192 | 0 | if (window_size <= 0) { |
193 | 0 | LOG(FATAL) << "Invalid window_size=" << window_size; |
194 | 0 | return; |
195 | 0 | } |
196 | 0 | BAIDU_SCOPED_LOCK(_mutex); |
197 | 0 | if (_q.size() <= 1) { |
198 | | // We need more samples to get reasonable result. |
199 | 0 | return; |
200 | 0 | } |
201 | 0 | Sample<T>* oldest = _q.bottom(window_size); |
202 | 0 | if (NULL == oldest) { |
203 | 0 | oldest = _q.top(); |
204 | 0 | } |
205 | 0 | for (int i = 1; true; ++i) { |
206 | 0 | Sample<T>* e = _q.bottom(i); |
207 | 0 | if (e == oldest) { |
208 | 0 | break; |
209 | 0 | } |
210 | 0 | samples->push_back(e->data); |
211 | 0 | } |
212 | 0 | } |
213 | | |
214 | | private: |
215 | | R* _reducer; |
216 | | time_t _window_size; |
217 | | butil::BoundedQueue<Sample<T> > _q; |
218 | | }; |
219 | | |
220 | | } // namespace detail |
221 | | } // namespace bvar |
222 | | |
223 | | #endif // BVAR_DETAIL_SAMPLER_H |