JayBeams  0.1
Another project to have fun coding.
event_rate_histogram.hpp
Go to the documentation of this file.
1 #ifndef jb_event_rate_histogram_hpp
2 #define jb_event_rate_histogram_hpp
3 
5 #include <jb/histogram.hpp>
7 
8 namespace jb {
9 
10 /**
11  * Keep a histogram of observed event rates.
12  *
13  * This class collects running statistics about event rates. While an
14  * event_rate_estimator computes the number of events in the last X
15  * seconds, this class keeps a tally of the observed event rates,
16  * which can be used to build median, maximum and any other quantile
17  * of the message rate.
18  *
19  * The user specifies the maximum message rate to keep at full
20  * resolution, any rate above that value is simply recorded in the
21  * histogram overflow bucket.
22  *
23  * For example to keep track of per-millisecond message rate you would
24  * instantiate the class as follows:
25  *
26  * @code
27  * typedef event_rate_histogram<
28  * int, std::chrono::microseconds> my_rate_histogram;
29  * int max_expected_rate = 1000000;
30  * my_rate_histogram rate_histo(
31  * max_expected_rate, std::chrono::microseconds(1000));
32  *
33  * ...
34  * rate_histo.sample(timestamp);
35  * ...
36  * rate_histo.sample(timestamp);
37  * @endcode
38  *
39  * The user of the class must provide a maximum expected message rate,
40  * higher rates are recorded in a single 'overflow' bucket. If you
41  * guess too high on the rate the rate_histo object would consume more
42  * memory than necessary. If you guess too low the high quantiles
43  * might be less accurate. Memory requirements are low (the data
44  * structure is basically a vector of ints), but can be an issue if
45  * you create many histograms (for example, one histogram per security
46  * when analyzing a market data feed).
47  *
48  * @tparam duration_type Define the units used to measure time. This
49  * class assumes all events are timestamped with a class compatible
50  * with std::chrono::duration<>, against some epoch that is defined
51  * by convention but not explicitly provided to the class. This is
52  * convenient because some feeds just provide microseconds or
53  * nanoseconds since midnight, while others use microseconds since
54  * the Unix Epoch. If you are using some kind of
55  * std::chrono::time_point<> object for your timestamps simply call
56  * time_since_epoch() on the object before sampling.
57  * @tparam counter_type The type used in the histogram counters. For
58  * most applications @a int is adequate, but you may use a
59  * smaller type if (a) you are memory constrained, and (b) you do
60  * not expect high values in the counters. You might also consider
61  * a wider integral type if you expect very high number of events.
62  * @tparam rate_counter_type The type used in the event rate
63  * counters. Similar tradeofss as @a counter_type.
64  */
65 template <
66  typename duration_type = std::chrono::microseconds,
67  typename counter_type = int, typename rate_counter_type = int>
69  : private histogram<integer_range_binning<std::uint64_t>, counter_type> {
70 public:
71  //@{
72  /**
73  * @name Type traits.
74  */
77  //@}
78 
79  /**
80  * Constructor.
81  *
82  * @param max_expected_rate The histogram is kept at full resolution
83  * up to this rate, any periods with more events are counted only
84  * in the overflow bin. If this value is too low for the observed
85  * rates, the high quantiles may not be very accurate.
86  * @param measurement_period over what period we measure event rates.
87  * @param sampling_period how often do we measure event rates.
88  */
90  std::uint64_t max_expected_rate, duration_type measurement_period,
91  duration_type sampling_period = duration_type(1))
92  : rate_histogram(binning_strategy(0, max_expected_rate))
93  , rate_(measurement_period, sampling_period)
94  , last_rate_(0) {
95  }
96 
97  /// Record a new sample.
98  void sample(duration_type ts) {
99  rate_.sample(ts, [this](std::uint64_t rate, std::uint64_t repeats) {
100  this->last_rate_ = rate;
101  this->rate_histogram::weighted_sample(rate, repeats);
102  });
103  }
104 
105  /// Get the last sample, if any.
106  std::uint64_t last_rate() const {
107  if (nsamples() == 0) {
108  throw std::invalid_argument("No sample recorded yet");
109  }
110  return last_rate_;
111  }
112 
113  //@{
114  /**
115  * @name Histogram accessors.
116  */
124  //@}
125 
126 private:
128  std::uint64_t last_rate_;
129 };
130 
131 } // namespace jb
132 
133 #endif // jb_event_rate_histogram_hpp
Keep a histogram of observed event rates.
std::uint64_t last_rate() const
Get the last sample, if any.
A histogram class with controllable binning and range strategy.
Definition: histogram.hpp:46
integer_range_binning< std::uint64_t > binning_strategy
void sample(duration_type ts)
Record a new sample.
histogram< binning_strategy, counter_type > rate_histogram
event_rate_histogram(std::uint64_t max_expected_rate, duration_type measurement_period, duration_type sampling_period=duration_type(1))
Constructor.
sample_type estimated_quantile(double q) const
Estimate a quantile of the sample distribution.
Definition: histogram.hpp:136
sample_type observed_max() const
Return the largest sample value observed to this point.
Definition: histogram.hpp:89
void sample(duration_type ts, functor update)
Record a sample.
std::uint64_t underflow_count() const
Return the number of samples smaller than the histogram range.
Definition: histogram.hpp:175
sample_type observed_min() const
Return the smallest sample value observed to this point.
Definition: histogram.hpp:84
sample_type estimated_mean() const
Estimate the mean of the sample distribution.
Definition: histogram.hpp:98
event_rate_estimator< duration_type, rate_counter_type > rate_
std::uint64_t nsamples() const
Return the number of samples observed to this point.
Definition: histogram.hpp:79
void weighted_sample(sample_type const &t, counter_type weight)
Record a new sample.
Definition: histogram.hpp:202
std::uint64_t overflow_count() const
Return the number of samples larger than the histogram range.
Definition: histogram.hpp:180
The top-level namespace for the JayBeams library.
Definition: as_hhmmss.hpp:7