master
c 837 lines 26.1 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "query-internal.h"
4
5 #include "average/average.h"
6 #include "countif/countif.h"
7 #include "incremental_sum/incremental_sum.h"
8 #include "max/max.h"
9 #include "median/median.h"
10 #include "min/min.h"
11 #include "sum/sum.h"
12 #include "stddev/stddev.h"
13 #include "ses/ses.h"
14 #include "des/des.h"
15 #include "percentile/percentile.h"
16 #include "trimmed_mean/trimmed_mean.h"
17 #include "extremes/extremes.h"
18
19 // ----------------------------------------------------------------------------
20
21 static struct {
22 const char *name;
23 uint32_t hash;
24 RRDR_TIME_GROUPING value;
25 RRDR_TIME_GROUPING add_flush;
26
27 // One time initialization for the module.
28 // This is called once, when netdata starts.
29 void (*init)(void);
30
31 // Allocate all required structures for a query.
32 // This is called once for each netdata query.
33 void (*create)(struct rrdresult *r, const char *options);
34
35 // Cleanup collected values, but don't destroy the structures.
36 // This is called when the query engine switches dimensions,
37 // as part of the same query (so same chart, switching metric).
38 void (*reset)(struct rrdresult *r);
39
40 // Free all resources allocated for the query.
41 void (*free)(struct rrdresult *r);
42
43 // Add a single value into the calculation.
44 // The module may decide to cache it, or use it in the fly.
45 void (*add)(struct rrdresult *r, NETDATA_DOUBLE value);
46
47 // Generate a single result for the values added so far.
48 // More values and points may be requested later.
49 // It is up to the module to reset its internal structures
50 // when flushing it (so for a few modules it may be better to
51 // continue after a flush as if nothing changed, for others a
52 // cleanup of the internal structures may be required).
53 NETDATA_DOUBLE (*flush)(struct rrdresult *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr);
54
55 TIER_QUERY_FETCH tier_query_fetch;
56 } api_v1_data_groups[] = {
57 {.name = "average",
58 .hash = 0,
59 .value = RRDR_GROUPING_AVERAGE,
60 .add_flush = RRDR_GROUPING_AVERAGE,
61 .init = NULL,
62 .create= tg_average_create,
63 .reset = tg_average_reset,
64 .free = tg_average_free,
65 .add = tg_average_add,
66 .flush = tg_average_flush,
67 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
68 },
69 {.name = "avg", // alias on 'average'
70 .hash = 0,
71 .value = RRDR_GROUPING_AVERAGE,
72 .add_flush = RRDR_GROUPING_AVERAGE,
73 .init = NULL,
74 .create= tg_average_create,
75 .reset = tg_average_reset,
76 .free = tg_average_free,
77 .add = tg_average_add,
78 .flush = tg_average_flush,
79 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
80 },
81 {.name = "mean", // alias on 'average'
82 .hash = 0,
83 .value = RRDR_GROUPING_AVERAGE,
84 .add_flush = RRDR_GROUPING_AVERAGE,
85 .init = NULL,
86 .create= tg_average_create,
87 .reset = tg_average_reset,
88 .free = tg_average_free,
89 .add = tg_average_add,
90 .flush = tg_average_flush,
91 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
92 },
93 {.name = "trimmed-mean1",
94 .hash = 0,
95 .value = RRDR_GROUPING_TRIMMED_MEAN1,
96 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
97 .init = NULL,
98 .create= tg_trimmed_mean_create_1,
99 .reset = tg_trimmed_mean_reset,
100 .free = tg_trimmed_mean_free,
101 .add = tg_trimmed_mean_add,
102 .flush = tg_trimmed_mean_flush,
103 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
104 },
105 {.name = "trimmed-mean2",
106 .hash = 0,
107 .value = RRDR_GROUPING_TRIMMED_MEAN2,
108 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
109 .init = NULL,
110 .create= tg_trimmed_mean_create_2,
111 .reset = tg_trimmed_mean_reset,
112 .free = tg_trimmed_mean_free,
113 .add = tg_trimmed_mean_add,
114 .flush = tg_trimmed_mean_flush,
115 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
116 },
117 {.name = "trimmed-mean3",
118 .hash = 0,
119 .value = RRDR_GROUPING_TRIMMED_MEAN3,
120 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
121 .init = NULL,
122 .create= tg_trimmed_mean_create_3,
123 .reset = tg_trimmed_mean_reset,
124 .free = tg_trimmed_mean_free,
125 .add = tg_trimmed_mean_add,
126 .flush = tg_trimmed_mean_flush,
127 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
128 },
129 {.name = "trimmed-mean5",
130 .hash = 0,
131 .value = RRDR_GROUPING_TRIMMED_MEAN,
132 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
133 .init = NULL,
134 .create= tg_trimmed_mean_create_5,
135 .reset = tg_trimmed_mean_reset,
136 .free = tg_trimmed_mean_free,
137 .add = tg_trimmed_mean_add,
138 .flush = tg_trimmed_mean_flush,
139 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
140 },
141 {.name = "trimmed-mean10",
142 .hash = 0,
143 .value = RRDR_GROUPING_TRIMMED_MEAN10,
144 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
145 .init = NULL,
146 .create= tg_trimmed_mean_create_10,
147 .reset = tg_trimmed_mean_reset,
148 .free = tg_trimmed_mean_free,
149 .add = tg_trimmed_mean_add,
150 .flush = tg_trimmed_mean_flush,
151 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
152 },
153 {.name = "trimmed-mean15",
154 .hash = 0,
155 .value = RRDR_GROUPING_TRIMMED_MEAN15,
156 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
157 .init = NULL,
158 .create= tg_trimmed_mean_create_15,
159 .reset = tg_trimmed_mean_reset,
160 .free = tg_trimmed_mean_free,
161 .add = tg_trimmed_mean_add,
162 .flush = tg_trimmed_mean_flush,
163 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
164 },
165 {.name = "trimmed-mean20",
166 .hash = 0,
167 .value = RRDR_GROUPING_TRIMMED_MEAN20,
168 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
169 .init = NULL,
170 .create= tg_trimmed_mean_create_20,
171 .reset = tg_trimmed_mean_reset,
172 .free = tg_trimmed_mean_free,
173 .add = tg_trimmed_mean_add,
174 .flush = tg_trimmed_mean_flush,
175 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
176 },
177 {.name = "trimmed-mean25",
178 .hash = 0,
179 .value = RRDR_GROUPING_TRIMMED_MEAN25,
180 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
181 .init = NULL,
182 .create= tg_trimmed_mean_create_25,
183 .reset = tg_trimmed_mean_reset,
184 .free = tg_trimmed_mean_free,
185 .add = tg_trimmed_mean_add,
186 .flush = tg_trimmed_mean_flush,
187 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
188 },
189 {.name = "trimmed-mean",
190 .hash = 0,
191 .value = RRDR_GROUPING_TRIMMED_MEAN,
192 .add_flush = RRDR_GROUPING_TRIMMED_MEAN,
193 .init = NULL,
194 .create= tg_trimmed_mean_create_5,
195 .reset = tg_trimmed_mean_reset,
196 .free = tg_trimmed_mean_free,
197 .add = tg_trimmed_mean_add,
198 .flush = tg_trimmed_mean_flush,
199 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
200 },
201 {.name = "incremental_sum",
202 .hash = 0,
203 .value = RRDR_GROUPING_INCREMENTAL_SUM,
204 .add_flush = RRDR_GROUPING_INCREMENTAL_SUM,
205 .init = NULL,
206 .create= tg_incremental_sum_create,
207 .reset = tg_incremental_sum_reset,
208 .free = tg_incremental_sum_free,
209 .add = tg_incremental_sum_add,
210 .flush = tg_incremental_sum_flush,
211 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
212 },
213 {.name = "incremental-sum",
214 .hash = 0,
215 .value = RRDR_GROUPING_INCREMENTAL_SUM,
216 .add_flush = RRDR_GROUPING_INCREMENTAL_SUM,
217 .init = NULL,
218 .create= tg_incremental_sum_create,
219 .reset = tg_incremental_sum_reset,
220 .free = tg_incremental_sum_free,
221 .add = tg_incremental_sum_add,
222 .flush = tg_incremental_sum_flush,
223 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
224 },
225 {.name = "median",
226 .hash = 0,
227 .value = RRDR_GROUPING_MEDIAN,
228 .add_flush = RRDR_GROUPING_MEDIAN,
229 .init = NULL,
230 .create= tg_median_create,
231 .reset = tg_median_reset,
232 .free = tg_median_free,
233 .add = tg_median_add,
234 .flush = tg_median_flush,
235 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
236 },
237 {.name = "trimmed-median1",
238 .hash = 0,
239 .value = RRDR_GROUPING_TRIMMED_MEDIAN1,
240 .add_flush = RRDR_GROUPING_MEDIAN,
241 .init = NULL,
242 .create= tg_median_create_trimmed_1,
243 .reset = tg_median_reset,
244 .free = tg_median_free,
245 .add = tg_median_add,
246 .flush = tg_median_flush,
247 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
248 },
249 {.name = "trimmed-median2",
250 .hash = 0,
251 .value = RRDR_GROUPING_TRIMMED_MEDIAN2,
252 .add_flush = RRDR_GROUPING_MEDIAN,
253 .init = NULL,
254 .create= tg_median_create_trimmed_2,
255 .reset = tg_median_reset,
256 .free = tg_median_free,
257 .add = tg_median_add,
258 .flush = tg_median_flush,
259 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
260 },
261 {.name = "trimmed-median3",
262 .hash = 0,
263 .value = RRDR_GROUPING_TRIMMED_MEDIAN3,
264 .add_flush = RRDR_GROUPING_MEDIAN,
265 .init = NULL,
266 .create= tg_median_create_trimmed_3,
267 .reset = tg_median_reset,
268 .free = tg_median_free,
269 .add = tg_median_add,
270 .flush = tg_median_flush,
271 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
272 },
273 {.name = "trimmed-median5",
274 .hash = 0,
275 .value = RRDR_GROUPING_TRIMMED_MEDIAN,
276 .add_flush = RRDR_GROUPING_MEDIAN,
277 .init = NULL,
278 .create= tg_median_create_trimmed_5,
279 .reset = tg_median_reset,
280 .free = tg_median_free,
281 .add = tg_median_add,
282 .flush = tg_median_flush,
283 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
284 },
285 {.name = "trimmed-median10",
286 .hash = 0,
287 .value = RRDR_GROUPING_TRIMMED_MEDIAN10,
288 .add_flush = RRDR_GROUPING_MEDIAN,
289 .init = NULL,
290 .create= tg_median_create_trimmed_10,
291 .reset = tg_median_reset,
292 .free = tg_median_free,
293 .add = tg_median_add,
294 .flush = tg_median_flush,
295 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
296 },
297 {.name = "trimmed-median15",
298 .hash = 0,
299 .value = RRDR_GROUPING_TRIMMED_MEDIAN15,
300 .add_flush = RRDR_GROUPING_MEDIAN,
301 .init = NULL,
302 .create= tg_median_create_trimmed_15,
303 .reset = tg_median_reset,
304 .free = tg_median_free,
305 .add = tg_median_add,
306 .flush = tg_median_flush,
307 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
308 },
309 {.name = "trimmed-median20",
310 .hash = 0,
311 .value = RRDR_GROUPING_TRIMMED_MEDIAN20,
312 .add_flush = RRDR_GROUPING_MEDIAN,
313 .init = NULL,
314 .create= tg_median_create_trimmed_20,
315 .reset = tg_median_reset,
316 .free = tg_median_free,
317 .add = tg_median_add,
318 .flush = tg_median_flush,
319 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
320 },
321 {.name = "trimmed-median25",
322 .hash = 0,
323 .value = RRDR_GROUPING_TRIMMED_MEDIAN25,
324 .add_flush = RRDR_GROUPING_MEDIAN,
325 .init = NULL,
326 .create= tg_median_create_trimmed_25,
327 .reset = tg_median_reset,
328 .free = tg_median_free,
329 .add = tg_median_add,
330 .flush = tg_median_flush,
331 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
332 },
333 {.name = "trimmed-median",
334 .hash = 0,
335 .value = RRDR_GROUPING_TRIMMED_MEDIAN,
336 .add_flush = RRDR_GROUPING_MEDIAN,
337 .init = NULL,
338 .create= tg_median_create_trimmed_5,
339 .reset = tg_median_reset,
340 .free = tg_median_free,
341 .add = tg_median_add,
342 .flush = tg_median_flush,
343 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
344 },
345 {.name = "percentile25",
346 .hash = 0,
347 .value = RRDR_GROUPING_PERCENTILE25,
348 .add_flush = RRDR_GROUPING_PERCENTILE,
349 .init = NULL,
350 .create= tg_percentile_create_25,
351 .reset = tg_percentile_reset,
352 .free = tg_percentile_free,
353 .add = tg_percentile_add,
354 .flush = tg_percentile_flush,
355 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
356 },
357 {.name = "percentile50",
358 .hash = 0,
359 .value = RRDR_GROUPING_PERCENTILE50,
360 .add_flush = RRDR_GROUPING_PERCENTILE,
361 .init = NULL,
362 .create= tg_percentile_create_50,
363 .reset = tg_percentile_reset,
364 .free = tg_percentile_free,
365 .add = tg_percentile_add,
366 .flush = tg_percentile_flush,
367 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
368 },
369 {.name = "percentile75",
370 .hash = 0,
371 .value = RRDR_GROUPING_PERCENTILE75,
372 .add_flush = RRDR_GROUPING_PERCENTILE,
373 .init = NULL,
374 .create= tg_percentile_create_75,
375 .reset = tg_percentile_reset,
376 .free = tg_percentile_free,
377 .add = tg_percentile_add,
378 .flush = tg_percentile_flush,
379 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
380 },
381 {.name = "percentile80",
382 .hash = 0,
383 .value = RRDR_GROUPING_PERCENTILE80,
384 .add_flush = RRDR_GROUPING_PERCENTILE,
385 .init = NULL,
386 .create= tg_percentile_create_80,
387 .reset = tg_percentile_reset,
388 .free = tg_percentile_free,
389 .add = tg_percentile_add,
390 .flush = tg_percentile_flush,
391 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
392 },
393 {.name = "percentile90",
394 .hash = 0,
395 .value = RRDR_GROUPING_PERCENTILE90,
396 .add_flush = RRDR_GROUPING_PERCENTILE,
397 .init = NULL,
398 .create= tg_percentile_create_90,
399 .reset = tg_percentile_reset,
400 .free = tg_percentile_free,
401 .add = tg_percentile_add,
402 .flush = tg_percentile_flush,
403 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
404 },
405 {.name = "percentile95",
406 .hash = 0,
407 .value = RRDR_GROUPING_PERCENTILE,
408 .add_flush = RRDR_GROUPING_PERCENTILE,
409 .init = NULL,
410 .create= tg_percentile_create_95,
411 .reset = tg_percentile_reset,
412 .free = tg_percentile_free,
413 .add = tg_percentile_add,
414 .flush = tg_percentile_flush,
415 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
416 },
417 {.name = "percentile97",
418 .hash = 0,
419 .value = RRDR_GROUPING_PERCENTILE97,
420 .add_flush = RRDR_GROUPING_PERCENTILE,
421 .init = NULL,
422 .create= tg_percentile_create_97,
423 .reset = tg_percentile_reset,
424 .free = tg_percentile_free,
425 .add = tg_percentile_add,
426 .flush = tg_percentile_flush,
427 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
428 },
429 {.name = "percentile98",
430 .hash = 0,
431 .value = RRDR_GROUPING_PERCENTILE98,
432 .add_flush = RRDR_GROUPING_PERCENTILE,
433 .init = NULL,
434 .create= tg_percentile_create_98,
435 .reset = tg_percentile_reset,
436 .free = tg_percentile_free,
437 .add = tg_percentile_add,
438 .flush = tg_percentile_flush,
439 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
440 },
441 {.name = "percentile99",
442 .hash = 0,
443 .value = RRDR_GROUPING_PERCENTILE99,
444 .add_flush = RRDR_GROUPING_PERCENTILE,
445 .init = NULL,
446 .create= tg_percentile_create_99,
447 .reset = tg_percentile_reset,
448 .free = tg_percentile_free,
449 .add = tg_percentile_add,
450 .flush = tg_percentile_flush,
451 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
452 },
453 {.name = "percentile",
454 .hash = 0,
455 .value = RRDR_GROUPING_PERCENTILE,
456 .add_flush = RRDR_GROUPING_PERCENTILE,
457 .init = NULL,
458 .create= tg_percentile_create_95,
459 .reset = tg_percentile_reset,
460 .free = tg_percentile_free,
461 .add = tg_percentile_add,
462 .flush = tg_percentile_flush,
463 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
464 },
465 {.name = "min",
466 .hash = 0,
467 .value = RRDR_GROUPING_MIN,
468 .add_flush = RRDR_GROUPING_MIN,
469 .init = NULL,
470 .create= tg_min_create,
471 .reset = tg_min_reset,
472 .free = tg_min_free,
473 .add = tg_min_add,
474 .flush = tg_min_flush,
475 .tier_query_fetch = TIER_QUERY_FETCH_MIN
476 },
477 {.name = "max",
478 .hash = 0,
479 .value = RRDR_GROUPING_MAX,
480 .add_flush = RRDR_GROUPING_MAX,
481 .init = NULL,
482 .create= tg_max_create,
483 .reset = tg_max_reset,
484 .free = tg_max_free,
485 .add = tg_max_add,
486 .flush = tg_max_flush,
487 .tier_query_fetch = TIER_QUERY_FETCH_MAX
488 },
489 {.name = "sum",
490 .hash = 0,
491 .value = RRDR_GROUPING_SUM,
492 .add_flush = RRDR_GROUPING_SUM,
493 .init = NULL,
494 .create= tg_sum_create,
495 .reset = tg_sum_reset,
496 .free = tg_sum_free,
497 .add = tg_sum_add,
498 .flush = tg_sum_flush,
499 .tier_query_fetch = TIER_QUERY_FETCH_SUM
500 },
501
502 // standard deviation
503 {.name = "stddev",
504 .hash = 0,
505 .value = RRDR_GROUPING_STDDEV,
506 .add_flush = RRDR_GROUPING_STDDEV,
507 .init = NULL,
508 .create= tg_stddev_create,
509 .reset = tg_stddev_reset,
510 .free = tg_stddev_free,
511 .add = tg_stddev_add,
512 .flush = tg_stddev_flush,
513 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
514 },
515 {.name = "cv", // coefficient variation is calculated by stddev
516 .hash = 0,
517 .value = RRDR_GROUPING_CV,
518 .add_flush = RRDR_GROUPING_CV,
519 .init = NULL,
520 .create= tg_stddev_create, // not an error, stddev calculates this too
521 .reset = tg_stddev_reset, // not an error, stddev calculates this too
522 .free = tg_stddev_free, // not an error, stddev calculates this too
523 .add = tg_stddev_add, // not an error, stddev calculates this too
524 .flush = tg_stddev_coefficient_of_variation_flush,
525 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
526 },
527 {.name = "rsd", // alias of 'cv'
528 .hash = 0,
529 .value = RRDR_GROUPING_CV,
530 .add_flush = RRDR_GROUPING_CV,
531 .init = NULL,
532 .create= tg_stddev_create, // not an error, stddev calculates this too
533 .reset = tg_stddev_reset, // not an error, stddev calculates this too
534 .free = tg_stddev_free, // not an error, stddev calculates this too
535 .add = tg_stddev_add, // not an error, stddev calculates this too
536 .flush = tg_stddev_coefficient_of_variation_flush,
537 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
538 },
539 {.name = "coefficient-of-variation", // alias of 'cv'
540 .hash = 0,
541 .value = RRDR_GROUPING_CV,
542 .add_flush = RRDR_GROUPING_CV,
543 .init = NULL,
544 .create= tg_stddev_create, // not an error, stddev calculates this too
545 .reset = tg_stddev_reset, // not an error, stddev calculates this too
546 .free = tg_stddev_free, // not an error, stddev calculates this too
547 .add = tg_stddev_add, // not an error, stddev calculates this too
548 .flush = tg_stddev_coefficient_of_variation_flush,
549 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
550 },
551
552 // single exponential smoothing
553 {.name = "ses",
554 .hash = 0,
555 .value = RRDR_GROUPING_SES,
556 .add_flush = RRDR_GROUPING_SES,
557 .init = tg_ses_init,
558 .create= tg_ses_create,
559 .reset = tg_ses_reset,
560 .free = tg_ses_free,
561 .add = tg_ses_add,
562 .flush = tg_ses_flush,
563 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
564 },
565 {.name = "ema", // alias for 'ses'
566 .hash = 0,
567 .value = RRDR_GROUPING_SES,
568 .add_flush = RRDR_GROUPING_SES,
569 .init = NULL,
570 .create= tg_ses_create,
571 .reset = tg_ses_reset,
572 .free = tg_ses_free,
573 .add = tg_ses_add,
574 .flush = tg_ses_flush,
575 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
576 },
577 {.name = "ewma", // alias for ses
578 .hash = 0,
579 .value = RRDR_GROUPING_SES,
580 .add_flush = RRDR_GROUPING_SES,
581 .init = NULL,
582 .create= tg_ses_create,
583 .reset = tg_ses_reset,
584 .free = tg_ses_free,
585 .add = tg_ses_add,
586 .flush = tg_ses_flush,
587 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
588 },
589
590 // double exponential smoothing
591 {.name = "des",
592 .hash = 0,
593 .value = RRDR_GROUPING_DES,
594 .add_flush = RRDR_GROUPING_DES,
595 .init = tg_des_init,
596 .create= tg_des_create,
597 .reset = tg_des_reset,
598 .free = tg_des_free,
599 .add = tg_des_add,
600 .flush = tg_des_flush,
601 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
602 },
603
604 {.name = "countif",
605 .hash = 0,
606 .value = RRDR_GROUPING_COUNTIF,
607 .add_flush = RRDR_GROUPING_COUNTIF,
608 .init = NULL,
609 .create= tg_countif_create,
610 .reset = tg_countif_reset,
611 .free = tg_countif_free,
612 .add = tg_countif_add,
613 .flush = tg_countif_flush,
614 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
615 },
616
617 {.name = "extremes",
618 .hash = 0,
619 .value = RRDR_GROUPING_EXTREMES,
620 .add_flush = RRDR_GROUPING_EXTREMES,
621 .init = NULL,
622 .create= tg_extremes_create,
623 .reset = tg_extremes_reset,
624 .free = tg_extremes_free,
625 .add = tg_extremes_add,
626 .flush = tg_extremes_flush,
627 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
628 },
629
630 // terminator
631 {.name = NULL,
632 .hash = 0,
633 .value = RRDR_GROUPING_UNDEFINED,
634 .add_flush = RRDR_GROUPING_AVERAGE,
635 .init = NULL,
636 .create= tg_average_create,
637 .reset = tg_average_reset,
638 .free = tg_average_free,
639 .add = tg_average_add,
640 .flush = tg_average_flush,
641 .tier_query_fetch = TIER_QUERY_FETCH_AVERAGE
642 }
643 };
644
645 void time_grouping_init(void) {
646 int i;
647
648 for(i = 0; api_v1_data_groups[i].name ; i++) {
649 api_v1_data_groups[i].hash = simple_hash(api_v1_data_groups[i].name);
650
651 if(api_v1_data_groups[i].init)
652 api_v1_data_groups[i].init();
653 }
654 }
655
656 const char *time_grouping_id2txt(RRDR_TIME_GROUPING group) {
657 int i;
658
659 for(i = 0; api_v1_data_groups[i].name ; i++) {
660 if(api_v1_data_groups[i].value == group) {
661 return api_v1_data_groups[i].name;
662 }
663 }
664
665 return "average";
666 }
667
668 RRDR_TIME_GROUPING time_grouping_txt2id(const char *name) {
669 int i;
670
671 uint32_t hash = simple_hash(name);
672 for(i = 0; api_v1_data_groups[i].name ; i++)
673 if(unlikely(hash == api_v1_data_groups[i].hash && !strcmp(name, api_v1_data_groups[i].name)))
674 return api_v1_data_groups[i].value;
675
676 return RRDR_GROUPING_AVERAGE;
677 }
678
679 RRDR_TIME_GROUPING time_grouping_parse(const char *name, RRDR_TIME_GROUPING def) {
680 int i;
681
682 uint32_t hash = simple_hash(name);
683 for(i = 0; api_v1_data_groups[i].name ; i++)
684 if(unlikely(hash == api_v1_data_groups[i].hash && !strcmp(name, api_v1_data_groups[i].name)))
685 return api_v1_data_groups[i].value;
686
687 return def;
688 }
689
690 const char *time_grouping_tostring(RRDR_TIME_GROUPING group) {
691 int i;
692
693 for(i = 0; api_v1_data_groups[i].name ; i++)
694 if(unlikely(group == api_v1_data_groups[i].value))
695 return api_v1_data_groups[i].name;
696
697 return "unknown";
698 }
699
700 void rrdr_set_grouping_function(RRDR *r, RRDR_TIME_GROUPING group_method) {
701 int i, found = 0;
702 for(i = 0; !found && api_v1_data_groups[i].name ;i++) {
703 if(api_v1_data_groups[i].value == group_method) {
704 r->time_grouping.create = api_v1_data_groups[i].create;
705 r->time_grouping.reset = api_v1_data_groups[i].reset;
706 r->time_grouping.free = api_v1_data_groups[i].free;
707 r->time_grouping.add = api_v1_data_groups[i].add;
708 r->time_grouping.flush = api_v1_data_groups[i].flush;
709 r->time_grouping.tier_query_fetch = api_v1_data_groups[i].tier_query_fetch;
710 r->time_grouping.add_flush = api_v1_data_groups[i].add_flush;
711 found = 1;
712 }
713 }
714 if(!found) {
715 errno_clear();
716 internal_error(true, "QUERY: grouping method %u not found. Using 'average'", (unsigned int)group_method);
717 r->time_grouping.create = tg_average_create;
718 r->time_grouping.reset = tg_average_reset;
719 r->time_grouping.free = tg_average_free;
720 r->time_grouping.add = tg_average_add;
721 r->time_grouping.flush = tg_average_flush;
722 r->time_grouping.tier_query_fetch = TIER_QUERY_FETCH_AVERAGE;
723 r->time_grouping.add_flush = RRDR_GROUPING_AVERAGE;
724 }
725 }
726
727 ALWAYS_INLINE_HOT_FLATTEN
728 void time_grouping_add(RRDR *r, NETDATA_DOUBLE value, const RRDR_TIME_GROUPING add_flush) {
729 switch(add_flush) {
730 case RRDR_GROUPING_AVERAGE:
731 tg_average_add(r, value);
732 break;
733
734 case RRDR_GROUPING_MAX:
735 tg_max_add(r, value);
736 break;
737
738 case RRDR_GROUPING_MIN:
739 tg_min_add(r, value);
740 break;
741
742 case RRDR_GROUPING_MEDIAN:
743 tg_median_add(r, value);
744 break;
745
746 case RRDR_GROUPING_STDDEV:
747 case RRDR_GROUPING_CV:
748 tg_stddev_add(r, value);
749 break;
750
751 case RRDR_GROUPING_SUM:
752 tg_sum_add(r, value);
753 break;
754
755 case RRDR_GROUPING_COUNTIF:
756 tg_countif_add(r, value);
757 break;
758
759 case RRDR_GROUPING_EXTREMES:
760 tg_extremes_add(r, value);
761 break;
762
763 case RRDR_GROUPING_TRIMMED_MEAN:
764 tg_trimmed_mean_add(r, value);
765 break;
766
767 case RRDR_GROUPING_PERCENTILE:
768 tg_percentile_add(r, value);
769 break;
770
771 case RRDR_GROUPING_SES:
772 tg_ses_add(r, value);
773 break;
774
775 case RRDR_GROUPING_DES:
776 tg_des_add(r, value);
777 break;
778
779 case RRDR_GROUPING_INCREMENTAL_SUM:
780 tg_incremental_sum_add(r, value);
781 break;
782
783 default:
784 r->time_grouping.add(r, value);
785 break;
786 }
787 }
788
789 ALWAYS_INLINE_HOT_FLATTEN
790 NETDATA_DOUBLE time_grouping_flush(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr, const RRDR_TIME_GROUPING add_flush) {
791 switch(add_flush) {
792 case RRDR_GROUPING_AVERAGE:
793 return tg_average_flush(r, rrdr_value_options_ptr);
794
795 case RRDR_GROUPING_MAX:
796 return tg_max_flush(r, rrdr_value_options_ptr);
797
798 case RRDR_GROUPING_MIN:
799 return tg_min_flush(r, rrdr_value_options_ptr);
800
801 case RRDR_GROUPING_MEDIAN:
802 return tg_median_flush(r, rrdr_value_options_ptr);
803
804 case RRDR_GROUPING_STDDEV:
805 return tg_stddev_flush(r, rrdr_value_options_ptr);
806
807 case RRDR_GROUPING_CV:
808 return tg_stddev_coefficient_of_variation_flush(r, rrdr_value_options_ptr);
809
810 case RRDR_GROUPING_SUM:
811 return tg_sum_flush(r, rrdr_value_options_ptr);
812
813 case RRDR_GROUPING_COUNTIF:
814 return tg_countif_flush(r, rrdr_value_options_ptr);
815
816 case RRDR_GROUPING_EXTREMES:
817 return tg_extremes_flush(r, rrdr_value_options_ptr);
818
819 case RRDR_GROUPING_TRIMMED_MEAN:
820 return tg_trimmed_mean_flush(r, rrdr_value_options_ptr);
821
822 case RRDR_GROUPING_PERCENTILE:
823 return tg_percentile_flush(r, rrdr_value_options_ptr);
824
825 case RRDR_GROUPING_SES:
826 return tg_ses_flush(r, rrdr_value_options_ptr);
827
828 case RRDR_GROUPING_DES:
829 return tg_des_flush(r, rrdr_value_options_ptr);
830
831 case RRDR_GROUPING_INCREMENTAL_SUM:
832 return tg_incremental_sum_flush(r, rrdr_value_options_ptr);
833
834 default:
835 return r->time_grouping.flush(r, rrdr_value_options_ptr);
836 }
837 }