master
h 101 lines 2.76 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef NETDATA_API_QUERY_EXTREMES_H
4 #define NETDATA_API_QUERY_EXTREMES_H
5
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 struct tg_extremes {
10 NETDATA_DOUBLE min; // for negative values
11 NETDATA_DOUBLE max; // for positive values
12 size_t pos_count; // count of positive values
13 size_t neg_count; // count of negative values
14 size_t zero_count; // count of zero values
15 };
16
17 static inline void tg_extremes_create(RRDR *r, const char *options __maybe_unused) {
18 r->time_grouping.data = onewayalloc_callocz(r->internal.owa, 1, sizeof(struct tg_extremes));
19 }
20
21 // resets when switches dimensions
22 // so, clear everything to restart
23 static inline void tg_extremes_reset(RRDR *r) {
24 struct tg_extremes *g = (struct tg_extremes *)r->time_grouping.data;
25 g->min = 0;
26 g->max = 0;
27 g->pos_count = 0;
28 g->neg_count = 0;
29 g->zero_count = 0;
30 }
31
32 static inline void tg_extremes_free(RRDR *r) {
33 onewayalloc_freez(r->internal.owa, r->time_grouping.data);
34 r->time_grouping.data = NULL;
35 }
36
37 static inline void tg_extremes_add(RRDR *r, NETDATA_DOUBLE value) {
38 struct tg_extremes *g = (struct tg_extremes *)r->time_grouping.data;
39
40 if (value > 0) {
41 // For positive values, track the maximum
42 if (!g->pos_count || value > g->max) {
43 g->max = value;
44 }
45 g->pos_count++;
46 }
47 else if (value < 0) {
48 // For negative values, track the minimum
49 if (!g->neg_count || value < g->min) {
50 g->min = value;
51 }
52 g->neg_count++;
53 }
54 else {
55 // It's a zero
56 g->zero_count++;
57 }
58 }
59
60 static inline NETDATA_DOUBLE tg_extremes_flush(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
61 struct tg_extremes *g = (struct tg_extremes *)r->time_grouping.data;
62
63 NETDATA_DOUBLE value;
64
65 if (unlikely(!g->pos_count && !g->neg_count && !g->zero_count)) {
66 // No values at all
67 value = 0.0;
68 *rrdr_value_options_ptr |= RRDR_VALUE_EMPTY;
69 }
70 else if (g->pos_count && g->neg_count) {
71 // If we have both positive and negative values,
72 // return the one with the greatest absolute value
73 if (fabsndd(g->max) > fabsndd(g->min))
74 value = g->max;
75 else
76 value = g->min;
77 }
78 else if (g->pos_count) {
79 // Only positive values, return the maximum
80 value = g->max;
81 }
82 else if (g->neg_count) {
83 // Only negative values, return the minimum
84 value = g->min;
85 }
86 else {
87 // Only zeros
88 value = 0.0;
89 }
90
91 // Reset the state for the next calculation
92 g->min = 0.0;
93 g->max = 0.0;
94 g->pos_count = 0;
95 g->neg_count = 0;
96 g->zero_count = 0;
97
98 return value;
99 }
100
101 #endif //NETDATA_API_QUERY_EXTREMES_H