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