]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
properly handle DS names - this allows to reorder data sources
authorPeter Stamfest <peter@stamfest.at>
Thu, 21 Aug 2014 19:37:55 +0000 (21:37 +0200)
committerPeter Stamfest <peter@stamfest.at>
Sun, 31 Aug 2014 20:19:22 +0000 (22:19 +0200)
src/rrd_create.c
src/rrd_modify.c
src/rrd_modify.h
tests/create-with-source-1

index e9a9b81076932e0f12fab48dae00178686426f4a..33fa9c55b6b749aa6c903f48d9e66e672ffa3f36 100644 (file)
@@ -1243,14 +1243,13 @@ static int rrd_prefill_data(rrd_t *rrd, const GList *sources) {
                 fprintf(stderr, "src rrd last_up %ld\n", src_rrd->live_head->last_up);
                 fprintf(stderr, "dst rrd last_up %ld\n", rrd->live_head->last_up);
                 
-                int found_ds_index = -1;
                 for (sj = 0 ; sj < src_rrd->stat_head->ds_cnt ; sj++) {
                     if (strcmp(ds_def->ds_nam, src_rrd->ds_def[sj].ds_nam) == 0) {
                         // name match!!!
-                        found_ds_index = sj;
                         
+                        candidate_extra_t extra = { .l = sj };
                         // candidates = g_list_append(candidates, (gpointer) src);
-                        candidates = find_candidate_rras(src_rrd, rra_def, &candidate_cnt);
+                        candidates = find_candidate_rras(src_rrd, rra_def, &candidate_cnt, extra);
                         
 for (unsigned int tt = 0 ; tt < src_rrd->stat_head->rra_cnt ; tt++) {
     fprintf(stderr, "SRC RRA %d row_cnt=%ld\n", tt, src_rrd->rra_def[tt].row_cnt);
@@ -1308,16 +1307,16 @@ for (int tt = 0 ; tt < candidate_cnt ; tt++) {
                             
                             long covered = overlap(bin_start_time, bin_end_time,
                                                    cand_bin_start_time, cand_bin_end_time) +1;
-                            rrd_value_t v = candidate->values[ci * candidate->rrd->stat_head->ds_cnt + j];
+                            rrd_value_t v = candidate->values[ci * candidate->rrd->stat_head->ds_cnt + candidate->extra.l];
                             if (covered > 0 && v != NAN) {
                                 total_covered += covered;
                                 covering_bins++;
                                 
                                 value += v / cand_bin_size * covered;
                             }
-                            fprintf(stderr, "  covers from %ld to %ld overlap is %g value=%g\n",
+                            fprintf(stderr, "  covers from %ld to %ld overlap is %g value=%g (ds #%d)\n",
                                         cand_bin_start_time, cand_bin_end_time,
-                                        (float) covered / bin_size, v);
+                                        (float) covered / bin_size, v, candidate->extra.l);
                         }
                         fprintf(stderr, "total coverage=%ld/%ld from %ld bins\n", total_covered, bin_size, covering_bins);
                         
@@ -1397,12 +1396,6 @@ time_t end_time_for_row(const rrd_t *rrd,
     time_t last_up = rrd->live_head->last_up;
     time_t now = (last_up - last_up % timeslot) - past_cnt * timeslot;
 
-    
-        fprintf(stderr, "ETFR %012lx, %012lx, cr=%d, r=%d, ts=%d, pc=%d, lu=%ld = %ld\n", 
-                rrd, rra, cur_row, row,
-                timeslot, past_cnt, last_up, now);
-    
-
     return now;
 }
 
index ab7b3d79091664ebe7e3eca6db157b37c96be032..1c11e7066ba37107865f43aade1e61a417be4307 100644 (file)
@@ -77,7 +77,8 @@ static int sort_candidates(const void *va, const void *vb) {
     return a_def->pdp_cnt - b_def->pdp_cnt;
 }
 
-candidate_t *find_candidate_rras(const rrd_t *rrd, const rra_def_t *rra, int *cnt) {
+candidate_t *find_candidate_rras(const rrd_t *rrd, const rra_def_t *rra, int *cnt, 
+                                 candidate_extra_t extra) {
     int total_rows = 0;
     candidate_t *candidates = NULL;
     *cnt = 0;
@@ -106,6 +107,7 @@ candidate_t *find_candidate_rras(const rrd_t *rrd, const rra_def_t *rra, int *cn
                c.rra = rrd->rra_def + i;
                c.ptr = rrd->rra_ptr + i;
                c.cdp = rrd->cdp_prep + rrd->stat_head->ds_cnt * i;
+                memcpy(&c.extra, &extra, sizeof(extra));
 #else
            candidate_t c = { 
                .rrd = rrd, 
@@ -113,10 +115,11 @@ candidate_t *find_candidate_rras(const rrd_t *rrd, const rra_def_t *rra, int *cn
                .values = rrd->rrd_value + rrd->stat_head->ds_cnt * total_rows,
                .rra = rrd->rra_def + i,
                .ptr = rrd->rra_ptr + i,
-               .cdp = rrd->cdp_prep + rrd->stat_head->ds_cnt * i       
+               .cdp = rrd->cdp_prep + rrd->stat_head->ds_cnt * i,
+               .extra = extra
            };
 #endif
-               candidates = (candidate_t *) copy_over_realloc(candidates, *cnt,
+            candidates = (candidate_t *) copy_over_realloc(candidates, *cnt,
                                           &c, 0, sizeof(c));
            if (candidates == NULL) {
                rrd_set_error("out of memory");
@@ -421,8 +424,9 @@ static int populate_row(const rrd_t *in_rrd,
     int candidates_cnt = 0;
 
     int i, ri;
-
-    candidates = find_candidate_rras(in_rrd, new_rra, &candidates_cnt);
+    candidate_extra_t junk;
+    
+    candidates = find_candidate_rras(in_rrd, new_rra, &candidates_cnt, junk);
     if (candidates == NULL) {
        goto done;
     }
@@ -1012,13 +1016,14 @@ static void prepare_CDPs(const rrd_t *in, rrd_t *out,
     int candidates_cnt = 0;
     candidate_t *candidates = NULL;
     candidate_t *chosen_candidate = NULL;
-
+    candidate_extra_t junk;
+    
     if (candidates) {
        free(candidates);
        candidates = NULL;
     }
 
-    candidates = find_candidate_rras(in, rra_def, &candidates_cnt);
+    candidates = find_candidate_rras(in, rra_def, &candidates_cnt, junk);
 
     if (candidates != NULL) {
        int ci;
index 7cffed971f2e3b3c37221c6ab2b6f0cb2cc225d5..2d1128e0c5dbcba5eb25f09283fc62e9c0158655 100644 (file)
@@ -31,6 +31,12 @@ int handle_modify(const rrd_t *in, const char *outfilename,
                  int argc, char **argv, int optind,
                  int newstep);
 
+typedef union {
+       long l;
+       unsigned long ul;
+       void *vp;
+} candidate_extra_t;
+
 typedef struct {
     const rrd_t *rrd;
     int rra_index;
@@ -38,6 +44,7 @@ typedef struct {
     rra_def_t *rra;
     rra_ptr_t *ptr;
     cdp_prep_t *cdp;
+    candidate_extra_t extra;
 } candidate_t;
 
 /* 
@@ -58,7 +65,8 @@ typedef struct {
    rra .. the RRA we want to populate
    cnt .. a pointer to an int receiving the number of returned candidates
 */
-candidate_t *find_candidate_rras(const rrd_t *rrd, const rra_def_t *rra, int *cnt);
+candidate_t *find_candidate_rras(const rrd_t *rrd, const rra_def_t *rra, int *cnt,
+                                candidate_extra_t extra);
 
 #endif
 
index 17ea0da3b31d837fc61abcb9779b5daf07a9db1b..e847d3dfe2c60a5c9e47a257c391170c36228ec9 100755 (executable)
@@ -5,6 +5,22 @@
 BASE=$BASEDIR/$(basename $0)-test
 BUILD=$BUILDDIR/$(basename $0)-test
 
+# currently, we do not properly copy cdp and pdp information, so for
+# comparison of RRD dumps, we just filter out those parts we do not
+# expect to match anyway...
+function xmlfilter {
+
+#-               <last_ds>1010</last_ds>
+#-               <value>4.0400000000e+04</value>
+#-               <unknown_sec> 0 </unknown_sec>
+#+               <last_ds>U</last_ds>
+#+               <value>0.0000000000e+00</value>
+#+               <unknown_sec> 40 </unknown_sec>
+
+
+       perl -n -e '$a=join("",<>); $a=~s,<(cdp_prep|last_ds|value|unknown_sec).*?</\1>,,msg ; print $a'
+}
+
 # create 2 RRDs only differing in the way that the second contains an additional RRA
 # test: remove the additional RRA from the second and compare dumps
 # test: add the additional RRA to the first and compare dumps 
@@ -26,5 +42,38 @@ $RRDTOOL update ${BUILD}a1.rrd  $UPDATE
 $RRDTOOL create ${BUILD}a2.rrd --start $ST --step 60 --source ${BUILD}a1.rrd DS:a:GAUGE:120:0:U  RRA:AVERAGE:0.5:1:100 RRA:AVERAGE:0.5:5:2 RRA:MIN:0.5:5:2 RRA:MAX:0.5:5:2 RRA:LAST:0.5:5:2 
 report create-with-source-1
 
+$RRDTOOL dump ${BUILD}a1.rrd | xmlfilter > ${BUILD}a1.xml
+$RRDTOOL dump ${BUILD}a2.rrd | xmlfilter > ${BUILD}a2.xml
+$DIFF ${BUILD}a1.xml ${BUILD}a2.xml
+report data-match
+
 $RRDTOOL create ${BUILD}a3.rrd --start $ST --step 60 --source ${BUILD}a2.rrd DS:a:GAUGE:120:0:U  RRA:AVERAGE:0.5:1:100 RRA:AVERAGE:0.5:5:2 RRA:MIN:0.5:5:2 RRA:MAX:0.5:5:2 RRA:LAST:0.5:5:2 
-report create-with-source-2
+$RRDTOOL dump ${BUILD}a3.rrd | xmlfilter > ${BUILD}a3.xml
+$DIFF ${BUILD}a1.xml ${BUILD}a3.xml
+report data-match-again
+
+$RRDTOOL create ${BUILD}a4.rrd --start $ST --step 60 --source ${BUILD}a2.rrd DS:b:GAUGE:120:0:U DS:a:GAUGE:120:0:U  RRA:AVERAGE:0.5:1:100 RRA:AVERAGE:0.5:5:2 RRA:MIN:0.5:5:2 RRA:MAX:0.5:5:2 RRA:LAST:0.5:5:2 
+report create-with-source-effectively-adding-DS
+
+UPDATE=
+ST=$(($ST + 60))
+for A in $(seq $ST 60 $(($ST + 3000)) ) ; do
+       UPDATE="$UPDATE $A:$V:$((2 * $V))"
+       V=$(($V + 20))
+       ST=$A
+done
+
+$RRDTOOL update ${BUILD}a4.rrd --template a:b $UPDATE
+report update-with-two-data-sources
+
+# now swap the two data sources
+$RRDTOOL create ${BUILD}a5.rrd --start $ST --step 60 --source ${BUILD}a4.rrd DS:a:GAUGE:120:0:U DS:b:GAUGE:120:0:U  RRA:AVERAGE:0.5:1:100 RRA:AVERAGE:0.5:5:2 RRA:MIN:0.5:5:2 RRA:MAX:0.5:5:2 RRA:LAST:0.5:5:2 
+
+# and swap the two data sources back, so we can then compare the outputs....
+$RRDTOOL create ${BUILD}a6.rrd --start $ST --step 60 --source ${BUILD}a5.rrd DS:b:GAUGE:120:0:U DS:a:GAUGE:120:0:U  RRA:AVERAGE:0.5:1:100 RRA:AVERAGE:0.5:5:2 RRA:MIN:0.5:5:2 RRA:MAX:0.5:5:2 RRA:LAST:0.5:5:2 
+# now a4 and a6 must match....
+
+$RRDTOOL dump ${BUILD}a4.rrd | xmlfilter > ${BUILD}a4.xml
+$RRDTOOL dump ${BUILD}a6.rrd | xmlfilter > ${BUILD}a6.xml
+$DIFF ${BUILD}a4.xml ${BUILD}a6.xml
+report data-match-after-swap