Re: How to create a new Data Type and Consolidation Function?

Long <[email protected]>
Newsgroups gmane.comp.db.rrdtool.devel
Message-ID <[email protected]>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.