From fc97af558e405cfe3bb4192a6db9032e7f3e6d29 Mon Sep 17 00:00:00 2001 From: oetiker Date: Sun, 18 Jun 2006 21:21:56 +0000 Subject: [PATCH] Added AVG function to CDEF language. Martin Sperl martin sperl.org git-svn-id: svn://svn.oetiker.ch/rrdtool/branches/1.2@847 a5681a0c-68f1-0310-ab6d-d61299d08faa --- program/doc/rrdgraph_rpn.pod | 7 +++++++ program/src/rrd_rpncalc.c | 24 ++++++++++++++++++++++++ program/src/rrd_rpncalc.h | 3 ++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/program/doc/rrdgraph_rpn.pod b/program/doc/rrdgraph_rpn.pod index 5000d7a1..6e31ea6d 100644 --- a/program/doc/rrdgraph_rpn.pod +++ b/program/doc/rrdgraph_rpn.pod @@ -139,6 +139,13 @@ Example: C will compute the average of the values v1 to v6 after removing the smallest and largest. +B + +Pop one element (I) from the stack. Now pop I elements and build the +average, ignoring all UNKNOWN values in the process. + +Example: C + B Create a "sliding window" average of another data series. diff --git a/program/src/rrd_rpncalc.c b/program/src/rrd_rpncalc.c index 104ea8f2..3753c0f5 100644 --- a/program/src/rrd_rpncalc.c +++ b/program/src/rrd_rpncalc.c @@ -161,6 +161,7 @@ void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str) add_op(OP_TREND,TREND) add_op(OP_RAD2DEG,RAD2DEG) add_op(OP_DEG2RAD,DEG2RAD) + add_op(OP_AVG,AVG) #undef add_op } (*str)[offset] = '\0'; @@ -338,6 +339,7 @@ rpn_parse(void *key_hash,const char *const expr_const,long (*lookup)(void *,char match_op(OP_TREND,TREND) match_op(OP_RAD2DEG,RAD2DEG) match_op(OP_DEG2RAD,DEG2RAD) + match_op(OP_AVG,AVG) #undef match_op @@ -755,6 +757,28 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, rpnstack -> s[--stptr] = DNAN; } break; + case OP_AVG: + stackunderflow(0); + { + int i=rpnstack -> s[stptr--]; + double sum=0; + int count=0; + stackunderflow(i-1); + while(i>0) { + double val=rpnstack -> s[stptr--]; + i--; + if (isnan(val)) { continue; } + count++; + sum+=val; + } + // now push the result bavk on stack + if (count>0) { + rpnstack -> s[++stptr]=sum/count; + } else { + rpnstack -> s[++stptr]=DNAN; + } + } + break; case OP_END: break; } diff --git a/program/src/rrd_rpncalc.h b/program/src/rrd_rpncalc.h index 94fa31e7..38ba9f81 100644 --- a/program/src/rrd_rpncalc.h +++ b/program/src/rrd_rpncalc.h @@ -17,7 +17,8 @@ enum op_en {OP_NUMBER=0,OP_VARIABLE,OP_INF,OP_PREV,OP_NEGINF, OP_MIN,OP_MAX,OP_LIMIT, OP_FLOOR, OP_CEIL, OP_UN,OP_END,OP_LTIME,OP_NE,OP_ISINF,OP_PREV_OTHER,OP_COUNT, OP_ATAN,OP_SQRT,OP_SORT,OP_REV,OP_TREND, - OP_ATAN2,OP_RAD2DEG,OP_DEG2RAD}; + OP_ATAN2,OP_RAD2DEG,OP_DEG2RAD, + OP_AVG}; typedef struct rpnp_t { enum op_en op; -- 2.30.2