master
h 127 lines 6.21 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_STORAGE_POINT_H
4 #define NETDATA_STORAGE_POINT_H
5
6 #include "storage_number/storage_number.h"
7
8 typedef struct storage_point {
9 NETDATA_DOUBLE min; // when count > 1, this is the minimum among them
10 NETDATA_DOUBLE max; // when count > 1, this is the maximum among them
11 NETDATA_DOUBLE sum; // the point sum - divided by count gives the average
12
13 // end_time - start_time = point duration
14 time_t start_time_s; // the time the point starts
15 time_t end_time_s; // the time the point ends
16
17 uint32_t count; // the number of original points aggregated
18 uint32_t anomaly_count; // the number of original points found anomalous
19
20 SN_FLAGS flags; // flags stored with the point
21 } STORAGE_POINT;
22
23 #define storage_point_unset(x) do { \
24 (x).min = (x).max = (x).sum = NAN; \
25 (x).count = 0; \
26 (x).anomaly_count = 0; \
27 (x).flags = SN_FLAG_NONE; \
28 (x).start_time_s = 0; \
29 (x).end_time_s = 0; \
30 } while(0)
31
32 #define storage_point_empty(x, start_s, end_s) do { \
33 (x).min = (x).max = (x).sum = NAN; \
34 (x).count = 1; \
35 (x).anomaly_count = 0; \
36 (x).flags = SN_FLAG_NONE; \
37 (x).start_time_s = start_s; \
38 (x).end_time_s = end_s; \
39 } while(0)
40
41 #define STORAGE_POINT_UNSET (STORAGE_POINT){ .min = NAN, .max = NAN, .sum = NAN, .count = 0, .anomaly_count = 0, .flags = SN_FLAG_NONE, .start_time_s = 0, .end_time_s = 0 }
42
43 #define storage_point_is_unset(x) (!(x).count)
44 #define storage_point_is_gap(x) (!netdata_double_isnumber((x).sum))
45 #define storage_point_is_zero(x) (!(x).count || (netdata_double_is_zero((x).min) && netdata_double_is_zero((x).max) && netdata_double_is_zero((x).sum) && (x).anomaly_count == 0))
46
47 #define storage_point_merge_to(dst, src) do { \
48 if(storage_point_is_unset(dst)) \
49 (dst) = (src); \
50 \
51 else if(!storage_point_is_unset(src) && \
52 !storage_point_is_gap(src)) { \
53 \
54 if((src).start_time_s < (dst).start_time_s) \
55 (dst).start_time_s = (src).start_time_s;\
56 \
57 if((src).end_time_s > (dst).end_time_s) \
58 (dst).end_time_s = (src).end_time_s; \
59 \
60 if((src).min < (dst).min) \
61 (dst).min = (src).min; \
62 \
63 if((src).max > (dst).max) \
64 (dst).max = (src).max; \
65 \
66 (dst).sum += (src).sum; \
67 \
68 (dst).count += (src).count; \
69 (dst).anomaly_count += (src).anomaly_count; \
70 \
71 (dst).flags |= (src).flags & SN_FLAG_RESET; \
72 } \
73 } while(0)
74
75 #define storage_point_add_to(dst, src) do { \
76 if(storage_point_is_unset(dst)) \
77 (dst) = (src); \
78 \
79 else if(!storage_point_is_unset(src) && \
80 !storage_point_is_gap(src)) { \
81 \
82 if((src).start_time_s < (dst).start_time_s) \
83 (dst).start_time_s = (src).start_time_s;\
84 \
85 if((src).end_time_s > (dst).end_time_s) \
86 (dst).end_time_s = (src).end_time_s; \
87 \
88 (dst).min += (src).min; \
89 (dst).max += (src).max; \
90 (dst).sum += (src).sum; \
91 \
92 (dst).count += (src).count; \
93 (dst).anomaly_count += (src).anomaly_count; \
94 \
95 (dst).flags |= (src).flags & SN_FLAG_RESET; \
96 } \
97 } while(0)
98
99 #define storage_point_make_positive(sp) do { \
100 if(!storage_point_is_unset(sp) && \
101 !storage_point_is_gap(sp)) { \
102 \
103 if(unlikely(signbit((sp).sum))) \
104 (sp).sum = -(sp).sum; \
105 \
106 if(unlikely(signbit((sp).min))) \
107 (sp).min = -(sp).min; \
108 \
109 if(unlikely(signbit((sp).max))) \
110 (sp).max = -(sp).max; \
111 \
112 if(unlikely((sp).min > (sp).max)) { \
113 NETDATA_DOUBLE t = (sp).min; \
114 (sp).min = (sp).max; \
115 (sp).max = t; \
116 } \
117 } \
118 } while(0)
119
120 #define storage_point_anomaly_rate(sp) \
121 (NETDATA_DOUBLE)(storage_point_is_unset(sp) ? 0.0 : (NETDATA_DOUBLE)((sp).anomaly_count) * 100.0 / (NETDATA_DOUBLE)((sp).count))
122
123 #define storage_point_average_value(sp) \
124 ((sp).count ? (sp).sum / (NETDATA_DOUBLE)((sp).count) : 0.0)
125
126
127 #endif //NETDATA_STORAGE_POINT_H