Hi, I have created a new DST called DIFFERENCE and a new CF called SUM (see the patch file at the end of this post). The patch has been created from the trunk (SVN checkout) and applied to http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.4.4.tar.gz
I have written a very simple test and my patch is not working, it's not adding the differences, all CDP are zeros. Before I dig further, could you tell me if I am on the right track for completely lost? Here's my test result (notice I used the new DST DIFFERENCE and the new CF SUM when creating the RRD file): set -x ; rm -f test_difference_ds_sum_cf.rrd; ./rrdtool create test_difference_ds_sum_cf.rrd --step 60 DS:test_new_ds_cf:DIFFERENCE:120:U:U RRA:SUM:0.5:2:30; ./rrdtool info test_difference_ds_sum_cf.rrd; NOW=`date +%s`; for i in `seq 5`; do TIME_DELTA=`expr $i \* 60`; NEW_VAL=`expr $TIME_DELTA + $NOW`; ./rrdtool update test_difference_ds_sum_cf.rrd $NEW_VAL:$NEW_VAL; done; ./rrdtool fetch test_difference_ds_sum_cf.rrd SUM --start $NOW --end $NEW_VAL; set +x + rm -i -f test_difference_ds_sum_cf.rrd + ./rrdtool create test_difference_ds_sum_cf.rrd --step 60 DS:test_new_ds_cf:DIFFERENCE:120:U:U RRA:SUM:0.5:2:30 + ./rrdtool info test_difference_ds_sum_cf.rrd filename = "test_difference_ds_sum_cf.rrd" rrd_version = "0003" step = 60 last_update = 1296894230 header_size = 592 ds[test_new_ds_cf].index = 0 ds[test_new_ds_cf].type = "DIFFERENCE" ds[test_new_ds_cf].minimal_heartbeat = 120 ds[test_new_ds_cf].min = NaN ds[test_new_ds_cf].max = NaN ds[test_new_ds_cf].last_ds = "U" ds[test_new_ds_cf].value = 0.0000000000e+00 ds[test_new_ds_cf].unknown_sec = 50 rra[0].cf = "SUM" rra[0].rows = 30 rra[0].cur_row = 17 rra[0].pdp_per_row = 2 rra[0].xff = 5.0000000000e-01 rra[0].cdp_prep[0].value = NaN rra[0].cdp_prep[0].unknown_datapoints = 1 ++ date +%s + NOW=1296894240 ++ seq 5 + for i in '`seq 5`' ++ expr 1 '*' 60 + TIME_DELTA=60 ++ expr 60 + 1296894240 + NEW_VAL=1296894300 + ./rrdtool update test_difference_ds_sum_cf.rrd 1296894300:1296894300 + for i in '`seq 5`' ++ expr 2 '*' 60 + TIME_DELTA=120 ++ expr 120 + 1296894240 + NEW_VAL=1296894360 + ./rrdtool update test_difference_ds_sum_cf.rrd 1296894360:1296894360 + for i in '`seq 5`' ++ expr 3 '*' 60 + TIME_DELTA=180 ++ expr 180 + 1296894240 + NEW_VAL=1296894420 + ./rrdtool update test_difference_ds_sum_cf.rrd 1296894420:1296894420 + for i in '`seq 5`' ++ expr 4 '*' 60 + TIME_DELTA=240 ++ expr 240 + 1296894240 + NEW_VAL=1296894480 + ./rrdtool update test_difference_ds_sum_cf.rrd 1296894480:1296894480 + for i in '`seq 5`' ++ expr 5 '*' 60 + TIME_DELTA=300 ++ expr 300 + 1296894240 + NEW_VAL=1296894540 + ./rrdtool update test_difference_ds_sum_cf.rrd 1296894540:1296894540 + ./rrdtool fetch test_difference_ds_sum_cf.rrd SUM --start 1296894240 --end 1296894540 test_new_ds_cf 1296894360: 0.0000000000e+00 1296894480: 0.0000000000e+00 1296894600: nan + set +x Here's my patch file. Thanks ! diff -Naur rrdtool-trunk-original/src/rrd_create.c rrdtool-trunk/src/rrd_create.c --- rrdtool-trunk-original/src/rrd_create.c 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_create.c 2011-02-04 15:34:56.000000000 -0500 @@ -252,6 +252,7 @@ /* parse the remainder of the arguments */ switch (dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst)) { case DST_COUNTER: + case DST_DIFFERENCE: case DST_ABSOLUTE: case DST_GAUGE: case DST_DERIVE: diff -Naur rrdtool-trunk-original/src/rrd_dump.c rrdtool-trunk/src/rrd_dump.c --- rrdtool-trunk-original/src/rrd_dump.c 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_dump.c 2011-02-04 15:38:43.000000000 -0500 @@ -271,6 +271,7 @@ case CF_MAXIMUM: case CF_MINIMUM: case CF_LAST: + case CF_SUM: default: CB_FMTS("\t\t<xff>%0.10e</xff>\n", rrd.rra_def[i].par[RRA_cdp_xff_val].u_val); @@ -390,6 +391,7 @@ case CF_MAXIMUM: case CF_MINIMUM: case CF_LAST: + case CF_SUM: default: value = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_val].u_val; if (isnan(value)) { diff -Naur rrdtool-trunk-original/src/rrd_format.c rrdtool-trunk/src/rrd_format.c --- rrdtool-trunk-original/src/rrd_format.c 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_format.c 2011-02-04 14:46:57.000000000 -0500 @@ -61,6 +61,7 @@ converter(GAUGE, DST_GAUGE) converter(DERIVE, DST_DERIVE) converter(COMPUTE, DST_CDEF) + converter(DIFFERENCE, DST_DIFFERENCE) rrd_set_error("unknown data acquisition function '%s'", string); return (enum dst_en)(-1); } @@ -80,6 +81,7 @@ converter(SEASONAL, CF_SEASONAL) converter(DEVSEASONAL, CF_DEVSEASONAL) converter(FAILURES, CF_FAILURES) + converter(SUM, CF_SUM) rrd_set_error("unknown consolidation function '%s'", string); return (enum cf_en)(-1); } @@ -98,6 +100,7 @@ case CF_DEVSEASONAL: return "DEVSEASONAL"; case CF_FAILURES: return "FAILURES"; case CF_MHWPREDICT: return "MHWPREDICT"; + case CF_SUM: return "SUM"; default: return NULL; diff -Naur rrdtool-trunk-original/src/rrd_format.h rrdtool-trunk/src/rrd_format.h --- rrdtool-trunk-original/src/rrd_format.h 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_format.h 2011-02-04 14:51:01.000000000 -0500 @@ -138,6 +138,7 @@ DST_ABSOLUTE, DST_GAUGE, DST_DERIVE, + DST_DIFFERENCE, DST_CDEF }; @@ -192,8 +193,9 @@ * */ CF_FAILURES, /* HWPREDICT that follows a moving baseline */ - CF_MHWPREDICT + CF_MHWPREDICT, /* new entries must come last !!! */ + CF_SUM }; /* A binary array of failure indicators: 1 indicates diff -Naur rrdtool-trunk-original/src/rrd_graph.c rrdtool-trunk/src/rrd_graph.c --- rrdtool-trunk-original/src/rrd_graph.c 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_graph.c 2011-02-05 13:22:37.000000000 -0500 @@ -749,6 +749,7 @@ case CF_DEVSEASONAL: case CF_DEVPREDICT: case CF_SEASONAL: + case CF_SUM: case CF_AVERAGE: newval += srcptr[i * (*ds_cnt) + col]; break; @@ -782,6 +783,7 @@ case CF_FAILURES: case CF_MAXIMUM: case CF_LAST: + case CF_SUM: break; } } @@ -1567,8 +1569,11 @@ case CF_DEVPREDICT: case CF_DEVSEASONAL: case CF_SEASONAL: + case CF_SUM: case CF_AVERAGE: - validsteps++; + if ( CF_SUM != im->gdes[i].cf ) { + validsteps++; + } printval += im->gdes[vidx].data[ii]; break; case CF_MINIMUM: @@ -4901,6 +4906,8 @@ gdes->vf.op = VDEF_MAXIMUM; else if (!strcmp("AVERAGE", func)) gdes->vf.op = VDEF_AVERAGE; + else if (!strcmp("SUM", func)) + gdes->vf.op = VDEF_SUM; else if (!strcmp("STDEV", func)) gdes->vf.op = VDEF_STDEV; else if (!strcmp("MINIMUM", func)) @@ -4945,6 +4952,7 @@ break; case VDEF_MAXIMUM: case VDEF_AVERAGE: + case VDEF_SUM: case VDEF_STDEV: case VDEF_MINIMUM: case VDEF_TOTAL: @@ -5067,6 +5075,7 @@ break; case VDEF_TOTAL: case VDEF_STDEV: + case VDEF_SUM: case VDEF_AVERAGE:{ int cnt = 0; double sum = 0.0; @@ -5079,7 +5088,7 @@ }; } if (cnt) { - if (dst->vf.op == VDEF_TOTAL) { + if (dst->vf.op == VDEF_TOTAL || dst->vf.op == VDEF_SUM) { dst->vf.val = sum * src->step; dst->vf.when = 0; /* no time component */ dst->vf.never = 1; diff -Naur rrdtool-trunk-original/src/rrd_graph.h rrdtool-trunk/src/rrd_graph.h --- rrdtool-trunk-original/src/rrd_graph.h 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_graph.h 2011-02-04 16:06:07.000000000 -0500 @@ -70,6 +70,7 @@ , VDEF_STDEV /* the standard deviation */ , VDEF_PERCENT /* Nth percentile */ , VDEF_TOTAL /* average multiplied by time */ + , VDEF_SUM /* average multiplied by time */ , VDEF_FIRST /* first non-unknown value and time */ , VDEF_LAST /* last non-unknown value and time */ , VDEF_LSLSLOPE /* least squares line slope */ diff -Naur rrdtool-trunk-original/src/rrd_update.c rrdtool-trunk/src/rrd_update.c --- rrdtool-trunk-original/src/rrd_update.c 2011-02-05 13:23:01.000000000 -0500 +++ rrdtool-trunk/src/rrd_update.c 2011-02-04 23:07:13.000000000 -0500 @@ -1131,6 +1131,9 @@ } rate = pdp_new[ds_idx] / interval; break; + case DST_DIFFERENCE: + pdp_new[ds_idx] = pdp_new[ds_idx] * interval; + break; default: rrd_set_error("rrd contains unknown DS type : '%s'", rrd->ds_def[ds_idx].dst); @@ -1664,12 +1667,16 @@ rrd_value_t cum_val, cur_val; switch (current_cf) { + case CF_SUM: case CF_AVERAGE: cum_val = IFDNAN(scratch[CDP_val].u_val, 0.0); cur_val = IFDNAN(pdp_temp_val, 0.0); scratch[CDP_primary_val].u_val = - (cum_val + cur_val * start_pdp_offset) / + (cum_val + cur_val * start_pdp_offset); + if ( current_cf == CF_AVERAGE ) { + scratch[CDP_primary_val].u_val /= (pdp_cnt - scratch[CDP_unkn_pdp_cnt].u_cnt); + } break; case CF_MAXIMUM: cum_val = IFDNAN(scratch[CDP_val].u_val, -DINF); @@ -1786,6 +1793,7 @@ return -DINF; case CF_MINIMUM: return DINF; + case CF_SUM: case CF_AVERAGE: return 0; default: @@ -1794,6 +1802,7 @@ } else { switch (current_cf) { + case CF_SUM: case CF_AVERAGE: return pdp_temp_val * pdp_into_cdp_cnt ; default: @@ -1823,7 +1832,7 @@ ) { if (isnan(cdp_val)) { - if (current_cf == CF_AVERAGE) { + if (current_cf == CF_AVERAGE || current_cf == CF_SUM) { pdp_temp_val *= elapsed_pdp_st; } #ifdef DEBUG @@ -1832,7 +1841,7 @@ #endif return pdp_temp_val; } - if (current_cf == CF_AVERAGE) + if (current_cf == CF_AVERAGE || current_cf == CF_SUM) return cdp_val + pdp_temp_val * elapsed_pdp_st; if (current_cf == CF_MINIMUM) return (pdp_temp_val < cdp_val) ? pdp_temp_val : cdp_val; -- View this message in context: http://rrd-mailinglists.937164.n2.nabble.com/How-to-create-a-new-Data-Type-and-Consolidation-Function-tp5990330p5996203.html Sent from the RRDtool Developers Mailinglist mailing list archive at Nabble.com. _______________________________________________ rrd-developers mailing list rrd-developers@lists.oetiker.ch https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers