summaryrefslogtreecommitdiffstats
path: root/web/api/formatters/value/value.c
diff options
context:
space:
mode:
Diffstat (limited to 'web/api/formatters/value/value.c')
-rw-r--r--web/api/formatters/value/value.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/web/api/formatters/value/value.c b/web/api/formatters/value/value.c
index 30e00c068..46a71303e 100644
--- a/web/api/formatters/value/value.c
+++ b/web/api/formatters/value/value.c
@@ -3,9 +3,10 @@
#include "value.h"
-inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, NETDATA_DOUBLE *anomaly_rate, RRDDIM *temp_rd) {
+inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all_values_are_null, NETDATA_DOUBLE *anomaly_rate) {
+ QUERY_TARGET *qt = r->internal.qt;
long c;
- RRDDIM *d;
+ const long used = qt->query.used;
NETDATA_DOUBLE *cn = &r->v[ i * r->d ];
RRDR_VALUE_FLAGS *co = &r->o[ i * r->d ];
@@ -20,7 +21,7 @@ inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all
int set_min_max = 0;
if(unlikely(options & RRDR_OPTION_PERCENTAGE)) {
total = 0;
- for (c = 0, d = temp_rd ? temp_rd : r->st->dimensions; d && c < r->d; c++, d = d->next) {
+ for (c = 0; c < used; c++) {
NETDATA_DOUBLE n = cn[c];
if(likely((options & RRDR_OPTION_ABSOLUTE) && n < 0))
@@ -34,7 +35,7 @@ inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all
}
// for each dimension
- for (c = 0, d = temp_rd ? temp_rd : r->st->dimensions; d && c < r->d; c++, d = d->next) {
+ for (c = 0; c < used; c++) {
if(unlikely(r->od[c] & RRDR_DIMENSION_HIDDEN)) continue;
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_DIMENSION_NONZERO))) continue;
@@ -80,7 +81,7 @@ inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all
if(anomaly_rate) {
if(!r->d) *anomaly_rate = 0;
- else *anomaly_rate = total_anomaly_rate / r->d;
+ else *anomaly_rate = total_anomaly_rate / (NETDATA_DOUBLE)r->d;
}
if(unlikely(all_null)) {
@@ -100,3 +101,62 @@ inline NETDATA_DOUBLE rrdr2value(RRDR *r, long i, RRDR_OPTIONS options, int *all
return v;
}
+
+QUERY_VALUE rrdmetric2value(RRDHOST *host,
+ struct rrdcontext_acquired *rca, struct rrdinstance_acquired *ria, struct rrdmetric_acquired *rma,
+ time_t after, time_t before,
+ RRDR_OPTIONS options, RRDR_GROUPING group_method, const char *group_options,
+ size_t tier, time_t timeout, QUERY_SOURCE query_source
+) {
+ QUERY_TARGET_REQUEST qtr = {
+ .host = host,
+ .rca = rca,
+ .ria = ria,
+ .rma = rma,
+ .after = after,
+ .before = before,
+ .points = 1,
+ .options = options,
+ .group_method = group_method,
+ .group_options = group_options,
+ .tier = tier,
+ .timeout = timeout,
+ .query_source = query_source,
+ };
+
+ ONEWAYALLOC *owa = onewayalloc_create(16 * 1024);
+ RRDR *r = rrd2rrdr(owa, query_target_create(&qtr));
+
+ QUERY_VALUE qv;
+
+ if(!r || rrdr_rows(r) == 0) {
+ qv = (QUERY_VALUE) {
+ .value = NAN,
+ .anomaly_rate = NAN,
+ };
+ }
+ else {
+ qv = (QUERY_VALUE) {
+ .after = r->after,
+ .before = r->before,
+ .points_read = r->internal.db_points_read,
+ .result_points = r->internal.result_points_generated,
+ };
+
+ for(size_t t = 0; t < storage_tiers ;t++)
+ qv.storage_points_per_tier[t] = r->internal.tier_points_read[t];
+
+ long i = (!(options & RRDR_OPTION_REVERSED))?(long)rrdr_rows(r) - 1:0;
+ int all_values_are_null = 0;
+ qv.value = rrdr2value(r, i, options, &all_values_are_null, &qv.anomaly_rate);
+ if(all_values_are_null) {
+ qv.value = NAN;
+ qv.anomaly_rate = NAN;
+ }
+ }
+
+ rrdr_free(owa, r);
+ onewayalloc_destroy(owa);
+
+ return qv;
+}