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