Coverage Report

Created: 2026-09-01 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 <string>                        // std::string
25
#include <type_traits>                   // std::true_type
26
#include <utility>                       // std::declval
27
#include "butil/containers/linked_list.h"// LinkNode
28
#include "butil/scoped_lock.h"           // BAIDU_SCOPED_LOCK
29
#include "butil/logging.h"               // LOG()
30
#include "butil/containers/bounded_queue.h"// BoundedQueue
31
#include "butil/type_traits.h"           // is_same
32
#include "butil/time.h"                  // cpuwide_time_us
33
#include "butil/class_name.h"
34
35
namespace bvar {
36
namespace detail {
37
38
template <typename T>
39
struct Sample {
40
    T data;
41
    int64_t time_us;
42
43
6
    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
43
4
    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
43
2
    Sample() : data(), time_us(0) {}
44
    Sample(const T& data2, int64_t time2) : data(data2), time_us(time2) {}  
45
};
46
47
// The base class for all samplers whose take_sample() are called periodically.
48
class Sampler : public butil::LinkNode<Sampler> {
49
public:
50
    Sampler();
51
        
52
    // This function will be called every second(approximately) in a
53
    // dedicated thread if schedule() is called.
54
    virtual void take_sample() = 0;
55
56
    // Register this sampler globally so that take_sample() will be called
57
    // periodically.
58
    void schedule();
59
60
    // Call this function instead of delete to destroy the sampler. Deletion
61
    // of the sampler may be delayed for seconds.
62
    void destroy();
63
64
    // Declare/undeclare that an external object borrows this sampler which is
65
    // owned by another bvar. Window/PerSecond does this because it samples
66
    // through the sampler of the bvar it references.
67
    // If the owner is destructed while borrowers remain (namely a Window
68
    // outlives the bvar it references, which violates the contract documented
69
    // in bvar/window.h), destroy() reports the misuse and the sampler is
70
    // deliberately leaked so that borrowers are not left with a dangling
71
    // pointer.
72
    void add_borrower();
73
    void remove_borrower();
74
75
    // Name of the owning bvar, purely for diagnostics.
76
3
    void set_debug_name(const std::string& name) {
77
3
        BAIDU_SCOPED_LOCK(_mutex);
78
3
        _debug_name = name;
79
3
    }
80
0
    std::string debug_name() const {
81
0
        BAIDU_SCOPED_LOCK(_mutex);
82
0
        return _debug_name;
83
0
    }
84
85
protected:
86
    virtual ~Sampler();
87
    
88
friend class SamplerCollector;
89
    bool _used;
90
    // Number of external borrowers, guarded by _mutex.
91
    int _nborrow;
92
    // Set by destroy() when _nborrow > 0, telling the sampling thread to leak
93
    // this sampler instead of deleting it. Guarded by _mutex.
94
    bool _leaked;
95
    mutable butil::Mutex _mutex;
96
    // For diagnostics only, see set_debug_name().
97
    std::string _debug_name;
98
};
99
100
// Representing a non-existing operator so that we can test
101
// is_same<Op, VoidOp>::value to write code for different branches.
102
// The false branch should be removed by compiler at compile-time.
103
struct VoidOp {
104
    template <typename T>
105
0
    T operator()(const T&, const T&) const {
106
0
        CHECK(false) << "This function should never be called, abort";
107
0
        abort();
108
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
109
};
110
111
// Detects whether the host R exposes share_combiner(), namely whether its
112
// sampling data lives in a shared_ptr-managed carrier (an AgentCombiner) that
113
// the sampler is able to hold on its own. Hosts keeping the data elsewhere --
114
// a user callback in PassiveStatus, or a value-type babylon counter -- do NOT
115
// provide it and are sampled through the host pointer as before.
116
template <typename R>
117
class HasShareCombiner {
118
    template <typename U>
119
    static auto probe(U* p) -> decltype(p->share_combiner(), std::true_type());
120
    static std::false_type probe(...);
121
public:
122
    static const bool value = decltype(probe(std::declval<R*>()))::value;
123
};
124
125
// Samples through the host pointer, for hosts keeping their data outside a
126
// shared carrier (a user callback in PassiveStatus, a value-type babylon
127
// counter, ...).
128
template <typename R, typename T, typename Op, typename InvOp>
129
class HostSampleSource {
130
public:
131
    explicit HostSampleSource(R* host)
132
0
        : _host(host), _op(host->op()), _inv_op(host->inv_op()) {}
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::HostSampleSource(bvar::PassiveStatus<double>*)
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::HostSampleSource(bvar::PassiveStatus<long>*)
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::HostSampleSource(bvar::PassiveStatus<unsigned long>*)
133
134
    // Only reached from take_sample(), namely from the sampling thread, which is
135
    // mutually exclusive with the host's destroy(). The host is therefore always
136
    // alive here.
137
0
    T reset() { return _host->reset(); }
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::reset()
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::reset()
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::reset()
138
0
    T get_value() const { return _host->get_value(); }
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::get_value() const
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::get_value() const
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::get_value() const
139
140
    // Never touch the host, see the ctor.
141
0
    const Op& op() const { return _op; }
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::op() const
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::op() const
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::op() const
142
0
    const InvOp& inv_op() const { return _inv_op; }
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<long>, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::inv_op() const
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<double>, double, bvar::detail::AddTo<double>, bvar::detail::MinusFrom<double> >::inv_op() const
Unexecuted instantiation: bvar::detail::HostSampleSource<bvar::PassiveStatus<unsigned long>, unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >::inv_op() const
143
144
private:
145
    R* _host;
146
    Op _op;
147
    InvOp _inv_op;
148
};
149
150
// Samples directly from the shared data carrier, so that sampling still reads
151
// valid memory even if the host is destructed before the sampler is recycled.
152
// `Op'/`InvOp' are stateless functors, thus copied by value at construction and
153
// the host is never touched afterwards.
154
template <typename R, typename T, typename Op, typename InvOp>
155
class CombinerSampleSource {
156
public:
157
    explicit CombinerSampleSource(R* host)
158
3
        : _combiner(host->share_combiner())
159
3
        , _op(host->op())
160
3
        , _inv_op(host->inv_op()) {}
bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::CombinerSampleSource(bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >*)
Line
Count
Source
158
2
        : _combiner(host->share_combiner())
159
2
        , _op(host->op())
160
2
        , _inv_op(host->inv_op()) {}
bvar::detail::CombinerSampleSource<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::CombinerSampleSource(bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >*)
Line
Count
Source
158
1
        : _combiner(host->share_combiner())
159
1
        , _op(host->op())
160
1
        , _inv_op(host->inv_op()) {}
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::CombinerSampleSource(bvar::IntRecorder*)
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::CombinerSampleSource(bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>*)
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::CombinerSampleSource(bvar::detail::Percentile*)
Unexecuted instantiation: bvar::detail::CombinerSampleSource<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> >::CombinerSampleSource(bvar::Reducer<unsigned long, bvar::detail::AddTo<unsigned long>, bvar::detail::MinusFrom<unsigned long> >*)
161
162
0
    T reset() { return _combiner->reset_all_agents(); }
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::reset()
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::reset()
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::reset()
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::reset()
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::reset()
Unexecuted instantiation: bvar::detail::CombinerSampleSource<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> >::reset()
163
3
    T get_value() const { return _combiner->combine_agents(); }
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::get_value() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::get_value() const
bvar::detail::CombinerSampleSource<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::get_value() const
Line
Count
Source
163
1
    T get_value() const { return _combiner->combine_agents(); }
bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::get_value() const
Line
Count
Source
163
2
    T get_value() const { return _combiner->combine_agents(); }
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::get_value() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<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() const
164
0
    const Op& op() const { return _op; }
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<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> >::op() const
165
0
    const InvOp& inv_op() const { return _inv_op; }
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::inv_op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >, int, bvar::detail::AddTo<int>, bvar::detail::MinusFrom<int> >::inv_op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >, long, bvar::detail::AddTo<long>, bvar::detail::MinusFrom<long> >::inv_op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::Reducer<long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>, long, bvar::detail::MaxTo<long>, bvar::detail::VoidOp>::inv_op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<bvar::detail::Percentile, bvar::detail::PercentileSamples<254ul>, bvar::detail::detail::AddPercentileSamples, bvar::detail::VoidOp>::inv_op() const
Unexecuted instantiation: bvar::detail::CombinerSampleSource<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> >::inv_op() const
166
167
private:
168
    typename R::shared_combiner_type _combiner;
169
    Op _op;
170
    InvOp _inv_op;
171
};
172
173
// The sampler for reducer-alike variables.
174
// The R should have following methods:
175
//  - T reset();
176
//  - T get_value();
177
//  - Op op();
178
//  - InvOp inv_op();
179
// Additionally, if R exposes
180
//  - shared_combiner_type share_combiner();
181
// the sampler holds that shared carrier instead of R itself, which makes
182
// sampling immune to R being destructed first.
183
template <typename R, typename T, typename Op, typename InvOp>
184
class ReducerSampler : public Sampler {
185
    typedef typename butil::conditional<
186
        HasShareCombiner<R>::value,
187
        CombinerSampleSource<R, T, Op, InvOp>,
188
        HostSampleSource<R, T, Op, InvOp> >::type source_type;
189
190
public:
191
    static const time_t MAX_SECONDS_LIMIT = 3600;
192
193
    explicit ReducerSampler(R* reducer)
194
3
        : _source(reducer)
195
3
        , _window_size(1) {
196
        
197
        // Invoked take_sample at begining so the value of the first second
198
        // would not be ignored
199
3
        take_sample();
200
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<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
194
2
        : _source(reducer)
195
2
        , _window_size(1) {
196
        
197
        // Invoked take_sample at begining so the value of the first second
198
        // would not be ignored
199
2
        take_sample();
200
2
    }
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
194
1
        : _source(reducer)
195
1
        , _window_size(1) {
196
        
197
        // Invoked take_sample at begining so the value of the first second
198
        // would not be ignored
199
1
        take_sample();
200
1
    }
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> >*)
201
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<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::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::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()
202
203
3
    void take_sample() override {
204
        // Make _q ready.
205
        // If _window_size is larger than what _q can hold, e.g. a larger
206
        // Window<> is created after running of sampler, make _q larger.
207
3
        if ((size_t)_window_size + 1 > _q.capacity()) {
208
3
            const size_t new_cap =
209
3
                std::max(_q.capacity() * 2, (size_t)_window_size + 1);
210
3
            const size_t memsize = sizeof(Sample<T>) * new_cap;
211
3
            void* mem = malloc(memsize);
212
3
            if (nullptr == mem) {
213
0
                return;
214
0
            }
215
3
            butil::BoundedQueue<Sample<T> > new_q(
216
3
                mem, memsize, butil::OWNS_STORAGE);
217
3
            Sample<T> tmp;
218
3
            while (_q.pop(&tmp)) {
219
0
                new_q.push(tmp);
220
0
            }
221
3
            new_q.swap(_q);
222
3
        }
223
224
3
        Sample<T> latest;
225
3
        if (butil::is_same<InvOp, VoidOp>::value) {
226
            // The operator can't be inversed.
227
            // We reset the reducer and save the result as a sample.
228
            // Suming up samples gives the result within a window.
229
            // In this case, get_value() of _reducer gives wrong answer and
230
            // should not be called.
231
0
            latest.data = _source.reset();
232
3
        } else {
233
            // The operator can be inversed.
234
            // We save the result as a sample.
235
            // Inversed operation between latest and oldest sample within a
236
            // window gives result.
237
            // get_value() of _reducer can still be called.
238
3
            latest.data = _source.get_value();
239
3
        }
240
3
        latest.time_us = butil::cpuwide_time_us();
241
3
        _q.elim_push(latest);
242
3
    }
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
203
1
    void take_sample() override {
204
        // Make _q ready.
205
        // If _window_size is larger than what _q can hold, e.g. a larger
206
        // Window<> is created after running of sampler, make _q larger.
207
1
        if ((size_t)_window_size + 1 > _q.capacity()) {
208
1
            const size_t new_cap =
209
1
                std::max(_q.capacity() * 2, (size_t)_window_size + 1);
210
1
            const size_t memsize = sizeof(Sample<T>) * new_cap;
211
1
            void* mem = malloc(memsize);
212
1
            if (nullptr == mem) {
213
0
                return;
214
0
            }
215
1
            butil::BoundedQueue<Sample<T> > new_q(
216
1
                mem, memsize, butil::OWNS_STORAGE);
217
1
            Sample<T> tmp;
218
1
            while (_q.pop(&tmp)) {
219
0
                new_q.push(tmp);
220
0
            }
221
1
            new_q.swap(_q);
222
1
        }
223
224
1
        Sample<T> latest;
225
1
        if (butil::is_same<InvOp, VoidOp>::value) {
226
            // The operator can't be inversed.
227
            // We reset the reducer and save the result as a sample.
228
            // Suming up samples gives the result within a window.
229
            // In this case, get_value() of _reducer gives wrong answer and
230
            // should not be called.
231
0
            latest.data = _source.reset();
232
1
        } else {
233
            // The operator can be inversed.
234
            // We save the result as a sample.
235
            // Inversed operation between latest and oldest sample within a
236
            // window gives result.
237
            // get_value() of _reducer can still be called.
238
1
            latest.data = _source.get_value();
239
1
        }
240
1
        latest.time_us = butil::cpuwide_time_us();
241
1
        _q.elim_push(latest);
242
1
    }
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
203
2
    void take_sample() override {
204
        // Make _q ready.
205
        // If _window_size is larger than what _q can hold, e.g. a larger
206
        // Window<> is created after running of sampler, make _q larger.
207
2
        if ((size_t)_window_size + 1 > _q.capacity()) {
208
2
            const size_t new_cap =
209
2
                std::max(_q.capacity() * 2, (size_t)_window_size + 1);
210
2
            const size_t memsize = sizeof(Sample<T>) * new_cap;
211
2
            void* mem = malloc(memsize);
212
2
            if (nullptr == mem) {
213
0
                return;
214
0
            }
215
2
            butil::BoundedQueue<Sample<T> > new_q(
216
2
                mem, memsize, butil::OWNS_STORAGE);
217
2
            Sample<T> tmp;
218
2
            while (_q.pop(&tmp)) {
219
0
                new_q.push(tmp);
220
0
            }
221
2
            new_q.swap(_q);
222
2
        }
223
224
2
        Sample<T> latest;
225
2
        if (butil::is_same<InvOp, VoidOp>::value) {
226
            // The operator can't be inversed.
227
            // We reset the reducer and save the result as a sample.
228
            // Suming up samples gives the result within a window.
229
            // In this case, get_value() of _reducer gives wrong answer and
230
            // should not be called.
231
0
            latest.data = _source.reset();
232
2
        } else {
233
            // The operator can be inversed.
234
            // We save the result as a sample.
235
            // Inversed operation between latest and oldest sample within a
236
            // window gives result.
237
            // get_value() of _reducer can still be called.
238
2
            latest.data = _source.get_value();
239
2
        }
240
2
        latest.time_us = butil::cpuwide_time_us();
241
2
        _q.elim_push(latest);
242
2
    }
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()
243
244
0
    bool get_value(time_t window_size, Sample<T>* result) {
245
0
        if (window_size <= 0) {
246
0
            LOG(FATAL) << "Invalid window_size=" << window_size;
247
0
            return false;
248
0
        }
249
0
        BAIDU_SCOPED_LOCK(_mutex);
250
0
        if (_q.size() <= 1UL) {
251
            // We need more samples to get reasonable result.
252
0
            return false;
253
0
        }
254
0
        Sample<T>* oldest = _q.bottom(window_size);
255
0
        if (nullptr == oldest) {
256
0
            oldest = _q.top();
257
0
        }
258
0
        Sample<T>* latest = _q.bottom();
259
0
        DCHECK(latest != oldest);
260
0
        if (butil::is_same<InvOp, VoidOp>::value) {
261
            // No inverse op. Sum up all samples within the window.
262
0
            result->data = latest->data;
263
0
            for (int i = 1; true; ++i) {
264
0
                Sample<T>* e = _q.bottom(i);
265
0
                if (e == oldest) {
266
0
                    break;
267
0
                }
268
0
                _source.op()(result->data, e->data);
269
0
            }
270
0
        } else {
271
            // Diff the latest and oldest sample within the window.
272
0
            result->data = latest->data;
273
0
            _source.inv_op()(result->data, oldest->data);
274
0
        }
275
0
        result->time_us = latest->time_us - oldest->time_us;
276
0
        return true;
277
0
    }
Unexecuted instantiation: bvar::detail::ReducerSampler<bvar::IntRecorder, bvar::Stat, bvar::detail::AddStat, bvar::detail::MinusStat>::get_value(long, bvar::detail::Sample<bvar::Stat>*)
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> >::get_value(long, bvar::detail::Sample<int>*)
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> >::get_value(long, bvar::detail::Sample<long>*)
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>*)
278
279
    // Change the time window which can only go larger.
280
3
    int set_window_size(time_t window_size) {
281
3
        if (window_size <= 0 || window_size > MAX_SECONDS_LIMIT) {
282
0
            LOG(ERROR) << "Invalid window_size=" << window_size;
283
0
            return -1;
284
0
        }
285
3
        BAIDU_SCOPED_LOCK(_mutex);
286
3
        if (window_size > _window_size) {
287
3
            _window_size = window_size;
288
3
        }
289
3
        return 0;
290
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
280
1
    int set_window_size(time_t window_size) {
281
1
        if (window_size <= 0 || window_size > MAX_SECONDS_LIMIT) {
282
0
            LOG(ERROR) << "Invalid window_size=" << window_size;
283
0
            return -1;
284
0
        }
285
1
        BAIDU_SCOPED_LOCK(_mutex);
286
1
        if (window_size > _window_size) {
287
1
            _window_size = window_size;
288
1
        }
289
1
        return 0;
290
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
280
2
    int set_window_size(time_t window_size) {
281
2
        if (window_size <= 0 || window_size > MAX_SECONDS_LIMIT) {
282
0
            LOG(ERROR) << "Invalid window_size=" << window_size;
283
0
            return -1;
284
0
        }
285
2
        BAIDU_SCOPED_LOCK(_mutex);
286
2
        if (window_size > _window_size) {
287
2
            _window_size = window_size;
288
2
        }
289
2
        return 0;
290
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)
291
292
0
    void get_samples(std::vector<T> *samples, time_t window_size) {
293
0
        if (window_size <= 0) {
294
0
            LOG(FATAL) << "Invalid window_size=" << window_size;
295
0
            return;
296
0
        }
297
0
        BAIDU_SCOPED_LOCK(_mutex);
298
0
        if (_q.size() <= 1) {
299
            // We need more samples to get reasonable result.
300
0
            return;
301
0
        }
302
0
        Sample<T>* oldest = _q.bottom(window_size);
303
0
        if (nullptr == oldest) {
304
0
            oldest = _q.top();
305
0
        }
306
0
        for (int i = 1; true; ++i) {
307
0
            Sample<T>* e = _q.bottom(i);
308
0
            if (e == oldest) {
309
0
                break;
310
0
            }
311
0
            samples->push_back(e->data);
312
0
        }
313
0
    }
314
315
private:
316
    source_type _source;
317
    time_t _window_size;
318
    butil::BoundedQueue<Sample<T> > _q;
319
};
320
321
}  // namespace detail
322
}  // namespace bvar
323
324
#endif  // BVAR_DETAIL_SAMPLER_H