From 22424d6b1c6a14c1d919482f991427c7e43853a8 Mon Sep 17 00:00:00 2001 From: oetiker Date: Wed, 14 Jan 2009 07:22:09 +0000 Subject: [PATCH] added percentnan (VDEF PERCENT variant that ignores NAN) -- patch by Martin Sperl git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1732 a5681a0c-68f1-0310-ab6d-d61299d08faa --- NEWS | 4 ++++ doc/rrdgraph_rpn.pod | 4 +++- src/rrd_graph.c | 31 +++++++++++++++++++++++++++++++ src/rrd_graph.h | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b31f0fd..2c26f68 100644 --- a/NEWS +++ b/NEWS @@ -14,3 +14,7 @@ RRDdump ------- * no more spaces in output * additional option: --header {none,xsd,dtd} + +RRDgraph +-------- +* VDEF PERCENTNAN (PRECENT that ignores NAN) diff --git a/doc/rrdgraph_rpn.pod b/doc/rrdgraph_rpn.pod index 21661ba..de44c0b 100644 --- a/doc/rrdgraph_rpn.pod +++ b/doc/rrdgraph_rpn.pod @@ -357,12 +357,13 @@ the number of seconds. Example: C -=item PERCENT +=item PERCENT, PERCENTNAN This should follow a B or B I. The I is popped, another number is popped which is a certain percentage (0..100). The data set is then sorted and the value returned is chosen such that I percent of the values is lower or equal than the result. +For PERCENTNAN I values are ignored, but for PERCENT I values are considered lower than any finite number for this purpose so if this operator returns an I you have quite a lot of them in your data. Binite numbers are lesser, or more, than the @@ -370,6 +371,7 @@ finite numbers and are always more than the I numbers. (NaN E -INF E finite values E INF) Example: C + C =item LSLSLOPE, LSLINT, LSLCORREL diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 613446f..40539b3 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -4586,6 +4586,8 @@ int vdef_parse( } if (!strcmp("PERCENT", func)) gdes->vf.op = VDEF_PERCENT; + else if (!strcmp("PERCENTNAN", func)) + gdes->vf.op = VDEF_PERCENTNAN; else if (!strcmp("MAXIMUM", func)) gdes->vf.op = VDEF_MAXIMUM; else if (!strcmp("AVERAGE", func)) @@ -4613,6 +4615,7 @@ int vdef_parse( }; switch (gdes->vf.op) { case VDEF_PERCENT: + case VDEF_PERCENTNAN: if (isnan(param)) { /* no parameter given */ rrd_set_error ("Function '%s' needs parameter in VDEF '%s'\n", @@ -4697,6 +4700,34 @@ int vdef_calc( #endif } break; + case VDEF_PERCENTNAN:{ + rrd_value_t *array; + int field; + /* count number of "valid" values */ + int nancount=0; + for (step = 0; step < steps; step++) { + if (!isnan(data[step * src->ds_cnt])) { nancount++; } + } + /* and allocate it */ + if ((array = (rrd_value_t*)malloc(nancount * sizeof(double))) == NULL) { + rrd_set_error("malloc VDEV_PERCENT"); + return -1; + } + /* and fill it in */ + field=0; + for (step = 0; step < steps; step++) { + if (!isnan(data[step * src->ds_cnt])) { + array[field] = data[step * src->ds_cnt]; + field++; + } + } + qsort(array, nancount, sizeof(double), vdef_percent_compar); + field = (nancount - 1) * dst->vf.param / 100; + dst->vf.val = array[field]; + dst->vf.when = 0; /* no time component */ + free(array); + } + break; case VDEF_MAXIMUM: step = 0; while (step != steps && isnan(data[step * src->ds_cnt])) diff --git a/src/rrd_graph.h b/src/rrd_graph.h index 25e9db2..cc36c25 100644 --- a/src/rrd_graph.h +++ b/src/rrd_graph.h @@ -70,6 +70,7 @@ enum vdef_op_en { , VDEF_LSLSLOPE /* least squares line slope */ , VDEF_LSLINT /* least squares line y_intercept */ , VDEF_LSLCORREL /* least squares line correlation coefficient */ + , VDEF_PERCENTNAN /* Nth percentile ignoring NAN*/ }; enum text_prop_en { TEXT_PROP_DEFAULT = 0, /* default settings */ -- 2.11.0