From: Julien Thomas Date: Fri, 7 Feb 2014 13:21:53 +0000 (+0100) Subject: Add support for MINNAN and MAXNAN operators X-Git-Tag: v1.4.9~24^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd8a2045de43f1ed6cd47d554534b0aab7a0e594;p=thirdparty%2Frrdtool-1.x.git Add support for MINNAN and MAXNAN operators NAN-safe version of MIN and MAX. If one of the input numbers is unknown then the result of the operation will be the other one. If both are unknown, then the result of the operation is unknown. --- diff --git a/doc/rrdgraph_rpn.pod b/doc/rrdgraph_rpn.pod index 894fef16..c7847a20 100644 --- a/doc/rrdgraph_rpn.pod +++ b/doc/rrdgraph_rpn.pod @@ -79,6 +79,12 @@ respectively. Note that I is larger than anything else. If one of the input numbers is I then the result of the operation will be I too. +B + +NAN-safe version of MIN and MAX. If one of the input numbers is I +then the result of the operation will be the other one. If both are +I, then the result of the operation is I. + B Pops two elements from the stack and uses them to define a range. diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index 630a94c4..c847ee4b 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -185,6 +185,8 @@ void rpn_compact2str( add_op(OP_AVG, AVG) add_op(OP_ABS, ABS) add_op(OP_ADDNAN, ADDNAN) + add_op(OP_MINNAN, MINNAN) + add_op(OP_MAXNAN, MAXNAN) #undef add_op } (*str)[offset] = '\0'; @@ -388,6 +390,8 @@ rpnp_t *rpn_parse( match_op(OP_AVG, AVG) match_op(OP_ABS, ABS) match_op(OP_ADDNAN, ADDNAN) + match_op(OP_MINNAN, MINNAN) + match_op(OP_MAXNAN, MAXNAN) #undef match_op else if ((sscanf(expr, DEF_NAM_FMT "%n", vname, &pos) == 1) && ((rpnp[steps].ptr = (*lookup) (key_hash, vname)) != @@ -735,6 +739,15 @@ short rpn_calc( rpnstack->s[stptr - 1] = rpnstack->s[stptr]; stptr--; break; + case OP_MINNAN: + stackunderflow(1); + if (isnan(rpnstack->s[stptr - 1])) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + else if (isnan(rpnstack->s[stptr])); + else if (rpnstack->s[stptr - 1] > rpnstack->s[stptr]) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + stptr--; + break; case OP_MAX: stackunderflow(1); if (isnan(rpnstack->s[stptr - 1])); @@ -744,6 +757,15 @@ short rpn_calc( rpnstack->s[stptr - 1] = rpnstack->s[stptr]; stptr--; break; + case OP_MAXNAN: + stackunderflow(1); + if (isnan(rpnstack->s[stptr - 1])) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + else if (isnan(rpnstack->s[stptr])); + else if (rpnstack->s[stptr - 1] < rpnstack->s[stptr]) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + stptr--; + break; case OP_LIMIT: stackunderflow(2); if (isnan(rpnstack->s[stptr - 2])); diff --git a/src/rrd_rpncalc.h b/src/rrd_rpncalc.h index ea6b87c2..c032d8e3 100644 --- a/src/rrd_rpncalc.h +++ b/src/rrd_rpncalc.h @@ -19,7 +19,8 @@ enum op_en { OP_NUMBER = 0, OP_VARIABLE, OP_INF, OP_PREV, OP_NEGINF, OP_ATAN, OP_SQRT, OP_SORT, OP_REV, OP_TREND, OP_TRENDNAN, OP_ATAN2, OP_RAD2DEG, OP_DEG2RAD, OP_PREDICT,OP_PREDICTSIGMA, - OP_AVG, OP_ABS, OP_ADDNAN + OP_AVG, OP_ABS, OP_ADDNAN, + OP_MINNAN, OP_MAXNAN }; typedef struct rpnp_t {