]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
Add support for MINNAN and MAXNAN operators 440/head
authorJulien Thomas <jthomas@exosec.fr>
Fri, 7 Feb 2014 13:21:53 +0000 (14:21 +0100)
committerJulien Thomas <jthomas@exosec.fr>
Tue, 11 Feb 2014 22:46:17 +0000 (23:46 +0100)
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.

doc/rrdgraph_rpn.pod
src/rrd_rpncalc.c
src/rrd_rpncalc.h

index 894fef16bbabcf42215946a1f880d8241d954f38..c7847a20a1e84726532192af19cd0cf2cdd426f2 100644 (file)
@@ -79,6 +79,12 @@ respectively.  Note that I<infinite> is larger than anything else.
 If one of the input numbers is I<unknown> then the result of the operation will be
 I<unknown> too.
 
+B<MINNAN, MAXNAN>
+
+NAN-safe version of MIN and MAX. If one of the input numbers is I<unknown>
+then the result of the operation will be the other one. If both are
+I<unknown>, then the result of the operation is I<unknown>.
+
 B<LIMIT>
 
 Pops two elements from the stack and uses them to define a range.
index 630a94c49c7148ce17a3738a1eee3ebb11fef851..c847ee4b5eb4587bc539bb31e42f8aa805ca5c6d 100644 (file)
@@ -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]));
index ea6b87c2045c465a19e69ade2ddf5cfc0a9861c0..c032d8e3be95f0e687594e43ecf01c602adbb836 100644 (file)
@@ -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 {