[rrd-developers] Patch for Percentil calculation that ignores NAN
Martin Sperl
rrdtool at martin.sperl.org
Fri Jan 9 09:32:26 CET 2009
Hi!
As this is missing for my needs here a patch for percentil calculation
that does ignore NAN's...
Ciao,
Martin
Index: src/rrd_graph.c
===================================================================
--- src/rrd_graph.c (revision 1726)
+++ src/rrd_graph.c (working copy)
@@ -4586,6 +4586,8 @@
}
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 @@
};
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 @@
#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]))
Index: src/rrd_graph.h
===================================================================
--- src/rrd_graph.h (revision 1726)
+++ src/rrd_graph.h (working copy)
@@ -70,6 +70,7 @@
, 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 */
Index: doc/rrdgraph_rpn.pod
===================================================================
--- doc/rrdgraph_rpn.pod (revision 1726)
+++ doc/rrdgraph_rpn.pod (working copy)
@@ -357,12 +357,13 @@
Example: C<VDEF:total=mydata,TOTAL>
-=item PERCENT
+=item PERCENT, PERCENTNAN
This should follow a B<DEF> or B<CDEF> I<vname>. The I<vname> 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<percentage> percent of the values is lower or equal than the result.
+For PERCENTNAN I<Unknown> values are ignored, but for PERCENT
I<Unknown> values are considered lower than any finite number for this
purpose so if this operator returns an I<unknown> you have quite a lot
of them in your data. B<Inf>inite numbers are lesser, or more, than the
@@ -370,6 +371,7 @@
(NaN E<lt> -INF E<lt> finite values E<lt> INF)
Example: C<VDEF:perc95=mydata,95,PERCENT>
+ C<VDEF:percnan95=mydata,95,PERCENTNAN>
=item LSLSLOPE, LSLINT, LSLCORREL
More information about the rrd-developers
mailing list