rippled
Loading...
Searching...
No Matches
DecayingSample.h
1#ifndef XRPL_BASICS_DECAYINGSAMPLE_H_INCLUDED
2#define XRPL_BASICS_DECAYINGSAMPLE_H_INCLUDED
3
4#include <chrono>
5#include <cmath>
6
7namespace ripple {
8
12template <int Window, typename Clock>
14{
15public:
16 using value_type = typename Clock::duration::rep;
17 using time_point = typename Clock::time_point;
18
19 DecayingSample() = delete;
20
25 {
26 }
27
33 {
34 decay(now);
35 m_value += value;
36 return m_value / Window;
37 }
38
44 {
45 decay(now);
46 return m_value / Window;
47 }
48
49private:
50 // Apply exponential decay based on the specified time.
51 void
53 {
54 if (now == m_when)
55 return;
56
57 if (m_value != value_type())
58 {
59 std::size_t elapsed =
60 std::chrono::duration_cast<std::chrono::seconds>(now - m_when)
61 .count();
62
63 // A span larger than four times the window decays the
64 // value to an insignificant amount so just reset it.
65 //
66 if (elapsed > 4 * Window)
67 {
69 }
70 else
71 {
72 while (elapsed--)
73 m_value -= (m_value + Window - 1) / Window;
74 }
75 }
76
77 m_when = now;
78 }
79
80 // Current value in exponential units
82
83 // Last time the aging function was applied
85};
86
87//------------------------------------------------------------------------------
88
92template <int HalfLife, class Clock>
94{
95public:
96 using time_point = typename Clock::time_point;
97
98 explicit DecayWindow(time_point now) : value_(0), when_(now)
99 {
100 }
101
102 void
103 add(double value, time_point now)
104 {
105 decay(now);
106 value_ += value;
107 }
108
109 double
111 {
112 decay(now);
113 return value_ / HalfLife;
114 }
115
116private:
117 static_assert(HalfLife > 0, "half life must be positive");
118
119 void
121 {
122 if (now <= when_)
123 return;
124 using namespace std::chrono;
125 auto const elapsed = duration<double>(now - when_).count();
126 value_ *= std::pow(2.0, -elapsed / HalfLife);
127 when_ = now;
128 }
129
130 double value_;
132};
133
134} // namespace ripple
135
136#endif
Sampling function using exponential decay to provide a continuous value.
void decay(time_point now)
double value(time_point now)
DecayWindow(time_point now)
typename Clock::time_point time_point
void add(double value, time_point now)
Sampling function using exponential decay to provide a continuous value.
typename Clock::duration::rep value_type
void decay(time_point now)
DecayingSample(time_point now)
value_type add(value_type value, time_point now)
Add a new sample.
typename Clock::time_point time_point
value_type value(time_point now)
Retrieve the current value in normalized units.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
T pow(T... args)