@cryptotaxi247 / netdata-1 / commits / 080e0aee2

Faster queries (#12988)

* faster rrdeng_load_metric_next() * no need to check validity for number - already done at the query side * solve discrepancy between query create and free * inline unpack_storage_number

Costa Tsaousis committed May 24, 2022 at 08:20 UTC 080e0aee277ee636d98df536b00e98bae46cdf37
24 files changed +156 -174
database/engine/rrdengine.h
+2
@@ -49,10 +49,12 @@ struct rrdeng_query_handle {
49 time_t next_page_time;
50 time_t now;
51 unsigned position;
52 + unsigned entries;
53 storage_number *page;
54 usec_t page_end_time;
55 uint32_t page_length;
56 usec_t dt;
57 + time_t dt_sec;
58 };
59
60 typedef enum {
database/engine/rrdengineapi.c
+19 -21
@@ -554,7 +554,7 @@ void rrdeng_load_metric_init(RRDDIM *rd, struct rrddim_query_handle *rrdimm_hand
554 handle->next_page_time = INVALID_TIME;
555 }
556
557 -static int rrdeng_load_page_next(struct rrddim_query_handle *rrdimm_handle, unsigned *position_ptr) {
557 +static int rrdeng_load_page_next(struct rrddim_query_handle *rrdimm_handle) {
558 struct rrdeng_query_handle *handle = (struct rrdeng_query_handle *)rrdimm_handle->handle;
559
560 struct rrdengine_instance *ctx = handle->ctx;
@@ -576,13 +576,13 @@ static int rrdeng_load_page_next(struct rrddim_query_handle *rrdimm_handle, unsi
576 handle->next_page_time = (handle->page_end_time / USEC_PER_SEC) + 1;
577
578 if (unlikely(handle->next_page_time > rrdimm_handle->end_time))
579 - goto no_more_metrics;
579 + return 1;
580 }
581
582 usec_t next_page_time = handle->next_page_time * USEC_PER_SEC;
583 descr = pg_cache_lookup_next(ctx, handle->page_index, &handle->page_index->id, next_page_time, rrdimm_handle->end_time * USEC_PER_SEC);
584 if (NULL == descr)
585 - goto no_more_metrics;
585 + return 1;
586
587 #ifdef NETDATA_INTERNAL_CHECKS
588 rrd_stat_atomic_add(&ctx->stats.metric_API_consumers, 1);
@@ -591,7 +591,7 @@ static int rrdeng_load_page_next(struct rrddim_query_handle *rrdimm_handle, unsi
591 handle->descr = descr;
592 pg_cache_atomic_get_pg_info(descr, &page_end_time, &page_length);
593 if (unlikely(INVALID_TIME == descr->start_time || INVALID_TIME == page_end_time))
594 - goto no_more_metrics;
594 + return 1;
595
596 if (unlikely(descr->start_time != page_end_time && next_page_time > descr->start_time)) {
597 // we're in the middle of the page somewhere
@@ -605,17 +605,16 @@ static int rrdeng_load_page_next(struct rrddim_query_handle *rrdimm_handle, unsi
605 handle->page_end_time = page_end_time;
606 handle->page_length = page_length;
607 handle->page = descr->pg_cache_descr->page;
608 - usec_t entries = page_length / sizeof(storage_number);
608 + usec_t entries = handle->entries = page_length / sizeof(storage_number);
609 if (likely(entries > 1))
610 handle->dt = (page_end_time - descr->start_time) / (entries - 1);
611 else
612 handle->dt = 0;
613
614 - *position_ptr = position;
615 - return 0;
614 + handle->dt_sec = handle->dt / USEC_PER_SEC;
615 + handle->position = position;
616
617 -no_more_metrics:
618 - return 1;
617 + return 0;
618 }
619
620 /* Returns the metric and sets its timestamp into current_time */
@@ -626,22 +625,25 @@ storage_number rrdeng_load_metric_next(struct rrddim_query_handle *rrdimm_handle
625 return SN_EMPTY_SLOT;
626
627 struct rrdeng_page_descr *descr = handle->descr;
629 -
630 - storage_number *page = handle->page;
628 unsigned position = handle->position + 1;
629 + time_t now = handle->now + handle->dt_sec;
630
633 - if (unlikely(!descr || position >= (handle->page_length / sizeof(storage_number)))) {
631 + if (unlikely(!descr || position >= handle->entries)) {
632 // We need to get a new page
635 - if(rrdeng_load_page_next(rrdimm_handle, &position))
636 - goto no_more_metrics;
633 + if(rrdeng_load_page_next(rrdimm_handle)) {
634 + // next calls will not load any more metrics
635 + handle->next_page_time = INVALID_TIME;
636 + return SN_EMPTY_SLOT;
637 + }
638
639 descr = handle->descr;
639 - page = handle->page;
640 + position = handle->position;
641 + now = (descr->start_time + position * handle->dt) / USEC_PER_SEC;
642 }
643
642 - storage_number ret = page[position];
644 + storage_number ret = handle->page[position];
645 handle->position = position;
644 - time_t now = handle->now = (descr->start_time + position * handle->dt) / USEC_PER_SEC;
646 + handle->now = now;
647
648 if (unlikely(now >= rrdimm_handle->end_time)) {
649 // next calls will not load any more metrics
@@ -650,10 +652,6 @@ storage_number rrdeng_load_metric_next(struct rrddim_query_handle *rrdimm_handle
652
653 *current_time = now;
654 return ret;
653 -
654 -no_more_metrics:
655 - handle->next_page_time = INVALID_TIME;
656 - return SN_EMPTY_SLOT;
655 }
656
657 int rrdeng_load_metric_is_finished(struct rrddim_query_handle *rrdimm_handle)
libnetdata/storage_number/storage_number.c
+5 -39
@@ -92,56 +92,22 @@ RET_SN:
92 }
93
94 // Lookup table to make storage number unpacking efficient.
95 -static calculated_number lut10x[4 * 8];
95 +calculated_number unpack_storage_number_lut10x[4 * 8];
96
97 __attribute__((constructor)) void initialize_lut(void) {
98 // The lookup table is partitioned in 4 subtables based on the
99 // values of the factor and exp bits.
100 for (int i = 0; i < 8; i++) {
101 // factor = 0
102 - lut10x[0 * 8 + i] = 1 / pow(10, i); // exp = 0
103 - lut10x[1 * 8 + i] = pow(10, i); // exp = 1
102 + unpack_storage_number_lut10x[0 * 8 + i] = 1 / pow(10, i); // exp = 0
103 + unpack_storage_number_lut10x[1 * 8 + i] = pow(10, i); // exp = 1
104
105 // factor = 1
106 - lut10x[2 * 8 + i] = 1 / pow(100, i); // exp = 0
107 - lut10x[3 * 8 + i] = pow(100, i); // exp = 1
106 + unpack_storage_number_lut10x[2 * 8 + i] = 1 / pow(100, i); // exp = 0
107 + unpack_storage_number_lut10x[3 * 8 + i] = pow(100, i); // exp = 1
108 }
109 }
110
111 -calculated_number unpack_storage_number(storage_number value) {
112 - if(!value) return 0;
113 -
114 - int sign = 1, exp = 0;
115 - int factor = 0;
116 -
117 - // bit 32 = 0:positive, 1:negative
118 - if(unlikely(value & (1 << 31)))
119 - sign = -1;
120 -
121 - // bit 31 = 0:divide, 1:multiply
122 - if(unlikely(value & (1 << 30)))
123 - exp = 1;
124 -
125 - // bit 27 SN_EXISTS_100
126 - if(unlikely(value & (1 << 26)))
127 - factor = 1;
128 -
129 - // bit 26 SN_EXISTS_RESET
130 - // bit 25 SN_ANOMALY_BIT
131 -
132 - // bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total)
133 - int mul = (value & ((1<<29)|(1<<28)|(1<<27))) >> 27;
134 -
135 - // bit 24 to bit 1 = the value, so remove all other bits
136 - value ^= value & ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24));
137 -
138 - calculated_number n = value;
139 -
140 - // fprintf(stderr, "UNPACK: %08X, sign = %d, exp = %d, mul = %d, factor = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, factor, n);
141 -
142 - return sign * lut10x[(factor * 16) + (exp * 8) + mul] * n;
143 -}
144 -
111 /*
112 int print_calculated_number(char *str, calculated_number value)
113 {
libnetdata/storage_number/storage_number.h
+38 -1
@@ -80,7 +80,7 @@ typedef uint32_t storage_number;
80 #define did_storage_number_reset(value) ((((storage_number) (value)) & SN_EXISTS_RESET) != 0)
81
82 storage_number pack_storage_number(calculated_number value, uint32_t flags);
83 -calculated_number unpack_storage_number(storage_number value);
83 +static inline calculated_number unpack_storage_number(storage_number value) __attribute__((const));
84
85 int print_calculated_number(char *str, calculated_number value);
86
@@ -98,4 +98,41 @@ int print_calculated_number(char *str, calculated_number value);
98 // period of at least every other 10 samples.
99 #define MAX_INCREMENTAL_PERCENT_RATE 10
100
101 +
102 +static inline calculated_number unpack_storage_number(storage_number value) {
103 + extern calculated_number unpack_storage_number_lut10x[4 * 8];
104 +
105 + if(!value) return 0;
106 +
107 + int sign = 1, exp = 0;
108 + int factor = 0;
109 +
110 + // bit 32 = 0:positive, 1:negative
111 + if(unlikely(value & (1 << 31)))
112 + sign = -1;
113 +
114 + // bit 31 = 0:divide, 1:multiply
115 + if(unlikely(value & (1 << 30)))
116 + exp = 1;
117 +
118 + // bit 27 SN_EXISTS_100
119 + if(unlikely(value & (1 << 26)))
120 + factor = 1;
121 +
122 + // bit 26 SN_EXISTS_RESET
123 + // bit 25 SN_ANOMALY_BIT
124 +
125 + // bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total)
126 + int mul = (value & ((1<<29)|(1<<28)|(1<<27))) >> 27;
127 +
128 + // bit 24 to bit 1 = the value, so remove all other bits
129 + value ^= value & ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24));
130 +
131 + calculated_number n = value;
132 +
133 + // fprintf(stderr, "UNPACK: %08X, sign = %d, exp = %d, mul = %d, factor = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, factor, n);
134 +
135 + return sign * unpack_storage_number_lut10x[(factor * 16) + (exp * 8) + mul] * n;
136 +}
137 +
138 #endif /* NETDATA_STORAGE_NUMBER_H */
web/api/queries/average/average.c
+5 -8
@@ -10,9 +10,8 @@ struct grouping_average {
10 size_t count;
11 };
12
13 -void *grouping_create_average(RRDR *r) {
14 - (void)r;
15 - return callocz(1, sizeof(struct grouping_average));
13 +void grouping_create_average(RRDR *r) {
14 + r->internal.grouping_data = callocz(1, sizeof(struct grouping_average));
15 }
16
17 // resets when switches dimensions
@@ -29,11 +28,9 @@ void grouping_free_average(RRDR *r) {
28 }
29
30 void grouping_add_average(RRDR *r, calculated_number value) {
32 - if(likely(!isnan(value))) {
33 - struct grouping_average *g = (struct grouping_average *)r->internal.grouping_data;
34 - g->sum += value;
35 - g->count++;
36 - }
31 + struct grouping_average *g = (struct grouping_average *)r->internal.grouping_data;
32 + g->sum += value;
33 + g->count++;
34 }
35
36 calculated_number grouping_flush_average(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
web/api/queries/average/average.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_average(RRDR *r);
9 +extern void grouping_create_average(RRDR *r);
10 extern void grouping_reset_average(RRDR *r);
11 extern void grouping_free_average(RRDR *r);
12 extern void grouping_add_average(RRDR *r, calculated_number value);
web/api/queries/des/des.c
+18 -20
@@ -69,14 +69,14 @@ static inline void set_beta(RRDR *r, struct grouping_des *g) {
69 //info("beta for chart '%s' is " CALCULATED_NUMBER_FORMAT, r->st->name, g->beta);
70 }
71
72 -void *grouping_create_des(RRDR *r) {
72 +void grouping_create_des(RRDR *r) {
73 struct grouping_des *g = (struct grouping_des *)mallocz(sizeof(struct grouping_des));
74 set_alpha(r, g);
75 set_beta(r, g);
76 g->level = 0.0;
77 g->trend = 0.0;
78 g->count = 0;
79 - return g;
79 + r->internal.grouping_data = g;
80 }
81
82 // resets when switches dimensions
@@ -99,28 +99,26 @@ void grouping_free_des(RRDR *r) {
99 void grouping_add_des(RRDR *r, calculated_number value) {
100 struct grouping_des *g = (struct grouping_des *)r->internal.grouping_data;
101
102 - if(calculated_number_isnumber(value)) {
103 - if(likely(g->count > 0)) {
104 - // we have at least a number so far
102 + if(likely(g->count > 0)) {
103 + // we have at least a number so far
104
106 - if(unlikely(g->count == 1)) {
107 - // the second value we got
108 - g->trend = value - g->trend;
109 - g->level = value;
110 - }
111 -
112 - // for the values, except the first
113 - calculated_number last_level = g->level;
114 - g->level = (g->alpha * value) + (g->alpha_other * (g->level + g->trend));
115 - g->trend = (g->beta * (g->level - last_level)) + (g->beta_other * g->trend);
116 - }
117 - else {
118 - // the first value we got
119 - g->level = g->trend = value;
105 + if(unlikely(g->count == 1)) {
106 + // the second value we got
107 + g->trend = value - g->trend;
108 + g->level = value;
109 }
110
122 - g->count++;
111 + // for the values, except the first
112 + calculated_number last_level = g->level;
113 + g->level = (g->alpha * value) + (g->alpha_other * (g->level + g->trend));
114 + g->trend = (g->beta * (g->level - last_level)) + (g->beta_other * g->trend);
115 }
116 + else {
117 + // the first value we got
118 + g->level = g->trend = value;
119 + }
120 +
121 + g->count++;
122
123 //fprintf(stderr, "value: " CALCULATED_NUMBER_FORMAT ", level: " CALCULATED_NUMBER_FORMAT ", trend: " CALCULATED_NUMBER_FORMAT "\n", value, g->level, g->trend);
124 }
web/api/queries/des/des.h
+1 -1
@@ -8,7 +8,7 @@
8
9 extern void grouping_init_des(void);
10
11 -extern void *grouping_create_des(RRDR *r);
11 +extern void grouping_create_des(RRDR *r);
12 extern void grouping_reset_des(RRDR *r);
13 extern void grouping_free_des(RRDR *r);
14 extern void grouping_add_des(RRDR *r, calculated_number value);
web/api/queries/incremental_sum/incremental_sum.c
+10 -13
@@ -11,9 +11,8 @@ struct grouping_incremental_sum {
11 size_t count;
12 };
13
14 -void *grouping_create_incremental_sum(RRDR *r) {
15 - (void)r;
16 - return callocz(1, sizeof(struct grouping_incremental_sum));
14 +void grouping_create_incremental_sum(RRDR *r) {
15 + r->internal.grouping_data = callocz(1, sizeof(struct grouping_incremental_sum));
16 }
17
18 // resets when switches dimensions
@@ -31,17 +30,15 @@ void grouping_free_incremental_sum(RRDR *r) {
30 }
31
32 void grouping_add_incremental_sum(RRDR *r, calculated_number value) {
34 - if(!isnan(value)) {
35 - struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->internal.grouping_data;
33 + struct grouping_incremental_sum *g = (struct grouping_incremental_sum *)r->internal.grouping_data;
34
37 - if(unlikely(!g->count)) {
38 - g->first = value;
39 - g->count++;
40 - }
41 - else {
42 - g->last = value;
43 - g->count++;
44 - }
35 + if(unlikely(!g->count)) {
36 + g->first = value;
37 + g->count++;
38 + }
39 + else {
40 + g->last = value;
41 + g->count++;
42 }
43 }
44
web/api/queries/incremental_sum/incremental_sum.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_incremental_sum(RRDR *r);
9 +extern void grouping_create_incremental_sum(RRDR *r);
10 extern void grouping_reset_incremental_sum(RRDR *r);
11 extern void grouping_free_incremental_sum(RRDR *r);
12 extern void grouping_add_incremental_sum(RRDR *r, calculated_number value);
web/api/queries/max/max.c
+6 -9
@@ -10,9 +10,8 @@ struct grouping_max {
10 size_t count;
11 };
12
13 -void *grouping_create_max(RRDR *r) {
14 - (void)r;
15 - return callocz(1, sizeof(struct grouping_max));
13 +void grouping_create_max(RRDR *r) {
14 + r->internal.grouping_data = callocz(1, sizeof(struct grouping_max));
15 }
16
17 // resets when switches dimensions
@@ -29,13 +28,11 @@ void grouping_free_max(RRDR *r) {
28 }
29
30 void grouping_add_max(RRDR *r, calculated_number value) {
32 - if(!isnan(value)) {
33 - struct grouping_max *g = (struct grouping_max *)r->internal.grouping_data;
31 + struct grouping_max *g = (struct grouping_max *)r->internal.grouping_data;
32
35 - if(!g->count || calculated_number_fabs(value) > calculated_number_fabs(g->max)) {
36 - g->max = value;
37 - g->count++;
38 - }
33 + if(!g->count || calculated_number_fabs(value) > calculated_number_fabs(g->max)) {
34 + g->max = value;
35 + g->count++;
36 }
37 }
38
web/api/queries/max/max.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_max(RRDR *r);
9 +extern void grouping_create_max(RRDR *r);
10 extern void grouping_reset_max(RRDR *r);
11 extern void grouping_free_max(RRDR *r);
12 extern void grouping_add_max(RRDR *r, calculated_number value);
web/api/queries/median/median.c
+4 -6
@@ -13,14 +13,14 @@ struct grouping_median {
13 LONG_DOUBLE series[];
14 };
15
16 -void *grouping_create_median(RRDR *r) {
16 +void grouping_create_median(RRDR *r) {
17 long entries = r->group;
18 if(entries < 0) entries = 0;
19
20 struct grouping_median *g = (struct grouping_median *)callocz(1, sizeof(struct grouping_median) + entries * sizeof(LONG_DOUBLE));
21 g->series_size = (size_t)entries;
22
23 - return g;
23 + r->internal.grouping_data = g;
24 }
25
26 // resets when switches dimensions
@@ -41,10 +41,8 @@ void grouping_add_median(RRDR *r, calculated_number value) {
41 if(unlikely(g->next_pos >= g->series_size)) {
42 error("INTERNAL ERROR: median buffer overflow on chart '%s' - next_pos = %zu, series_size = %zu, r->group = %ld.", r->st->name, g->next_pos, g->series_size, r->group);
43 }
44 - else {
45 - if(calculated_number_isnumber(value))
46 - g->series[g->next_pos++] = (LONG_DOUBLE)value;
47 - }
44 + else
45 + g->series[g->next_pos++] = (LONG_DOUBLE)value;
46 }
47
48 calculated_number grouping_flush_median(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
web/api/queries/median/median.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_median(RRDR *r);
9 +extern void grouping_create_median(RRDR *r);
10 extern void grouping_reset_median(RRDR *r);
11 extern void grouping_free_median(RRDR *r);
12 extern void grouping_add_median(RRDR *r, calculated_number value);
web/api/queries/min/min.c
+6 -9
@@ -10,9 +10,8 @@ struct grouping_min {
10 size_t count;
11 };
12
13 -void *grouping_create_min(RRDR *r) {
14 - (void)r;
15 - return callocz(1, sizeof(struct grouping_min));
13 +void grouping_create_min(RRDR *r) {
14 + r->internal.grouping_data = callocz(1, sizeof(struct grouping_min));
15 }
16
17 // resets when switches dimensions
@@ -29,13 +28,11 @@ void grouping_free_min(RRDR *r) {
28 }
29
30 void grouping_add_min(RRDR *r, calculated_number value) {
32 - if(!isnan(value)) {
33 - struct grouping_min *g = (struct grouping_min *)r->internal.grouping_data;
31 + struct grouping_min *g = (struct grouping_min *)r->internal.grouping_data;
32
35 - if(!g->count || calculated_number_fabs(value) < calculated_number_fabs(g->min)) {
36 - g->min = value;
37 - g->count++;
38 - }
33 + if(!g->count || calculated_number_fabs(value) < calculated_number_fabs(g->min)) {
34 + g->min = value;
35 + g->count++;
36 }
37 }
38
web/api/queries/min/min.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_min(RRDR *r);
9 +extern void grouping_create_min(RRDR *r);
10 extern void grouping_reset_min(RRDR *r);
11 extern void grouping_free_min(RRDR *r);
12 extern void grouping_add_min(RRDR *r, calculated_number value);
web/api/queries/query.c
+8 -5
@@ -28,7 +28,7 @@ static struct {
28
29 // Allocate all required structures for a query.
30 // This is called once for each netdata query.
31 - void *(*create)(struct rrdresult *r);
31 + void (*create)(struct rrdresult *r);
32
33 // Cleanup collected values, but don't destroy the structures.
34 // This is called when the query engine switches dimensions,
@@ -465,7 +465,9 @@ static inline void do_dimension_variablestep(
465 }
466 }
467 // add this value to grouping
468 - r->internal.grouping_add(r, value);
468 + if(likely(!isnan(value)))
469 + r->internal.grouping_add(r, value);
470 +
471 values_in_group++;
472 db_points_read++;
473 }
@@ -649,10 +651,11 @@ static inline void do_dimension_fixedstep(
651
652 if(unlikely(did_storage_number_reset(n)))
653 group_value_flags |= RRDR_VALUE_RESET;
654 +
655 + grouping_add(r, value);
656 }
657
658 // add this value for grouping
655 - grouping_add(r, value);
659 values_in_group++;
660 db_points_read++;
661
@@ -1112,7 +1115,7 @@ static RRDR *rrd2rrdr_fixedstep(
1115 }
1116
1117 // allocate any memory required by the grouping method
1115 - r->internal.grouping_data = r->internal.grouping_create(r);
1118 + r->internal.grouping_create(r);
1119
1120
1121 // -------------------------------------------------------------------------
@@ -1504,7 +1507,7 @@ static RRDR *rrd2rrdr_variablestep(
1507 }
1508
1509 // allocate any memory required by the grouping method
1507 - r->internal.grouping_data = r->internal.grouping_create(r);
1510 + r->internal.grouping_create(r);
1511
1512
1513 // -------------------------------------------------------------------------
web/api/queries/rrdr.h
+1 -1
@@ -83,7 +83,7 @@ typedef struct rrdresult {
83 long resampling_group;
84 calculated_number resampling_divisor;
85
86 - void *(*grouping_create)(struct rrdresult *r);
86 + void (*grouping_create)(struct rrdresult *r);
87 void (*grouping_reset)(struct rrdresult *r);
88 void (*grouping_free)(struct rrdresult *r);
89 void (*grouping_add)(struct rrdresult *r, calculated_number value);
web/api/queries/ses/ses.c
+6 -8
@@ -48,11 +48,11 @@ static inline void set_alpha(RRDR *r, struct grouping_ses *g) {
48 g->alpha_other = 1.0 - g->alpha;
49 }
50
51 -void *grouping_create_ses(RRDR *r) {
51 +void grouping_create_ses(RRDR *r) {
52 struct grouping_ses *g = (struct grouping_ses *)callocz(1, sizeof(struct grouping_ses));
53 set_alpha(r, g);
54 g->level = 0.0;
55 - return g;
55 + r->internal.grouping_data = g;
56 }
57
58 // resets when switches dimensions
@@ -71,13 +71,11 @@ void grouping_free_ses(RRDR *r) {
71 void grouping_add_ses(RRDR *r, calculated_number value) {
72 struct grouping_ses *g = (struct grouping_ses *)r->internal.grouping_data;
73
74 - if(calculated_number_isnumber(value)) {
75 - if(unlikely(!g->count))
76 - g->level = value;
74 + if(unlikely(!g->count))
75 + g->level = value;
76
78 - g->level = g->alpha * value + g->alpha_other * g->level;
79 - g->count++;
80 - }
77 + g->level = g->alpha * value + g->alpha_other * g->level;
78 + g->count++;
79 }
80
81 calculated_number grouping_flush_ses(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
web/api/queries/ses/ses.h
+1 -1
@@ -8,7 +8,7 @@
8
9 extern void grouping_init_ses(void);
10
11 -extern void *grouping_create_ses(RRDR *r);
11 +extern void grouping_create_ses(RRDR *r);
12 extern void grouping_reset_ses(RRDR *r);
13 extern void grouping_free_ses(RRDR *r);
14 extern void grouping_add_ses(RRDR *r, calculated_number value);
web/api/queries/stddev/stddev.c
+14 -17
@@ -14,9 +14,8 @@ struct grouping_stddev {
14 calculated_number m_oldM, m_newM, m_oldS, m_newS;
15 };
16
17 -void *grouping_create_stddev(RRDR *r) {
18 - UNUSED (r);
19 - return callocz(1, sizeof(struct grouping_stddev));
17 +void grouping_create_stddev(RRDR *r) {
18 + r->internal.grouping_data = callocz(1, sizeof(struct grouping_stddev));
19 }
20
21 // resets when switches dimensions
@@ -34,22 +33,20 @@ void grouping_free_stddev(RRDR *r) {
33 void grouping_add_stddev(RRDR *r, calculated_number value) {
34 struct grouping_stddev *g = (struct grouping_stddev *)r->internal.grouping_data;
35
37 - if(calculated_number_isnumber(value)) {
38 - g->count++;
36 + g->count++;
37
40 - // See Knuth TAOCP vol 2, 3rd edition, page 232
41 - if (g->count == 1) {
42 - g->m_oldM = g->m_newM = value;
43 - g->m_oldS = 0.0;
44 - }
45 - else {
46 - g->m_newM = g->m_oldM + (value - g->m_oldM) / g->count;
47 - g->m_newS = g->m_oldS + (value - g->m_oldM) * (value - g->m_newM);
38 + // See Knuth TAOCP vol 2, 3rd edition, page 232
39 + if (g->count == 1) {
40 + g->m_oldM = g->m_newM = value;
41 + g->m_oldS = 0.0;
42 + }
43 + else {
44 + g->m_newM = g->m_oldM + (value - g->m_oldM) / g->count;
45 + g->m_newS = g->m_oldS + (value - g->m_oldM) * (value - g->m_newM);
46
49 - // set up for next iteration
50 - g->m_oldM = g->m_newM;
51 - g->m_oldS = g->m_newS;
52 - }
47 + // set up for next iteration
48 + g->m_oldM = g->m_newM;
49 + g->m_oldS = g->m_newS;
50 }
51 }
52
web/api/queries/stddev/stddev.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_stddev(RRDR *r);
9 +extern void grouping_create_stddev(RRDR *r);
10 extern void grouping_reset_stddev(RRDR *r);
11 extern void grouping_free_stddev(RRDR *r);
12 extern void grouping_add_stddev(RRDR *r, calculated_number value);
web/api/queries/sum/sum.c
+5 -8
@@ -10,9 +10,8 @@ struct grouping_sum {
10 size_t count;
11 };
12
13 -void *grouping_create_sum(RRDR *r) {
14 - (void)r;
15 - return callocz(1, sizeof(struct grouping_sum));
13 +void grouping_create_sum(RRDR *r) {
14 + r->internal.grouping_data = callocz(1, sizeof(struct grouping_sum));
15 }
16
17 // resets when switches dimensions
@@ -29,11 +28,9 @@ void grouping_free_sum(RRDR *r) {
28 }
29
30 void grouping_add_sum(RRDR *r, calculated_number value) {
32 - if(!isnan(value)) {
33 - struct grouping_sum *g = (struct grouping_sum *)r->internal.grouping_data;
34 - g->sum += value;
35 - g->count++;
36 - }
31 + struct grouping_sum *g = (struct grouping_sum *)r->internal.grouping_data;
32 + g->sum += value;
33 + g->count++;
34 }
35
36 calculated_number grouping_flush_sum(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) {
web/api/queries/sum/sum.h
+1 -1
@@ -6,7 +6,7 @@
6 #include "../query.h"
7 #include "../rrdr.h"
8
9 -extern void *grouping_create_sum(RRDR *r);
9 +extern void grouping_create_sum(RRDR *r);
10 extern void grouping_reset_sum(RRDR *r);
11 extern void grouping_free_sum(RRDR *r);
12 extern void grouping_add_sum(RRDR *r, calculated_number value);