1f7ea2997SKrzysztof Grobelny #include "metrics/collection_data.hpp"
2f7ea2997SKrzysztof Grobelny
3f7ea2997SKrzysztof Grobelny #include "metrics/collection_function.hpp"
4f7ea2997SKrzysztof Grobelny
5f7ea2997SKrzysztof Grobelny namespace metrics
6f7ea2997SKrzysztof Grobelny {
7f7ea2997SKrzysztof Grobelny
updateLastValue(double value)8f7ea2997SKrzysztof Grobelny bool CollectionData::updateLastValue(double value)
9f7ea2997SKrzysztof Grobelny {
10f7ea2997SKrzysztof Grobelny const bool changed = lastValue != value;
11f7ea2997SKrzysztof Grobelny lastValue = value;
12f7ea2997SKrzysztof Grobelny return changed;
13f7ea2997SKrzysztof Grobelny }
14f7ea2997SKrzysztof Grobelny
15f7ea2997SKrzysztof Grobelny class DataPoint : public CollectionData
16f7ea2997SKrzysztof Grobelny {
17f7ea2997SKrzysztof Grobelny public:
update(Milliseconds)18f7ea2997SKrzysztof Grobelny std::optional<double> update(Milliseconds) override
19f7ea2997SKrzysztof Grobelny {
20f7ea2997SKrzysztof Grobelny return lastReading;
21f7ea2997SKrzysztof Grobelny }
22f7ea2997SKrzysztof Grobelny
update(Milliseconds,double reading)23f7ea2997SKrzysztof Grobelny double update(Milliseconds, double reading) override
24f7ea2997SKrzysztof Grobelny {
25f7ea2997SKrzysztof Grobelny lastReading = reading;
26f7ea2997SKrzysztof Grobelny return reading;
27f7ea2997SKrzysztof Grobelny }
28f7ea2997SKrzysztof Grobelny
29f7ea2997SKrzysztof Grobelny private:
30f7ea2997SKrzysztof Grobelny std::optional<double> lastReading;
31f7ea2997SKrzysztof Grobelny };
32f7ea2997SKrzysztof Grobelny
33f7ea2997SKrzysztof Grobelny class DataInterval : public CollectionData
34f7ea2997SKrzysztof Grobelny {
35f7ea2997SKrzysztof Grobelny public:
DataInterval(std::shared_ptr<CollectionFunction> function,CollectionDuration duration)36f7ea2997SKrzysztof Grobelny DataInterval(std::shared_ptr<CollectionFunction> function,
37f7ea2997SKrzysztof Grobelny CollectionDuration duration) :
38f535cad6SPatrick Williams function(std::move(function)), duration(duration)
39f7ea2997SKrzysztof Grobelny {
40f7ea2997SKrzysztof Grobelny if (duration.t.count() == 0)
41f7ea2997SKrzysztof Grobelny {
4262c08e9bSKrzysztof Grobelny throw errors::InvalidArgument(
4362c08e9bSKrzysztof Grobelny "ReadingParameters.CollectionDuration");
44f7ea2997SKrzysztof Grobelny }
45f7ea2997SKrzysztof Grobelny }
46f7ea2997SKrzysztof Grobelny
update(Milliseconds timestamp)47f7ea2997SKrzysztof Grobelny std::optional<double> update(Milliseconds timestamp) override
48f7ea2997SKrzysztof Grobelny {
49f7ea2997SKrzysztof Grobelny if (readings.empty())
50f7ea2997SKrzysztof Grobelny {
51f7ea2997SKrzysztof Grobelny return std::nullopt;
52f7ea2997SKrzysztof Grobelny }
53f7ea2997SKrzysztof Grobelny
54f7ea2997SKrzysztof Grobelny cleanup(timestamp);
55f7ea2997SKrzysztof Grobelny
56f7ea2997SKrzysztof Grobelny return function->calculate(readings, timestamp);
57f7ea2997SKrzysztof Grobelny }
58f7ea2997SKrzysztof Grobelny
update(Milliseconds timestamp,double reading)59f7ea2997SKrzysztof Grobelny double update(Milliseconds timestamp, double reading) override
60f7ea2997SKrzysztof Grobelny {
61f7ea2997SKrzysztof Grobelny readings.emplace_back(timestamp, reading);
62f7ea2997SKrzysztof Grobelny
63f7ea2997SKrzysztof Grobelny cleanup(timestamp);
64f7ea2997SKrzysztof Grobelny
65f7ea2997SKrzysztof Grobelny return function->calculate(readings, timestamp);
66f7ea2997SKrzysztof Grobelny }
67f7ea2997SKrzysztof Grobelny
68f7ea2997SKrzysztof Grobelny private:
cleanup(Milliseconds timestamp)69f7ea2997SKrzysztof Grobelny void cleanup(Milliseconds timestamp)
70f7ea2997SKrzysztof Grobelny {
71f7ea2997SKrzysztof Grobelny auto it = readings.begin();
72f7ea2997SKrzysztof Grobelny for (auto kt = std::next(readings.rbegin()); kt != readings.rend();
73f7ea2997SKrzysztof Grobelny ++kt)
74f7ea2997SKrzysztof Grobelny {
75f7ea2997SKrzysztof Grobelny const auto& [nextItemTimestamp, nextItemReading] = *std::prev(kt);
76f7ea2997SKrzysztof Grobelny if (timestamp >= nextItemTimestamp &&
77f7ea2997SKrzysztof Grobelny timestamp - nextItemTimestamp > duration.t)
78f7ea2997SKrzysztof Grobelny {
79f7ea2997SKrzysztof Grobelny it = kt.base();
80f7ea2997SKrzysztof Grobelny break;
81f7ea2997SKrzysztof Grobelny }
82f7ea2997SKrzysztof Grobelny }
83f7ea2997SKrzysztof Grobelny readings.erase(readings.begin(), it);
84f7ea2997SKrzysztof Grobelny
85f7ea2997SKrzysztof Grobelny if (timestamp > duration.t)
86f7ea2997SKrzysztof Grobelny {
87*583ba441SPatrick Williams readings.front().first =
88*583ba441SPatrick Williams std::max(readings.front().first, timestamp - duration.t);
89f7ea2997SKrzysztof Grobelny }
90f7ea2997SKrzysztof Grobelny }
91f7ea2997SKrzysztof Grobelny
92f7ea2997SKrzysztof Grobelny std::shared_ptr<CollectionFunction> function;
93f7ea2997SKrzysztof Grobelny std::vector<ReadingItem> readings;
94f7ea2997SKrzysztof Grobelny CollectionDuration duration;
95f7ea2997SKrzysztof Grobelny };
96f7ea2997SKrzysztof Grobelny
97f7ea2997SKrzysztof Grobelny class DataStartup : public CollectionData
98f7ea2997SKrzysztof Grobelny {
99f7ea2997SKrzysztof Grobelny public:
DataStartup(std::shared_ptr<CollectionFunction> function)100f7ea2997SKrzysztof Grobelny explicit DataStartup(std::shared_ptr<CollectionFunction> function) :
101f7ea2997SKrzysztof Grobelny function(std::move(function))
102f7ea2997SKrzysztof Grobelny {}
103f7ea2997SKrzysztof Grobelny
update(Milliseconds timestamp)104f7ea2997SKrzysztof Grobelny std::optional<double> update(Milliseconds timestamp) override
105f7ea2997SKrzysztof Grobelny {
106f7ea2997SKrzysztof Grobelny if (readings.empty())
107f7ea2997SKrzysztof Grobelny {
108f7ea2997SKrzysztof Grobelny return std::nullopt;
109f7ea2997SKrzysztof Grobelny }
110f7ea2997SKrzysztof Grobelny
111f7ea2997SKrzysztof Grobelny return function->calculateForStartupInterval(readings, timestamp);
112f7ea2997SKrzysztof Grobelny }
113f7ea2997SKrzysztof Grobelny
update(Milliseconds timestamp,double reading)114f7ea2997SKrzysztof Grobelny double update(Milliseconds timestamp, double reading) override
115f7ea2997SKrzysztof Grobelny {
116f7ea2997SKrzysztof Grobelny readings.emplace_back(timestamp, reading);
117f7ea2997SKrzysztof Grobelny return function->calculateForStartupInterval(readings, timestamp);
118f7ea2997SKrzysztof Grobelny }
119f7ea2997SKrzysztof Grobelny
120f7ea2997SKrzysztof Grobelny private:
121f7ea2997SKrzysztof Grobelny std::shared_ptr<CollectionFunction> function;
122f7ea2997SKrzysztof Grobelny std::vector<ReadingItem> readings;
123f7ea2997SKrzysztof Grobelny };
124f7ea2997SKrzysztof Grobelny
makeCollectionData(size_t size,OperationType op,CollectionTimeScope timeScope,CollectionDuration duration)125*583ba441SPatrick Williams std::vector<std::unique_ptr<CollectionData>> makeCollectionData(
126*583ba441SPatrick Williams size_t size, OperationType op, CollectionTimeScope timeScope,
127f7ea2997SKrzysztof Grobelny CollectionDuration duration)
128f7ea2997SKrzysztof Grobelny {
129f7ea2997SKrzysztof Grobelny using namespace std::string_literals;
130f7ea2997SKrzysztof Grobelny
131f7ea2997SKrzysztof Grobelny std::vector<std::unique_ptr<CollectionData>> result;
132f7ea2997SKrzysztof Grobelny
133f7ea2997SKrzysztof Grobelny result.reserve(size);
134f7ea2997SKrzysztof Grobelny
135f7ea2997SKrzysztof Grobelny switch (timeScope)
136f7ea2997SKrzysztof Grobelny {
137f7ea2997SKrzysztof Grobelny case CollectionTimeScope::interval:
138*583ba441SPatrick Williams std::generate_n(
139*583ba441SPatrick Williams std::back_inserter(result), size,
140f7ea2997SKrzysztof Grobelny [cf = makeCollectionFunction(op), duration] {
1413a1c297aSPatrick Williams return std::make_unique<DataInterval>(cf, duration);
142f7ea2997SKrzysztof Grobelny });
143f7ea2997SKrzysztof Grobelny break;
144f7ea2997SKrzysztof Grobelny case CollectionTimeScope::point:
145f7ea2997SKrzysztof Grobelny std::generate_n(std::back_inserter(result), size,
146f7ea2997SKrzysztof Grobelny [] { return std::make_unique<DataPoint>(); });
147f7ea2997SKrzysztof Grobelny break;
148f7ea2997SKrzysztof Grobelny case CollectionTimeScope::startup:
149f7ea2997SKrzysztof Grobelny std::generate_n(std::back_inserter(result), size,
150f7ea2997SKrzysztof Grobelny [cf = makeCollectionFunction(op)] {
151f7ea2997SKrzysztof Grobelny return std::make_unique<DataStartup>(cf);
152f7ea2997SKrzysztof Grobelny });
153f7ea2997SKrzysztof Grobelny break;
154f7ea2997SKrzysztof Grobelny }
155f7ea2997SKrzysztof Grobelny
156f7ea2997SKrzysztof Grobelny return result;
157f7ea2997SKrzysztof Grobelny }
158f7ea2997SKrzysztof Grobelny
159f7ea2997SKrzysztof Grobelny } // namespace metrics
160