blob: d92fdf38dd331e87218f81925a69d2195d4caf34 [file] [log] [blame]
Krzysztof Grobelny80697712021-03-04 09:49:27 +00001#include "collection_function.hpp"
2
3#include <cmath>
4
5namespace details
6{
7
8class FunctionSingle : public CollectionFunction
9{
10 public:
11 ReadingItem calculate(const std::vector<ReadingItem>& readings,
12 uint64_t) const override
13 {
14 return readings.back();
15 }
16
17 ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
18 uint64_t timestamp) const override
19 {
20 readings.assign({readings.back()});
21 return readings.back();
22 }
23};
24
25class FunctionMinimum : public CollectionFunction
26{
27 public:
28 ReadingItem calculate(const std::vector<ReadingItem>& readings,
29 uint64_t) const override
30 {
31 return *std::min_element(
32 readings.begin(), readings.end(),
33 [](const auto& left, const auto& right) {
34 return std::make_tuple(!std::isfinite(left.second),
35 left.second) <
36 std::make_tuple(!std::isfinite(right.second),
37 right.second);
38 });
39 }
40
41 ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
42 uint64_t timestamp) const override
43 {
44 readings.assign({ReadingItem(calculate(readings, timestamp))});
45 return readings.back();
46 }
47};
48
49class FunctionMaximum : public CollectionFunction
50{
51 public:
52 ReadingItem calculate(const std::vector<ReadingItem>& readings,
53 uint64_t) const override
54 {
55 return *std::max_element(
56 readings.begin(), readings.end(),
57 [](const auto& left, const auto& right) {
58 return std::make_tuple(std::isfinite(left.second),
59 left.second) <
60 std::make_tuple(std::isfinite(right.second),
61 right.second);
62 });
63 }
64
65 ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
66 uint64_t timestamp) const override
67 {
68 readings.assign({ReadingItem(calculate(readings, timestamp))});
69 return readings.back();
70 }
71};
72
73class FunctionAverage : public CollectionFunction
74{
75 public:
76 ReadingItem calculate(const std::vector<ReadingItem>& readings,
77 uint64_t timestamp) const override
78 {
79 auto valueSum = 0.0;
80 auto timeSum = uint64_t{0};
81 for (auto it = readings.begin(); it != std::prev(readings.end()); ++it)
82 {
83 if (std::isfinite(it->second))
84 {
85 const auto kt = std::next(it);
86 const auto duration = kt->first - it->first;
87 valueSum += it->second * duration;
88 timeSum += duration;
89 }
90 }
91
92 const auto duration = timestamp - readings.back().first;
93 valueSum += readings.back().second * duration;
94 timeSum += duration;
95
96 return ReadingItem{timestamp, valueSum / timeSum};
97 }
98
99 ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
100 uint64_t timestamp) const override
101 {
102 auto result = calculate(readings, timestamp);
103 if (std::isfinite(result.second))
104 {
105 readings.assign({ReadingItem(readings.front().first, result.second),
106 ReadingItem(timestamp, readings.back().second)});
107 }
108 return result;
109 }
110};
111
112class FunctionSummation : public CollectionFunction
113{
114 public:
115 ReadingItem calculate(const std::vector<ReadingItem>& readings,
116 uint64_t timestamp) const override
117 {
118 auto valueSum = 0.0;
119 for (auto it = readings.begin(); it != std::prev(readings.end()); ++it)
120 {
121 if (std::isfinite(it->second))
122 {
123 const auto kt = std::next(it);
124 const auto duration = kt->first - it->first;
125 valueSum += it->second * duration;
126 }
127 }
128
129 const auto duration = timestamp - readings.back().first;
130 valueSum += readings.back().second * duration;
131
132 return ReadingItem{timestamp, valueSum};
133 }
134
135 ReadingItem calculateForStartupInterval(std::vector<ReadingItem>& readings,
136 uint64_t timestamp) const override
137 {
138 auto result = calculate(readings, timestamp);
139 if (std::isfinite(result.second) && timestamp > 0u)
140 {
141 readings.assign({ReadingItem(timestamp - 1u, result.second),
142 ReadingItem(timestamp, readings.back().second)});
143 }
144 return result;
145 }
146};
147
148std::shared_ptr<CollectionFunction>
149 makeCollectionFunction(OperationType operationType)
150{
151 using namespace std::string_literals;
152
153 switch (operationType)
154 {
155 case OperationType::single:
156 return std::make_shared<FunctionSingle>();
157 case OperationType::min:
158 return std::make_shared<FunctionMinimum>();
159 case OperationType::max:
160 return std::make_shared<FunctionMaximum>();
161 case OperationType::avg:
162 return std::make_shared<FunctionAverage>();
163 case OperationType::sum:
164 return std::make_shared<FunctionSummation>();
165 default:
166 throw std::runtime_error("op: "s +
167 utils::enumToString(operationType) +
168 " is not supported"s);
169 }
170}
171
172} // namespace details