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 =
59 std::chrono::duration_cast<std::chrono::seconds>(now - m_when).count();
60
61 // A span larger than four times the window decays the
62 // value to an insignificant amount so just reset it.
63 //
64 if (elapsed > 4 * Window)
65 {
67 }
68 else
69 {
70 while (elapsed--)
71 m_value -= (m_value + Window - 1) / Window;
72 }
73 }
74
75 m_when = now;
76 }
77
78 // Current value in exponential units
80
81 // Last time the aging function was applied
83};
84
85//------------------------------------------------------------------------------
86
90template <int HalfLife, class Clock>
92{
93public:
94 using time_point = typename Clock::time_point;
95
96 explicit DecayWindow(time_point now) : when_(now)
97 {
98 }
99
100 void
101 add(double value, time_point now)
102 {
103 decay(now);
104 value_ += value;
105 }
106
107 double
109 {
110 decay(now);
111 return value_ / HalfLife;
112 }
113
114private:
115 static_assert(HalfLife > 0, "half life must be positive");
116
117 void
119 {
120 if (now <= when_)
121 return;
122 using namespace std::chrono;
123 auto const elapsed = duration<double>(now - when_).count();
124 value_ *= std::pow(2.0, -elapsed / HalfLife);
125 when_ = now;
126 }
127
128 double value_{0};
130};
131
132} // 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)