| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #ifndef NETDATA_QUERIES_RRDR_H |
| 4 | #define NETDATA_QUERIES_RRDR_H |
| 5 | |
| 6 | #include "libnetdata/libnetdata.h" |
| 7 | #include "web/api/queries/query.h" |
| 8 | |
| 9 | #ifdef __cplusplus |
| 10 | extern "C" { |
| 11 | #endif |
| 12 | |
| 13 | typedef enum tier_query_fetch { |
| 14 | TIER_QUERY_FETCH_SUM, |
| 15 | TIER_QUERY_FETCH_MIN, |
| 16 | TIER_QUERY_FETCH_MAX, |
| 17 | TIER_QUERY_FETCH_AVERAGE |
| 18 | } TIER_QUERY_FETCH; |
| 19 | |
| 20 | typedef enum __attribute__ ((__packed__)) rrdr_value_flag { |
| 21 | |
| 22 | // IMPORTANT: |
| 23 | // THIS IS AN AGREED BIT MAP BETWEEN AGENT, CLOUD FRONT-END AND CLOUD BACK-END |
| 24 | // DO NOT CHANGE THE MAPPINGS ! |
| 25 | |
| 26 | RRDR_VALUE_NOTHING = 0, // no flag set (a good default) |
| 27 | RRDR_VALUE_EMPTY = (1 << 0), // the database value is empty |
| 28 | RRDR_VALUE_RESET = (1 << 1), // the database value is marked as reset (overflown) |
| 29 | RRDR_VALUE_PARTIAL = (1 << 2), // the database provides partial data about this point (used in group-by) |
| 30 | } RRDR_VALUE_FLAGS; |
| 31 | |
| 32 | typedef enum __attribute__ ((__packed__)) rrdr_dimension_flag { |
| 33 | RRDR_DIMENSION_DEFAULT = 0, |
| 34 | RRDR_DIMENSION_HIDDEN = (1 << 0), // the dimension is hidden (not to be presented to callers) |
| 35 | RRDR_DIMENSION_NONZERO = (1 << 1), // the dimension is non zero (contains non-zero values) |
| 36 | RRDR_DIMENSION_SELECTED = (1 << 2), // the dimension has been selected for query |
| 37 | RRDR_DIMENSION_QUERIED = (1 << 3), // the dimension has been queried |
| 38 | RRDR_DIMENSION_FAILED = (1 << 4), // the dimension failed to be queried |
| 39 | RRDR_DIMENSION_GROUPED = (1 << 5), // the dimension has been grouped in this RRDR |
| 40 | } RRDR_DIMENSION_FLAGS; |
| 41 | |
| 42 | // RRDR result options |
| 43 | typedef enum __attribute__ ((__packed__)) rrdr_result_flags { |
| 44 | RRDR_RESULT_FLAG_ABSOLUTE = (1 << 0), // the query uses absolute time-frames |
| 45 | // (can be cached by browsers and proxies) |
| 46 | RRDR_RESULT_FLAG_RELATIVE = (1 << 1), // the query uses relative time-frames |
| 47 | // (should not to be cached by browsers and proxies) |
| 48 | RRDR_RESULT_FLAG_CANCEL = (1 << 2), // the query needs to be cancelled |
| 49 | } RRDR_RESULT_FLAGS; |
| 50 | |
| 51 | #define RRDR_DVIEW_ANOMALY_COUNT_MULTIPLIER 1000.0 |
| 52 | |
| 53 | typedef struct rrdresult { |
| 54 | size_t d; // the number of dimensions |
| 55 | size_t n; // the number of values in the arrays (number of points per dimension) |
| 56 | size_t rows; // the number of actual rows used |
| 57 | |
| 58 | RRDR_DIMENSION_FLAGS *od; // the options for the dimensions |
| 59 | |
| 60 | STRING **di; // array of d dimension ids |
| 61 | STRING **dn; // array of d dimension names |
| 62 | STRING **du; // array of d dimension units |
| 63 | uint32_t *dgbs; // array of d dimension group by slots - NOT ALLOCATED when RRDR is created |
| 64 | uint32_t *dgbc; // array of d dimension group by counts - NOT ALLOCATED when RRDR is created |
| 65 | uint32_t *dp; // array of d dimension priority - NOT ALLOCATED when RRDR is created |
| 66 | DICTIONARY **dl; // array of d dimension labels - NOT ALLOCATED when RRDR is created |
| 67 | STORAGE_POINT *dqp; // array of d dimensions query points - NOT ALLOCATED when RRDR is created |
| 68 | STORAGE_POINT *dview; // array of d dimensions group by view - NOT ALLOCATED when RRDR is created |
| 69 | NETDATA_DOUBLE *vh; // array of n x d hidden values, while grouping - NOT ALLOCATED when RRDR is created |
| 70 | |
| 71 | DICTIONARY *label_keys; |
| 72 | |
| 73 | time_t *t; // array of n timestamps |
| 74 | NETDATA_DOUBLE *v; // array n x d values |
| 75 | RRDR_VALUE_FLAGS *o; // array n x d options for each value returned |
| 76 | NETDATA_DOUBLE *ar; // array n x d of anomaly rates (0 - 100) |
| 77 | uint32_t *gbc; // array n x d of group by count - NOT ALLOCATED when RRDR is created |
| 78 | |
| 79 | struct { |
| 80 | size_t group; // how many collected values were grouped for each row - NEEDED BY GROUPING FUNCTIONS |
| 81 | time_t after; |
| 82 | time_t before; |
| 83 | time_t update_every; // what is the suggested update frequency in seconds |
| 84 | NETDATA_DOUBLE min; |
| 85 | NETDATA_DOUBLE max; |
| 86 | RRDR_RESULT_FLAGS flags; // RRDR_RESULT_FLAG_* |
| 87 | } view; |
| 88 | |
| 89 | struct { |
| 90 | size_t db_points_read; |
| 91 | size_t result_points_generated; |
| 92 | } stats; |
| 93 | |
| 94 | struct { |
| 95 | void *data; // the internal data of the grouping function |
| 96 | |
| 97 | // grouping function pointers |
| 98 | RRDR_TIME_GROUPING add_flush; |
| 99 | void (*create)(struct rrdresult *r, const char *options); |
| 100 | void (*reset)(struct rrdresult *r); |
| 101 | void (*free)(struct rrdresult *r); |
| 102 | void (*add)(struct rrdresult *r, NETDATA_DOUBLE value); |
| 103 | NETDATA_DOUBLE (*flush)(struct rrdresult *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr); |
| 104 | |
| 105 | TIER_QUERY_FETCH tier_query_fetch; // which value to use from STORAGE_POINT |
| 106 | |
| 107 | size_t points_wanted; // used by SES and DES |
| 108 | size_t resampling_group; // used by AVERAGE |
| 109 | NETDATA_DOUBLE resampling_divisor; // used by AVERAGE |
| 110 | } time_grouping; |
| 111 | |
| 112 | struct { |
| 113 | struct rrdresult *r; |
| 114 | } group_by; |
| 115 | |
| 116 | struct { |
| 117 | time_t max_update_every; |
| 118 | time_t expected_after; |
| 119 | time_t trimmed_after; |
| 120 | } partial_data_trimming; |
| 121 | |
| 122 | struct { |
| 123 | ONEWAYALLOC *owa; // the allocator used |
| 124 | struct query_target *qt; // the QUERY_TARGET |
| 125 | size_t contexts; // temp needed between json_wrapper_begin2() and json_wrapper_end2() |
| 126 | size_t queries_count; // temp needed to know if a query is the first executed |
| 127 | |
| 128 | #ifdef NETDATA_INTERNAL_CHECKS |
| 129 | const char *log; |
| 130 | #endif |
| 131 | |
| 132 | struct query_target *release_with_rrdr_qt; |
| 133 | } internal; |
| 134 | } RRDR; |
| 135 | |
| 136 | #define rrdr_rows(r) ((r)->rows) |
| 137 | |
| 138 | #include "database/rrd.h" |
| 139 | void rrdr_free(ONEWAYALLOC *owa, RRDR *r); |
| 140 | RRDR *rrdr_create(ONEWAYALLOC *owa, struct query_target *qt, size_t dimensions, size_t points); |
| 141 | |
| 142 | #include "../web_api_v1.h" |
| 143 | #include "web/api/queries/query.h" |
| 144 | |
| 145 | RRDR *rrd2rrdr_legacy( |
| 146 | ONEWAYALLOC *owa, |
| 147 | RRDSET *st, size_t points, time_t after, time_t before, |
| 148 | RRDR_TIME_GROUPING group_method, time_t resampling_time, RRDR_OPTIONS options, const char *dimensions, |
| 149 | const char *group_options, time_t timeout_ms, size_t tier, QUERY_SOURCE query_source, |
| 150 | STORAGE_PRIORITY priority); |
| 151 | |
| 152 | RRDR *rrd2rrdr(ONEWAYALLOC *owa, struct query_target *qt); |
| 153 | bool query_target_calculate_window(struct query_target *qt); |
| 154 | |
| 155 | #ifdef __cplusplus |
| 156 | } |
| 157 | #endif |
| 158 | |
| 159 | #endif //NETDATA_QUERIES_RRDR_H |