@cryptotaxi247 / netdata-1 / commits / 4fd1f55a6

fixed interpolation spikes on incremental values

Costa Tsaousis (ktsaou) committed Jan 21, 2016 at 21:39 UTC 4fd1f55a6bfbc3289971d85662bc8da7bcef77c1
2 files changed +59 -34
src/rrd.c
+23 -34
@@ -820,8 +820,8 @@ unsigned long long rrdset_done(RRDSET *st)
820 debug(D_RRD_CALLS, "rrdset_done() for chart %s", st->name);
821
822 RRDDIM *rd, *last;
823 - int oldstate, store_this_entry = 1, first_entry = 0, in_the_same_interpolation_point = 0;
824 - unsigned long long last_ut, now_ut, next_ut;
823 + int oldstate, store_this_entry = 1, first_entry = 0;
824 + unsigned long long last_ut, now_ut, next_ut, stored_entries = 0;
825
826 if(unlikely(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0))
827 error("Cannot set pthread cancel state to DISABLE.");
@@ -905,7 +905,6 @@ unsigned long long rrdset_done(RRDSET *st)
905
906 if(unlikely(!first_entry && now_ut < next_ut)) {
907 if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: THIS IS IN THE SAME INTERPOLATION POINT", st->name);
908 - in_the_same_interpolation_point = 1;
908 }
909
910 if(unlikely(st->debug)) {
@@ -1004,10 +1003,6 @@ unsigned long long rrdset_done(RRDSET *st)
1003 rd->last_collected_value = rd->collected_value;
1004 }
1005
1007 - if(!in_the_same_interpolation_point) {
1008 - rd->last_calculated_value = rd->calculated_value;
1009 - }
1010 -
1006 rd->calculated_value = (calculated_number)(rd->collected_value - rd->last_collected_value)
1007 * (calculated_number)rd->multiplier
1008 / (calculated_number)rd->divisor;
@@ -1041,10 +1036,6 @@ unsigned long long rrdset_done(RRDSET *st)
1036 * (calculated_number)(rd->collected_value - rd->last_collected_value)
1037 / (calculated_number)(st->collected_total - st->last_collected_total);
1038
1044 - if(!in_the_same_interpolation_point) {
1045 - rd->last_calculated_value = rd->calculated_value;
1046 - }
1047 -
1039 if(unlikely(st->debug))
1040 debug(D_RRD_STATS, "%s/%s: CALC PCENT-DIFF "
1041 CALCULATED_NUMBER_FORMAT " = 100"
@@ -1071,7 +1062,7 @@ unsigned long long rrdset_done(RRDSET *st)
1062 break;
1063 }
1064
1074 - if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: END "
1065 + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: PHASE2 "
1066 " last_collected_value = " COLLECTED_NUMBER_FORMAT
1067 " collected_value = " COLLECTED_NUMBER_FORMAT
1068 " last_calculated_value = " CALCULATED_NUMBER_FORMAT
@@ -1094,7 +1085,7 @@ unsigned long long rrdset_done(RRDSET *st)
1085
1086 for( ; likely(next_ut <= now_ut) ; next_ut += st->update_every * 1000000ULL, iterations-- ) {
1087 #ifdef NETDATA_INTERNAL_CHECKS
1097 - if(iterations <= 0) { error("iterations calculation wrapped!"); }
1088 + if(iterations <= 0) { error("iterations calculation wrapped! first_ut = %llu, last_ut = %llu, next_ut = %llu, now_ut = %llu", first_ut, last_ut, next_ut, now_ut); }
1089 #endif
1090
1091 if(unlikely(st->debug)) {
@@ -1203,6 +1194,8 @@ unsigned long long rrdset_done(RRDSET *st)
1194 rd->values[st->current_entry] = pack_storage_number(0, SN_NOT_EXISTS);
1195 }
1196
1197 + stored_entries++;
1198 +
1199 if(unlikely(st->debug)) {
1200 calculated_number t1 = new_value * (calculated_number)rd->multiplier / (calculated_number)rd->divisor;
1201 calculated_number t2 = unpack_storage_number(rd->values[st->current_entry]);
@@ -1240,41 +1233,37 @@ unsigned long long rrdset_done(RRDSET *st)
1233 }
1234
1235 // align next interpolation to last collection point
1243 - st->last_updated.tv_sec = st->last_collected_time.tv_sec;
1244 - st->last_updated.tv_usec = st->last_collected_time.tv_usec;
1236 + if(likely(stored_entries || !store_this_entry)) {
1237 + st->last_updated.tv_sec = st->last_collected_time.tv_sec;
1238 + st->last_updated.tv_usec = st->last_collected_time.tv_usec;
1239 + }
1240
1241 for( rd = st->dimensions; likely(rd) ; rd = rd->next ) {
1242 if(unlikely(!rd->updated)) continue;
1243
1249 - int is_incremental = 0;
1250 - if(rd->algorithm == RRDDIM_PCENT_OVER_DIFF_TOTAL || rd->algorithm == RRDDIM_INCREMENTAL)
1251 - is_incremental = 1;
1252 -
1253 - if((is_incremental && !in_the_same_interpolation_point) || !is_incremental || !store_this_entry) {
1244 + if(likely(stored_entries || !store_this_entry)) {
1245 if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: setting last_collected_value (old: " COLLECTED_NUMBER_FORMAT ") to last_collected_value (new: " COLLECTED_NUMBER_FORMAT ")", st->id, rd->name, rd->last_collected_value, rd->collected_value);
1246 rd->last_collected_value = rd->collected_value;
1247
1248 if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: setting last_calculated_value (old: " CALCULATED_NUMBER_FORMAT ") to last_calculated_value (new: " CALCULATED_NUMBER_FORMAT ")", st->id, rd->name, rd->last_calculated_value, rd->calculated_value);
1249 rd->last_calculated_value = rd->calculated_value;
1250 }
1260 - else {
1261 - if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: discarding calculated_value (old: " CALCULATED_NUMBER_FORMAT ") new: 0", st->id, rd->name, rd->calculated_value);
1262 - rd->calculated_value = 0;
1263 - }
1251
1252 + rd->calculated_value = 0;
1253 rd->collected_value = 0;
1254 rd->updated = 0;
1255
1268 - // if this is the first entry of incremental dimensions
1269 - // we have to set the first calculated_value to zero
1270 - // to eliminate the first spike
1271 - if(unlikely(st->counter_done == 1)) switch(rd->algorithm) {
1272 - case RRDDIM_PCENT_OVER_DIFF_TOTAL:
1273 - case RRDDIM_INCREMENTAL:
1274 - rd->calculated_value = 0;
1275 - // the next time, a new incremental total will be calculated
1276 - break;
1277 - }
1256 + if(unlikely(st->debug)) debug(D_RRD_STATS, "%s/%s: END "
1257 + " last_collected_value = " COLLECTED_NUMBER_FORMAT
1258 + " collected_value = " COLLECTED_NUMBER_FORMAT
1259 + " last_calculated_value = " CALCULATED_NUMBER_FORMAT
1260 + " calculated_value = " CALCULATED_NUMBER_FORMAT
1261 + , st->id, rd->name
1262 + , rd->last_collected_value
1263 + , rd->collected_value
1264 + , rd->last_calculated_value
1265 + , rd->calculated_value
1266 + );
1267 }
1268 st->last_collected_total = st->collected_total;
1269
src/unit_test.c
+36
@@ -571,6 +571,39 @@ struct test test9 = {
571 test9_results // results
572 };
573
574 +// --------------------------------------------------------------------------------------------------------------------
575 +// test10
576 +
577 +struct feed_values test10_feed[] = {
578 + { 500000, 1000 },
579 + { 600000, 1000 + 600 },
580 + { 200000, 1600 + 200 },
581 + { 1000000, 1800 + 1000 },
582 + { 200000, 2800 + 200 },
583 + { 2000000, 3000 + 2000 },
584 + { 600000, 5000 + 600 },
585 + { 400000, 5600 + 400 },
586 + { 900000, 6000 + 900 },
587 + { 1000000, 6900 + 1000 },
588 +};
589 +
590 +calculated_number test10_results[] = {
591 + 500, 1000, 1000, 1000, 1000, 1000, 1000
592 +};
593 +
594 +struct test test10 = {
595 + "test10", // name
596 + "test incremental values updated in short and long durations",
597 + 1, // update_every
598 + 1, // multiplier
599 + 1, // divisor
600 + RRDDIM_INCREMENTAL, // algorithm
601 + 10, // feed entries
602 + 7, // result entries
603 + test10_feed, // feed
604 + test10_results // results
605 +};
606 +
607 // --------------------------------------------------------------------------------------------------------------------
608
609 int run_test(struct test *test)
@@ -658,6 +691,9 @@ int run_all_mockup_tests(void)
691 if(run_test(&test9))
692 return 1;
693
694 + if(run_test(&test10))
695 + return 1;
696 +
697 return 0;
698 }
699