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);