From: Peter Stamfest Date: Thu, 21 Aug 2014 19:37:55 +0000 (+0200) Subject: properly handle DS names - this allows to reorder data sources X-Git-Tag: v1.5.0-rc1~42^2~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f613462c4e21fc5c1c5c9ba069607a6aff10ca29;p=thirdparty%2Frrdtool-1.x.git properly handle DS names - this allows to reorder data sources --- diff --git a/src/rrd_create.c b/src/rrd_create.c index e9a9b810..33fa9c55 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -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; } diff --git a/src/rrd_modify.c b/src/rrd_modify.c index ab7b3d79..1c11e706 100644 --- a/src/rrd_modify.c +++ b/src/rrd_modify.c @@ -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; diff --git a/src/rrd_modify.h b/src/rrd_modify.h index 7cffed97..2d1128e0 100644 --- a/src/rrd_modify.h +++ b/src/rrd_modify.h @@ -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 diff --git a/tests/create-with-source-1 b/tests/create-with-source-1 index 17ea0da3..e847d3df 100755 --- a/tests/create-with-source-1 +++ b/tests/create-with-source-1 @@ -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 { + +#- 1010 +#- 4.0400000000e+04 +#- 0 +#+ U +#+ 0.0000000000e+00 +#+ 40 + + + perl -n -e '$a=join("",<>); $a=~s,<(cdp_prep|last_ds|value|unknown_sec).*?,,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