xrpld
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 = Clock::duration::rep;
16 using time_point = Clock::time_point;
17
18 DecayingSample() = delete;
19
24 {
25 }
26
32 {
33 decay(now);
34 value_ += value;
35 return value_ / Window;
36 }
37
43 {
44 decay(now);
45 return value_ / Window;
46 }
47
48private:
49 // Apply exponential decay based on the specified time.
50 void
52 {
53 if (now == when_)
54 return;
55
56 if (value_ != value_type())
57 {
58 std::size_t elapsed =
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 for (; elapsed > 0; --elapsed)
71 {
72 value_ -= (value_ + Window - 1) / Window;
73 }
74 }
75 }
76
77 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 = Clock::time_point;
97
98 explicit DecayWindow(time_point now) : 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_{0};
132};
133
134} // namespace xrpl
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)
value_type value(time_point now)
Retrieve the current value in normalized units.
Clock::duration::rep value_type
DecayingSample(time_point now)
value_type add(value_type value, time_point now)
Add a new sample.
Clock::time_point time_point
void decay(time_point now)
T duration_cast(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
T pow(T... args)