master
c 156 lines 4.58 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "value.h"
4
5 inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, NETDATA_DOUBLE *anomaly_rate) {
6 size_t c;
7
8 if(!r->d || !r->n || (size_t)i >= r->n)
9 return NAN;
10
11 NETDATA_DOUBLE *cn = &r->v[ i * r->d ];
12 RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ];
13 NETDATA_DOUBLE *ar = &r->ar[ i * r->d ];
14
15 NETDATA_DOUBLE sum = 0, min = NAN, max = NAN, v = NAN;
16 size_t dims = 0;
17
18 NETDATA_DOUBLE total_anomaly_rate = 0;
19
20 // for each dimension
21 for (c = 0; c < r->d ; c++) {
22 if(unlikely(!rrdr_dimension_should_be_exposed(r->od[c], options)))
23 continue;
24
25 if(unlikely((co[c] & RRDR_VALUE_EMPTY)))
26 continue;
27
28 NETDATA_DOUBLE n = cn[c];
29
30 if(unlikely(!dims))
31 min = max = n;
32
33 sum += n;
34
35 if (n < min) min = n;
36 if (n > max) max = n;
37
38 total_anomaly_rate += ar[c];
39
40 dims++;
41 }
42
43 if(!dims) {
44 if(anomaly_rate)
45 *anomaly_rate = 0;
46
47 if(all_values_are_null)
48 *all_values_are_null = 1;
49
50 return (options & RRDR_OPTION_NULL2ZERO) ? 0 : NAN;
51 }
52
53 if(anomaly_rate)
54 *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)dims;
55
56 if(all_values_are_null)
57 *all_values_are_null = 0;
58
59 if(options & RRDR_OPTION_DIMS_MIN2MAX)
60 v = max - min;
61 else if(options & RRDR_OPTION_DIMS_AVERAGE)
62 v = sum / (NETDATA_DOUBLE)dims;
63 else if(options & RRDR_OPTION_DIMS_MIN)
64 v = min;
65 else if(options & RRDR_OPTION_DIMS_MAX)
66 v = max;
67 else
68 v = sum;
69
70 if((options & RRDR_OPTION_NULL2ZERO) && (isnan(v) || isinf(v)))
71 v = 0;
72
73 return v;
74 }
75
76 QUERY_VALUE rrdmetric2value(RRDHOST *host,
77 struct rrdcontext_acquired *rca, struct rrdinstance_acquired *ria, struct rrdmetric_acquired *rma,
78 time_t after, time_t before,
79 RRDR_OPTIONS options, RRDR_TIME_GROUPING time_group_method, const char *time_group_options,
80 size_t tier, time_t timeout, QUERY_SOURCE query_source, STORAGE_PRIORITY priority
81 ) {
82 QUERY_TARGET_REQUEST qtr = {
83 .version = 1,
84 .host = host,
85 .rca = rca,
86 .ria = ria,
87 .rma = rma,
88 .after = after,
89 .before = before,
90 .points = 1,
91 .options = options,
92 .time_group_method = time_group_method,
93 .time_group_options = time_group_options,
94 .tier = tier,
95 .timeout_ms = timeout,
96 .query_source = query_source,
97 .priority = priority,
98 };
99
100 ONEWAYALLOC *owa = onewayalloc_create(16 * 1024);
101 QUERY_TARGET *qt = query_target_create(&qtr);
102 RRDR *r = rrd2rrdr(owa, qt);
103
104 QUERY_VALUE qv;
105
106 if(!r || rrdr_rows(r) == 0) {
107 qv = (QUERY_VALUE) {
108 .value = NAN,
109 .anomaly_rate = NAN,
110 .sp = {
111 .count = 0,
112 .min = NAN,
113 .max = NAN,
114 .sum = NAN,
115 .anomaly_count = 0,
116 },
117 .duration_ut = (r) ? r->internal.qt->timings.executed_ut - r->internal.qt->timings.received_ut : 0,
118 };
119 }
120 else {
121 qv = (QUERY_VALUE) {
122 .after = r->view.after,
123 .before = r->view.before,
124 .points_read = r->stats.db_points_read,
125 .result_points = r->stats.result_points_generated,
126 .sp = {
127 .count = 0,
128 },
129 .duration_ut = r->internal.qt->timings.executed_ut - r->internal.qt->timings.received_ut,
130 };
131
132 for(size_t d = 0; d < r->internal.qt->query.used ;d++) {
133 if(!rrdr_dimension_should_be_exposed(r->internal.qt->query.array[d].status, options))
134 continue;
135
136 storage_point_merge_to(qv.sp, r->internal.qt->query.array[d].query_points);
137 }
138
139 for(size_t t = 0; t < nd_profile.storage_tiers;t++)
140 qv.storage_points_per_tier[t] = r->internal.qt->db.tiers[t].points;
141
142 long i = (!(options & RRDR_OPTION_REVERSED))?(long)rrdr_rows(r) - 1:0;
143 int all_values_are_null = 0;
144 qv.value = rrdr2value(r, i, options, &all_values_are_null, &qv.anomaly_rate);
145 if(all_values_are_null) {
146 qv.value = NAN;
147 qv.anomaly_rate = NAN;
148 }
149 }
150
151 rrdr_free(owa, r);
152 query_target_release(qt);
153 onewayalloc_destroy(owa);
154
155 return qv;
156 }