blob: f231f26c533c36674c32ce5c8c77e6674d74e130 [file] [log] [blame]
Brad Bishop4041d722017-05-21 10:06:07 -04001#pragma once
2
3#include "callback.hpp"
4#include "data_types.hpp"
5
Ratan Gupta882d7412018-02-19 23:43:44 +05306#include <algorithm>
Andrew Geisslerf3367682020-05-16 14:02:45 -05007#include <cstddef>
Brad Bishop35e75f02018-02-26 09:43:41 -05008#include <functional>
Ratan Gupta882d7412018-02-19 23:43:44 +05309
Brad Bishop4041d722017-05-21 10:06:07 -040010namespace phosphor
11{
12namespace dbus
13{
14namespace monitoring
15{
16
17/** @class CountCondition
18 * @brief Count properties that satisfy a condition.
19 *
20 * When invoked, a count class instance performs its condition
21 * test in two passes.
22 *
23 * In pass one, apply a C++ relational operator to the value of
24 * each property in the index and a value provided by the
25 * configuration file.
26 *
27 * Count the number of properties that pass the test in pass
28 * one. In pass two, apply a second C++ relational operator
29 * to the number of properties that pass the test from pass one
30 * to a count provided by the configuration file.
Matt Spinlerc458dee2018-02-19 13:09:10 -060031 *
32 * If the oneshot parameter is true, then this condition won't pass
33 * again until it fails at least once.
Brad Bishop4041d722017-05-21 10:06:07 -040034 */
Patrick Venture3d6d3182018-08-31 09:33:09 -070035template <typename T>
36class CountCondition : public IndexedConditional
Brad Bishop4041d722017-05-21 10:06:07 -040037{
Brad Bishopd1eac882018-03-29 10:34:05 -040038 public:
39 CountCondition() = delete;
40 CountCondition(const CountCondition&) = default;
41 CountCondition(CountCondition&&) = default;
42 CountCondition& operator=(const CountCondition&) = default;
43 CountCondition& operator=(CountCondition&&) = default;
44 ~CountCondition() = default;
Brad Bishop4041d722017-05-21 10:06:07 -040045
Brad Bishopd1eac882018-03-29 10:34:05 -040046 CountCondition(const PropertyIndex& conditionIndex,
47 const std::function<bool(size_t)>& _countOp,
48 const std::function<bool(T)>& _propertyOp,
49 bool oneshot = false) :
50 IndexedConditional(conditionIndex),
51 countOp(_countOp), propertyOp(_propertyOp), oneshot(oneshot)
52 {
53 }
Brad Bishop4041d722017-05-21 10:06:07 -040054
Brad Bishopd1eac882018-03-29 10:34:05 -040055 bool operator()() override
56 {
57 // Count the number of properties in the index that
58 // pass the condition specified in the config file.
59 auto count = std::count_if(
60 index.cbegin(), index.cend(),
61 [this](const auto& item)
Brad Bishop4041d722017-05-21 10:06:07 -040062 // *INDENT-OFF*
Matt Spinlerc458dee2018-02-19 13:09:10 -060063 {
Brad Bishopd1eac882018-03-29 10:34:05 -040064 // Get the property value from storage[0],
65 // and save the op result in storage[1].
66 const auto& storage = std::get<storageIndex>(item.second);
67 // Don't count properties that don't exist.
68 if (std::get<valueIndex>(storage.get()).empty())
69 {
70 return false;
71 }
72 const auto& value =
73 any_ns::any_cast<T>(std::get<valueIndex>(storage.get()));
74 auto r = propertyOp(value);
Matt Spinlerc458dee2018-02-19 13:09:10 -060075
Brad Bishopd1eac882018-03-29 10:34:05 -040076 std::get<resultIndex>(storage.get()) = r;
77
78 return r;
79 });
80 // *INDENT-ON*
81
82 // Now apply the count condition to the count.
83 auto result = countOp(count);
84
85 // If this was a oneshot and the the condition has already
86 // passed, then don't let it pass again until the condition
87 // has gone back to false.
88 if (oneshot && result && lastResult)
89 {
90 return false;
Brad Bishop4041d722017-05-21 10:06:07 -040091 }
92
Brad Bishopd1eac882018-03-29 10:34:05 -040093 lastResult = result;
94 return result;
95 }
96
97 private:
98 /** @brief The comparison to perform on the count. */
99 std::function<bool(size_t)> countOp;
100 /** @brief The comparison to perform on each property. */
101 std::function<bool(T)> propertyOp;
102 /** @brief If the condition can be allowed to pass again
103 on subsequent checks that are also true. */
104 const bool oneshot;
105 /** @brief The result of the previous check. */
106 bool lastResult = false;
Brad Bishop4041d722017-05-21 10:06:07 -0400107};
108} // namespace monitoring
109} // namespace dbus
110} // namespace phosphor