]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
added support for STEPWIDTH rpn operator
authorTobias Oetiker <tobi@oetiker.ch>
Wed, 5 Aug 2015 11:53:56 +0000 (13:53 +0200)
committerTobias Oetiker <tobi@oetiker.ch>
Wed, 5 Aug 2015 11:53:56 +0000 (13:53 +0200)
doc/rrdgraph_rpn.pod
src/rrd_graph.c
src/rrd_rpncalc.c
src/rrd_rpncalc.h
tests/Makefile.am
tests/functions
tests/rpn2 [new file with mode: 0755]
tests/rpn2.output [new file with mode: 0644]

index cb3d1a9c835dc75ca099683b4a0588c46404280a..c5c1c0b476b6906a2a148f2f171d61be67f1304a 100644 (file)
@@ -341,6 +341,13 @@ B<NOW>
 
 Pushes the current time on the stack.
 
+B<STEPWIDTH>
+
+The with of the current step in seconds. You can use this to go back from
+rate based presentations to absolute numbers
+
+  CDEF:abs=rate,STEPWIDTH,*,PREF,ADDNAN
+
 B<TIME>
 
 Pushes the time the currently processed value was taken at onto the stack.
index 47c4dcb08c5506728eda088f7fa975bdc22953a0..5d1184e58c26061c844971069c7e5f220d69bed1 100644 (file)
@@ -1252,6 +1252,14 @@ int data_calc(
              */
             im->gdes[gdi].step = lcd(steparray);
             free(steparray);
+            /* supply the actual stepwith for this run */
+            for (rpi = 0; im->gdes[gdi].rpnp[rpi].op != OP_END; rpi++) {
+                if (im->gdes[gdi].rpnp[rpi].op == OP_STEPWIDTH) {
+                    im->gdes[gdi].rpnp[rpi].val = im->gdes[gdi].step;
+                    im->gdes[gdi].rpnp[rpi].op = OP_NUMBER;
+                }
+            }
+
             if ((im->gdes[gdi].data = (rrd_value_t*)malloc(((im->gdes[gdi].end -
                                                im->gdes[gdi].start)
                                               / im->gdes[gdi].step)
index 243a7e65956ee6ec089c0502bebfd4009d3af104..08ffd619af38b92aeacbcd088ae566d0525e7cbd 100644 (file)
@@ -173,6 +173,7 @@ void rpn_compact2str(
             add_op(OP_ISINF, ISINF)
             add_op(OP_NOW, NOW)
             add_op(OP_LTIME, LTIME)
+            add_op(OP_STEPWIDTH, STEPWIDTH)
             add_op(OP_TIME, TIME)
             add_op(OP_ATAN2, ATAN2)
             add_op(OP_ATAN, ATAN)
@@ -246,13 +247,13 @@ void parseCDEF_DS(const char *def,
      * COMPUTE DS specific. This is less efficient, but creation doesn't
      * occur too often. */
     for (i = 0; rpnp[i].op != OP_END; i++) {
-        if (rpnp[i].op == OP_TIME || rpnp[i].op == OP_LTIME ||
+        if (rpnp[i].op == OP_TIME || rpnp[i].op == OP_LTIME || rpnp[i].op == OP_STEPWIDTH ||
             rpnp[i].op == OP_PREV || rpnp[i].op == OP_COUNT ||
             rpnp[i].op == OP_TREND || rpnp[i].op == OP_TRENDNAN ||
             rpnp[i].op == OP_PREDICT || rpnp[i].op ==  OP_PREDICTSIGMA ||
             rpnp[i].op == OP_PREDICTPERC ) {
             rrd_set_error
-                ("operators TIME, LTIME, PREV COUNT TREND TRENDNAN PREDICT PREDICTSIGMA PREDICTPERC are not supported with DS COMPUTE");
+                ("operators TIME LTIME STEPWIDTH PREV COUNT TREND TRENDNAN PREDICT PREDICTSIGMA PREDICTPERC are not supported with DS COMPUTE");
             free(rpnp);
             return;
         }
@@ -362,6 +363,7 @@ rpnp_t   *rpn_parse(
             match_op(OP_EXC, EXC)
             match_op(OP_POP, POP)
             match_op(OP_LTIME, LTIME)
+            match_op(OP_STEPWIDTH, STEPWIDTH)
             match_op(OP_LT, LT)
             match_op(OP_LE, LE)
             match_op(OP_GT, GT)
@@ -556,6 +558,10 @@ short rpn_calc(
                 }
             }
             break;
+        case OP_STEPWIDTH:
+            rrd_set_error("STEPWIDTH should never show up here... aborting");
+            return -1;
+            break;
         case OP_COUNT:
             rpnstack->s[++stptr] = (output_idx + 1);    /* Note: Counter starts at 1 */
             break;
index 000801019c5d72e0b340b5e119099eace00a464b..e1ebca9af29970b2ce475792c6d0a251ae94ef2c 100644 (file)
@@ -22,7 +22,7 @@ enum op_en { OP_NUMBER = 0, OP_VARIABLE, OP_INF, OP_PREV, OP_NEGINF,
     OP_AVG, OP_ABS, OP_ADDNAN,
     OP_MINNAN, OP_MAXNAN,
     OP_MEDIAN, OP_PREDICTPERC,
-    OP_DEPTH, OP_COPY, OP_ROLL, OP_INDEX
+    OP_DEPTH, OP_COPY, OP_ROLL, OP_INDEX, OP_STEPWIDTH
  };
 
 typedef struct rpnp_t {
@@ -33,7 +33,7 @@ typedef struct rpnp_t {
     long      ds_cnt;   /* data source count for data pointer */
     long      step;     /* time step for OP_VAR das */
     void     *extra;    /* some extra data for longer setups */
-    void      (*free_extra)(void *); /* function pointer used to free extra 
+    void      (*free_extra)(void *); /* function pointer used to free extra
                                      * - NULL for "simple" free(extra); */
 } rpnp_t;
 
index 81fae86c621d8d032bead61d5940de4cd9716de5..a658a1a8469888d8a83891ff7b39dc129822d3be 100644 (file)
@@ -1,5 +1,5 @@
 TESTS = modify1 modify2 modify3 modify4 modify5 \
-       tune1 tune2 rpn1 \
+       tune1 tune2 rpn1 rpn2 \
        rrdcreate \
        dump-restore \
        create-with-source-1 create-with-source-2 create-with-source-3 \
@@ -15,7 +15,7 @@ EXTRA_DIST = Makefile.am \
        rrdcreate \
        tune1-testa-mod1.dump tune1-testa-mod2.dump tune1-testorg.dump \
        tune2-testa-mod1.dump tune2-testorg.dump \
-       valgrind-supressions dcounter1 dcounter1.output vformatter1
+       valgrind-supressions dcounter1 dcounter1.output vformatter1 rpn2.output
 # NB: AM_TESTS_ENVIRONMENT not available until automake 1.12
 TESTS_ENVIRONMENT = \
        BASEDIR=${abs_srcdir} ; export BASEDIR ; \
index e13196a0676d79632cc71b1e6a88b80c83d17807..6db3f57628977ce63e0a217048b8a4b2bb7c14cc 100644 (file)
@@ -12,7 +12,7 @@ DIFF="diff -u"
 DIFF9=seddif
 
 function seddif {
-   sed -e "s/\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\)[0-9]\(e[+-][0-9]\)/\1\2/g" | $DIFF $@
+   perl -p -e 's/([-+]?\d\.\d+e[-+]\d+)/sprintf("%0.10e",$1)/ge' | $DIFF $@
 }
 
 #
diff --git a/tests/rpn2 b/tests/rpn2
new file mode 100755 (executable)
index 0000000..e5d6edf
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+. $(dirname $0)/functions
+
+RRD=rpn2.rrd
+
+$RRDTOOL create $RRD --start 920804400 DS:speed:DCOUNTER:600:U:U RRA:AVERAGE:0.5:1:24 RRA:AVERAGE:0.5:6:10
+report "create"
+$RRDTOOL update $RRD 920804700:10 920805000:20 920805300:30
+$RRDTOOL update $RRD 920805600:40 920805900:50 920806200:60
+$RRDTOOL update $RRD 920806500:70 920806800:80 920807100:90
+$RRDTOOL update $RRD 920807400:100 920807700:110 920808000:120
+$RRDTOOL update $RRD 920808300:130 920808600:140 920808900:150
+report "update"
+$RRDTOOL xport                          \
+      --json \
+      --start 920804400 --end 920808000               \
+      DEF:myspeed=$RRD:speed:AVERAGE              \
+      CDEF:total=myspeed,STEPWIDTH,*,PREV,ADDNAN             \
+      XPORT:myspeed:myspeed XPORT:total:total |\
+ $DIFF9 - $BASEDIR/rpn2.output
+report "xport"
diff --git a/tests/rpn2.output b/tests/rpn2.output
new file mode 100644 (file)
index 0000000..dfe9500
--- /dev/null
@@ -0,0 +1,25 @@
+{ "about": "RRDtool graph JSON output",
+  "meta": {
+    "start": 920804400,
+    "end": 920808000,
+    "step": 300,
+    "legend": [
+      "myspeed",
+      "total"
+          ]
+     },
+  "data": [
+    [ null, null ],
+    [ 3.3333333333e-02, 1.0000000000e+01 ],
+    [ 3.3333333333e-02, 2.0000000000e+01 ],
+    [ 3.3333333333e-02, 3.0000000000e+01 ],
+    [ 3.3333333333e-02, 4.0000000000e+01 ],
+    [ 3.3333333333e-02, 5.0000000000e+01 ],
+    [ 3.3333333333e-02, 6.0000000000e+01 ],
+    [ 3.3333333333e-02, 7.0000000000e+01 ],
+    [ 3.3333333333e-02, 8.0000000000e+01 ],
+    [ 3.3333333333e-02, 9.0000000000e+01 ],
+    [ 3.3333333333e-02, 1.0000000000e+02 ],
+    [ 3.3333333333e-02, 1.1000000000e+02 ]
+  ]
+}