fix the calculation of incremental-sum (#15468)
* fix the calculation of incremental-sum * for query planning use at least 400 points
Costa Tsaousis committed
Jul 20, 2023 at 23:27 UTC
d36fb28d73cac93412b15a0e23df08fd18b28879
2 files changed
+20
-13
web/api/queries/incremental_sum/incremental_sum.h
+15
-13
@@ -12,19 +12,20 @@ struct tg_incremental_sum {
12
size_t count;
13
};
14
15
-static inline void tg_incremental_sum_create(RRDR *r, const char *options __maybe_unused) {
16
- r->time_grouping.data = onewayalloc_callocz(r->internal.owa, 1, sizeof(struct tg_incremental_sum));
17
-}
18
-
15
// resets when switches dimensions
16
// so, clear everything to restart
17
static inline void tg_incremental_sum_reset(RRDR *r) {
18
struct tg_incremental_sum *g = (struct tg_incremental_sum *)r->time_grouping.data;
23
- g->first = 0;
24
- g->last = 0;
19
+ g->first = NAN;
20
+ g->last = NAN;
21
g->count = 0;
22
}
23
24
+static inline void tg_incremental_sum_create(RRDR *r, const char *options __maybe_unused) {
25
+ r->time_grouping.data = onewayalloc_mallocz(r->internal.owa, sizeof(struct tg_incremental_sum));
26
+ tg_incremental_sum_reset(r);
27
+}
28
+
29
static inline void tg_incremental_sum_free(RRDR *r) {
30
onewayalloc_freez(r->internal.owa, r->time_grouping.data);
31
r->time_grouping.data = NULL;
@@ -34,7 +35,11 @@ static inline void tg_incremental_sum_add(RRDR *r, NETDATA_DOUBLE value) {
35
struct tg_incremental_sum *g = (struct tg_incremental_sum *)r->time_grouping.data;
36
37
if(unlikely(!g->count)) {
37
- g->first = value;
38
+ if(isnan(g->first))
39
+ g->first = value;
40
+ else
41
+ g->last = value;
42
+
43
g->count++;
44
}
45
else {
@@ -48,19 +53,16 @@ static inline NETDATA_DOUBLE tg_incremental_sum_flush(RRDR *r, RRDR_VALUE_FLAGS
53
54
NETDATA_DOUBLE value;
55
51
- if(unlikely(!g->count)) {
56
+ if(unlikely(!g->count || isnan(g->first) || isnan(g->last))) {
57
value = 0.0;
58
*rrdr_value_options_ptr |= RRDR_VALUE_EMPTY;
59
}
55
- else if(unlikely(g->count == 1)) {
56
- value = 0.0;
57
- }
60
else {
61
value = g->last - g->first;
62
}
63
62
- g->first = 0.0;
63
- g->last = 0.0;
64
+ g->first = g->last;
65
+ g->last = NAN;
66
g->count = 0;
67
68
return value;
web/api/queries/query.c
+5
@@ -17,6 +17,7 @@
17
#include "percentile/percentile.h"
18
#include "trimmed_mean/trimmed_mean.h"
19
20
+#define QUERY_PLAN_MIN_POINTS 400
21
#define POINTS_TO_EXPAND_QUERY 5
22
23
// ----------------------------------------------------------------------------
@@ -996,6 +997,10 @@ static size_t query_metric_best_tier_for_timeframe(QUERY_METRIC *qm, time_t afte
997
if(unlikely(after_wanted == before_wanted || points_wanted <= 0))
998
return query_metric_first_working_tier(qm);
999
1000
+ if(points_wanted < QUERY_PLAN_MIN_POINTS)
1001
+ // when selecting tiers, aim for a resolution of at least QUERY_PLAN_MIN_POINTS points
1002
+ points_wanted = (before_wanted - after_wanted) > QUERY_PLAN_MIN_POINTS ? QUERY_PLAN_MIN_POINTS : before_wanted - after_wanted;
1003
+
1004
time_t min_first_time_s = 0;
1005
time_t max_last_time_s = 0;
1006