xrpld
Loading...
Searching...
No Matches
DecayingSample.h
1#pragma once
2
3#include <chrono>
4#include <cmath>
5#include <cstddef>
6
7namespace xrpl {
8
13template <int Window, typename Clock>
15{
16public:
17 using value_type = Clock::duration::rep;
18 using time_point = Clock::time_point;
19
20 DecayingSample() = delete;
21
26 {
27 }
28
35 {
36 decay(now);
37 value_ += value;
38 return value_ / Window;
39 }
40
47 {
48 decay(now);
49 return value_ / Window;
50 }
51
52private:
53 // Apply exponential decay based on the specified time.
54 void
56 {
57 if (now == when_)
58 return;
59
60 if (value_ != value_type())
61 {
62 std::size_t elapsed =
64
65 // A span larger than four times the window decays the
66 // value to an insignificant amount so just reset it.
67 //
68 if (elapsed > 4 * Window)
69 {
71 }
72 else
73 {
74 for (; elapsed > 0; --elapsed)
75 {
76 value_ -= (value_ + Window - 1) / Window;
77 }
78 }
79 }
80
81 when_ = now;
82 }
83
84 // Current value in exponential units
86
87 // Last time the aging function was applied
89};
90
91//------------------------------------------------------------------------------
92
97template <int HalfLife, class Clock>
99{
100public:
101 using time_point = Clock::time_point;
102
103 explicit DecayWindow(time_point now) : when_(now)
104 {
105 }
106
107 void
108 add(double value, time_point now)
109 {
110 decay(now);
111 value_ += value;
112 }
113
114 double
116 {
117 decay(now);
118 return value_ / HalfLife;
119 }
120
121private:
122 static_assert(HalfLife > 0, "half life must be positive");
123
124 void
126 {
127 if (now <= when_)
128 return;
129 using namespace std::chrono;
130 auto const elapsed = duration<double>(now - when_).count();
131 value_ *= std::pow(2.0, -elapsed / HalfLife);
132 when_ = now;
133 }
134
135 double value_{0};
137};
138
139} // 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)