master
h 170 lines 4.88 KB
Raw
1 #ifndef ML_LOOKUP_H
2 #define ML_LOOKUP_H
3
4 #include "ml_string_wrapper.h"
5 #include "ml_enums.h"
6 #include "ml_kmeans.h"
7 #include "ml_chart.h"
8
9 #include <array>
10
11 struct ml_dimension_t {
12 RRDDIM *rd;
13
14 enum ml_metric_type mt;
15 enum ml_training_status ts;
16 enum ml_machine_learning_status mls;
17 SPINLOCK slock;
18 uint32_t suppression_window_counter;
19 uint32_t suppression_anomaly_counter;
20 uint32_t reset_generation;
21 bool training_in_progress;
22 bool has_received_downstream_model;
23 bool create_new_model_queued;
24 size_t cns_head;
25
26 std::vector<calculated_number_t> cns;
27
28 std::vector<ml_kmeans_inlined_t> km_contexts;
29 ml_kmeans_t kmeans;
30 DSample feature;
31 };
32
33 bool
34 ml_dimension_predict(ml_dimension_t *dim, calculated_number_t value, bool exists);
35
36 bool ml_dimension_deserialize_kmeans(const char *json_str);
37
38 // Set dim's post-training state (mt/ts/suppression counters). Caller must hold
39 // dim->slock. Used by both the successful-training path and the undersampled
40 // early-return so the post-cycle state machine stays in sync.
41 void ml_dimension_finalize_constant_state(ml_dimension_t *dim);
42
43 class DimensionLookupInfo {
44 public:
45 DimensionLookupInfo()
46 {
47 memset(MachineGuid.data(), 0, MachineGuid.size());
48 }
49
50 DimensionLookupInfo(const char *MachineGuid, STRING *ChartId, STRING *DimensionId)
51 : ChartId(ChartId), DimensionId(DimensionId)
52 {
53 memcpy(this->MachineGuid.data(), MachineGuid, this->MachineGuid.size());
54 }
55
56 DimensionLookupInfo(const char *MachineGuid, const char *ChartId, const char *DimensionId)
57 : ChartId(ChartId), DimensionId(DimensionId)
58 {
59 memcpy(this->MachineGuid.data(), MachineGuid, this->MachineGuid.size());
60 }
61
62 const char *machineGuid() const
63 {
64 return MachineGuid.data();
65 }
66
67 const char *chartId() const
68 {
69 return ChartId;
70 }
71
72 const char *dimensionId() const
73 {
74 return DimensionId;
75 }
76
77 private:
78 std::array<char, GUID_LEN + 1> MachineGuid;
79 StringWrapper ChartId;
80 StringWrapper DimensionId;
81 };
82
83 class AcquiredDimension {
84 public:
85 AcquiredDimension(const DimensionLookupInfo &DLI) : AcqRH(nullptr), AcqRS(nullptr), AcqRD(nullptr), Dim(nullptr)
86 {
87 rrd_rdlock();
88
89 AcqRH = rrdhost_find_and_acquire(DLI.machineGuid());
90 if (AcqRH) {
91 RRDHOST *RH = rrdhost_acquired_to_rrdhost(AcqRH);
92 if (RH && !rrdhost_flag_check(RH, RRDHOST_FLAG_ORPHAN | RRDHOST_FLAG_ARCHIVED)) {
93 AcqRS = rrdset_find_and_acquire(RH, DLI.chartId(), false);
94 if (AcqRS) {
95 RRDSET *RS = rrdset_acquired_to_rrdset(AcqRS);
96 if (RS && !rrdset_flag_check(RS, RRDSET_FLAG_OBSOLETE)) {
97 AcqRD = rrddim_find_and_acquire(RS, DLI.dimensionId(), false);
98 if (AcqRD) {
99 RRDDIM *RD = rrddim_acquired_to_rrddim(AcqRD);
100 if (RD) {
101 Dim = reinterpret_cast<ml_dimension_t *>(RD->ml_dimension);
102 acquire_failure_reason = "ok";
103 }
104 else
105 acquire_failure_reason = "no dimension";
106 }
107 else
108 acquire_failure_reason = "can't find dimension";
109 }
110 else
111 acquire_failure_reason = "chart is obsolete";
112 }
113 else
114 acquire_failure_reason = "can't find chart";
115 }
116 else
117 acquire_failure_reason = "host is orphan or archived";
118 }
119 else
120 acquire_failure_reason = "can't find host";
121
122 rrd_rdunlock();
123 }
124
125 AcquiredDimension(const AcquiredDimension &) = delete;
126 AcquiredDimension operator=(const AcquiredDimension &) = delete;
127
128 AcquiredDimension(AcquiredDimension &&) = default;
129 AcquiredDimension &operator=(AcquiredDimension &&) = default;
130
131 bool acquired() const {
132 return AcqRD != nullptr;
133 }
134
135 const char *acquire_failure() const {
136 return acquire_failure_reason;
137 }
138
139 ml_host_t *host() const {
140 assert(acquired());
141 RRDHOST *RH = rrdhost_acquired_to_rrdhost(AcqRH);
142 return reinterpret_cast<ml_host_t *>(__atomic_load_n(&RH->ml_host, __ATOMIC_ACQUIRE));
143 }
144
145 ml_dimension_t *dimension() const {
146 assert(acquired());
147 return Dim;
148 }
149
150 ~AcquiredDimension()
151 {
152 if (AcqRD)
153 rrddim_acquired_release(AcqRD);
154
155 if (AcqRS)
156 rrdset_acquired_release(AcqRS);
157
158 if (AcqRH)
159 rrdhost_acquired_release(AcqRH);
160 }
161
162 private:
163 const char *acquire_failure_reason;
164 RRDHOST_ACQUIRED *AcqRH;
165 RRDSET_ACQUIRED *AcqRS;
166 RRDDIM_ACQUIRED *AcqRD;
167 ml_dimension_t *Dim;
168 };
169
170 #endif /* ML_LOOKUP_H */