647
size_t dim_id;
648
size_t dimensions = 0;
649
struct rda_item *rda = rda_base;
650
- total_number collected_total = 0;
651
- total_number last_collected_total = 0;
650
+ NETDATA_DOUBLE collected_total = 0.0;
651
+ NETDATA_DOUBLE last_collected_total = 0.0;
652
rrddim_foreach_read(rd, st) {
653
if(rd_dfe.counter >= rda_slots)
654
break;
664
if(likely(rrddim_check_updated(rd))) {
665
// if the new is smaller than the old (an overflow, or reset), set the old equal to the new
666
// to reset the calculation (it will give zero as the calculation for this second)
667
- if(unlikely(rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL && rd->collector.last_collected_value > rd->collector.collected_value)) {
668
- netdata_log_debug(D_RRD_STATS, "'%s' / '%s': RESET or OVERFLOW. Last collected value = " COLLECTED_NUMBER_FORMAT ", current = " COLLECTED_NUMBER_FORMAT
667
+ if(unlikely(rd->algorithm == RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL && rrddim_last_collected_as_double(rd) > rrddim_collected_as_double(rd))) {
668
+ netdata_log_debug(D_RRD_STATS, "'%s' / '%s': RESET or OVERFLOW. Last collected value = " NETDATA_DOUBLE_FORMAT ", current = " NETDATA_DOUBLE_FORMAT
669
, rrdset_id(st)
670
, rrddim_name(rd)
671
- , rd->collector.last_collected_value
672
- , rd->collector.collected_value
671
+ , rrddim_last_collected_as_double(rd)
672
+ , rrddim_collected_as_double(rd)
673
);
674
675
if(!(rrddim_option_check(rd, RRDDIM_OPTION_DONT_DETECT_RESETS_OR_OVERFLOWS)))
676
rda->reset_or_overflow = true;
677
678
- rd->collector.last_collected_value = rd->collector.collected_value;
678
+ if(rrddim_is_float(rd))
679
+ rrddim_set_last_collected_float(rd, rrddim_collected_as_double(rd));
680
+ else
681
+ rrddim_set_last_collected_int(rd, rd->collector.collected.i.collected_value);
682
}
683
681
- last_collected_total += rd->collector.last_collected_value;
682
- collected_total += rd->collector.collected_value;
684
+ last_collected_total += rrddim_last_collected_as_double(rd);
685
+ collected_total += rrddim_collected_as_double(rd);
686
687
if(unlikely(rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE))) {
688
netdata_log_error("Dimension %s in chart '%s' has the OBSOLETE flag set, but it is collected.", rrddim_name(rd), rrdset_id(st));
715
}
716
717
rrdset_debug(st, "%s: START "
715
- " last_collected_value = " COLLECTED_NUMBER_FORMAT
716
- " collected_value = " COLLECTED_NUMBER_FORMAT
718
+ " last_collected_value = " NETDATA_DOUBLE_FORMAT
719
+ " collected_value = " NETDATA_DOUBLE_FORMAT
720
" last_calculated_value = " NETDATA_DOUBLE_FORMAT
721
" calculated_value = " NETDATA_DOUBLE_FORMAT
722
, rrddim_name(rd)
720
- , rd->collector.last_collected_value
721
- , rd->collector.collected_value
723
+ , rrddim_last_collected_as_double(rd)
724
+ , rrddim_collected_as_double(rd)
725
, rd->collector.last_calculated_value
726
, rd->collector.calculated_value
727
);
728
729
switch(rd->algorithm) {
730
case RRD_ALGORITHM_ABSOLUTE:
728
- rd->collector.calculated_value = (NETDATA_DOUBLE)rd->collector.collected_value
731
+ rd->collector.calculated_value = rrddim_collected_as_double(rd)
732
* (NETDATA_DOUBLE)rd->multiplier
733
/ (NETDATA_DOUBLE)rd->divisor;
734
735
rrdset_debug(st, "%s: CALC ABS/ABS-NO-IN " NETDATA_DOUBLE_FORMAT " = "
733
- COLLECTED_NUMBER_FORMAT
736
+ NETDATA_DOUBLE_FORMAT
737
" * " NETDATA_DOUBLE_FORMAT
738
" / " NETDATA_DOUBLE_FORMAT
739
, rrddim_name(rd)
737
- , rd->collector.calculated_value
738
- , rd->collector.collected_value
740
+ , rd->collector.calculated_value
741
+ , rrddim_collected_as_double(rd)
742
, (NETDATA_DOUBLE)rd->multiplier
743
, (NETDATA_DOUBLE)rd->divisor
744
);
752
// over the total of all dimensions
753
rd->collector.calculated_value =
754
(NETDATA_DOUBLE)100
752
- * (NETDATA_DOUBLE)rd->collector.collected_value
755
+ * rrddim_collected_as_double(rd)
756
/ (NETDATA_DOUBLE)collected_total;
757
758
rrdset_debug(st, "%s: CALC PCENT-ROW " NETDATA_DOUBLE_FORMAT " = 100"
756
- " * " COLLECTED_NUMBER_FORMAT
757
- " / " COLLECTED_NUMBER_FORMAT
759
+ " * " NETDATA_DOUBLE_FORMAT
760
+ " / " NETDATA_DOUBLE_FORMAT
761
, rrddim_name(rd)
762
, rd->collector.calculated_value
760
- , rd->collector.collected_value
761
- , collected_total
763
+ , rrddim_collected_as_double(rd)
764
+ , (NETDATA_DOUBLE)collected_total
765
);
766
break;
767
771
continue;
772
}
773
771
- // If the new is smaller than the old (an overflow, or reset), set the old equal to the new
772
- // to reset the calculation (it will give zero as the calculation for this second).
773
- // It is imperative to set the comparison to uint64_t since type collected_number is signed and
774
- // produces wrong results as far as incremental counters are concerned.
775
- if(unlikely((uint64_t)rd->collector.last_collected_value > (uint64_t)rd->collector.collected_value)) {
776
- netdata_log_debug(D_RRD_STATS, "'%s' / '%s': RESET or OVERFLOW. Last collected value = " COLLECTED_NUMBER_FORMAT ", current = " COLLECTED_NUMBER_FORMAT
777
- , rrdset_id(st)
778
- , rrddim_name(rd)
779
- , rd->collector.last_collected_value
780
- , rd->collector.collected_value);
781
-
782
- if(!(rrddim_option_check(rd, RRDDIM_OPTION_DONT_DETECT_RESETS_OR_OVERFLOWS)))
783
- rda->reset_or_overflow = true;
784
-
785
- uint64_t last = (uint64_t)rd->collector.last_collected_value;
786
- uint64_t new = (uint64_t)rd->collector.collected_value;
787
- uint64_t max = (uint64_t)rd->collector.collected_value_max;
788
- uint64_t cap = 0;
789
-
790
- // Signed values are handled by exploiting two's complement which will produce positive deltas
791
- if (max > 0x00000000FFFFFFFFULL)
792
- cap = 0xFFFFFFFFFFFFFFFFULL; // handles signed and unsigned 64-bit counters
793
- else
794
- cap = 0x00000000FFFFFFFFULL; // handles signed and unsigned 32-bit counters
795
-
796
- uint64_t delta = cap - last + new;
797
- uint64_t max_acceptable_rate = (cap / 100) * MAX_INCREMENTAL_PERCENT_RATE;
798
-
799
- // If the delta is less than the maximum acceptable rate and the previous value was near the cap
800
- // then this is an overflow. There can be false positives such that a reset is detected as an
801
- // overflow.
802
- // TODO: remember recent history of rates and compare with current rate to reduce this chance.
803
- if (delta < max_acceptable_rate) {
774
+ if(rrddim_is_int(rd)) {
775
+ uint64_t last = (uint64_t)rd->collector.collected.i.last_collected_value;
776
+ uint64_t new = (uint64_t)rd->collector.collected.i.collected_value;
777
+ uint64_t max = (uint64_t)rd->collector.collected.i.collected_value_max;
778
+
779
+ // If the new is smaller than the old (overflow/reset), handle wrap
780
+ if(unlikely(last > new)) {
781
+ netdata_log_debug(D_RRD_STATS, "'%s' / '%s': RESET or OVERFLOW. Last collected value = " NETDATA_DOUBLE_FORMAT ", current = " NETDATA_DOUBLE_FORMAT
782
+ , rrdset_id(st)
783
+ , rrddim_name(rd)
784
+ , rrddim_last_collected_as_double(rd)
785
+ , rrddim_collected_as_double(rd));
786
+
787
+ if(!(rrddim_option_check(rd, RRDDIM_OPTION_DONT_DETECT_RESETS_OR_OVERFLOWS)))
788
+ rda->reset_or_overflow = true;
789
+
790
+ uint64_t cap = (max > 0x00000000FFFFFFFFULL) ? 0xFFFFFFFFFFFFFFFFULL : 0x00000000FFFFFFFFULL;
791
+ uint64_t delta = cap - last + new;
792
+ uint64_t max_acceptable_rate = (cap / 100) * MAX_INCREMENTAL_PERCENT_RATE;
793
+
794
+ if (delta < max_acceptable_rate) {
795
+ rd->collector.calculated_value +=
796
+ (NETDATA_DOUBLE) delta
797
+ * (NETDATA_DOUBLE) rd->multiplier
798
+ / (NETDATA_DOUBLE) rd->divisor;
799
+ } else {
800
+ rd->collector.calculated_value += 0;
801
+ }
802
+ }
803
+ else {
804
rd->collector.calculated_value +=
805
- (NETDATA_DOUBLE) delta
805
+ (NETDATA_DOUBLE)((int64_t)(rd->collector.collected.i.collected_value - rd->collector.collected.i.last_collected_value))
806
* (NETDATA_DOUBLE) rd->multiplier
807
/ (NETDATA_DOUBLE) rd->divisor;
808
- } else {
809
- // This is a reset. Any overflow with a rate greater than MAX_INCREMENTAL_PERCENT_RATE will also
810
- // be detected as a reset instead.
811
- rd->collector.calculated_value += (NETDATA_DOUBLE)0;
808
}
809
}
810
else {
815
- rd->collector.calculated_value +=
816
- (NETDATA_DOUBLE) (rd->collector.collected_value - rd->collector.last_collected_value)
817
- * (NETDATA_DOUBLE) rd->multiplier
818
- / (NETDATA_DOUBLE) rd->divisor;
811
+ NETDATA_DOUBLE last = rrddim_last_collected_as_double(rd);
812
+ NETDATA_DOUBLE cur = rrddim_collected_as_double(rd);
813
+ if(unlikely(cur < last)) {
814
+ if(!(rrddim_option_check(rd, RRDDIM_OPTION_DONT_DETECT_RESETS_OR_OVERFLOWS)))
815
+ rda->reset_or_overflow = true;
816
+ rd->collector.calculated_value += 0;
817
+ }
818
+ else {
819
+ rd->collector.calculated_value +=
820
+ (cur - last) * (NETDATA_DOUBLE) rd->multiplier / (NETDATA_DOUBLE) rd->divisor;
821
+ }
822
}
823
824
rrdset_debug(st, "%s: CALC INC PRE " NETDATA_DOUBLE_FORMAT " = ("
822
- COLLECTED_NUMBER_FORMAT " - " COLLECTED_NUMBER_FORMAT
825
+ NETDATA_DOUBLE_FORMAT " - " NETDATA_DOUBLE_FORMAT
826
")"
827
" * " NETDATA_DOUBLE_FORMAT
828
" / " NETDATA_DOUBLE_FORMAT
829
, rrddim_name(rd)
830
, rd->collector.calculated_value
828
- , rd->collector.collected_value, rd->collector.last_collected_value
831
+ , rrddim_collected_as_double(rd), rrddim_last_collected_as_double(rd)
832
, (NETDATA_DOUBLE)rd->multiplier
833
, (NETDATA_DOUBLE)rd->divisor
834
);
847
else
848
rd->collector.calculated_value =
849
(NETDATA_DOUBLE)100
847
- * (NETDATA_DOUBLE)(rd->collector.collected_value - rd->collector.last_collected_value)
850
+ * (NETDATA_DOUBLE)(rrddim_collected_as_double(rd) - rrddim_last_collected_as_double(rd))
851
/ (NETDATA_DOUBLE)(collected_total - last_collected_total);
852
853
rrdset_debug(st, "%s: CALC PCENT-DIFF " NETDATA_DOUBLE_FORMAT " = 100"
851
- " * (" COLLECTED_NUMBER_FORMAT " - " COLLECTED_NUMBER_FORMAT ")"
852
- " / (" COLLECTED_NUMBER_FORMAT " - " COLLECTED_NUMBER_FORMAT ")"
854
+ " * (" NETDATA_DOUBLE_FORMAT " - " NETDATA_DOUBLE_FORMAT ")"
855
+ " / (" NETDATA_DOUBLE_FORMAT " - " NETDATA_DOUBLE_FORMAT ")"
856
, rrddim_name(rd)
857
, rd->collector.calculated_value
855
- , rd->collector.collected_value, rd->collector.last_collected_value
856
- , collected_total, last_collected_total
858
+ , rrddim_collected_as_double(rd), rrddim_last_collected_as_double(rd)
859
+ , (NETDATA_DOUBLE)collected_total, (NETDATA_DOUBLE)last_collected_total
860
);
861
break;
862
873
}
874
875
rrdset_debug(st, "%s: PHASE2 "
873
- " last_collected_value = " COLLECTED_NUMBER_FORMAT
874
- " collected_value = " COLLECTED_NUMBER_FORMAT
876
+ " last_collected_value = " NETDATA_DOUBLE_FORMAT
877
+ " collected_value = " NETDATA_DOUBLE_FORMAT
878
" last_calculated_value = " NETDATA_DOUBLE_FORMAT
879
" calculated_value = " NETDATA_DOUBLE_FORMAT
880
, rrddim_name(rd)
878
- , rd->collector.last_collected_value
879
- , rd->collector.collected_value
881
+ , rrddim_last_collected_as_double(rd)
882
+ , rrddim_collected_as_double(rd)
883
, rd->collector.last_calculated_value
884
, rd->collector.calculated_value
885
);
916
if(unlikely(!rrddim_check_updated(rd)))
917
continue;
918
916
- rrdset_debug(st, "%s: setting last_collected_value (old: " COLLECTED_NUMBER_FORMAT ") to last_collected_value (new: " COLLECTED_NUMBER_FORMAT ")", rrddim_name(rd), rd->collector.last_collected_value, rd->collector.collected_value);
919
+ rrdset_debug(st, "%s: setting last_collected_value (old: " NETDATA_DOUBLE_FORMAT ") to last_collected_value (new: " NETDATA_DOUBLE_FORMAT ")", rrddim_name(rd), rrddim_last_collected_as_double(rd), rrddim_collected_as_double(rd));
920
918
- rd->collector.last_collected_value = rd->collector.collected_value;
921
+ if(rrddim_is_float(rd))
922
+ rrddim_set_last_collected_float(rd, rrddim_collected_as_double(rd));
923
+ else
924
+ rrddim_set_last_collected_int(rd, rd->collector.collected.i.collected_value);
925
926
switch(rd->algorithm) {
927
case RRD_ALGORITHM_INCREMENTAL:
953
}
954
955
rd->collector.calculated_value = 0;
950
- rd->collector.collected_value = 0;
956
+ if(rrddim_is_float(rd))
957
+ rrddim_set_collected_float(rd, 0.0);
958
+ else
959
+ rrddim_set_collected_int(rd, 0);
960
rrddim_clear_updated(rd);
961
962
rrdset_debug(st, "%s: END "
954
- " last_collected_value = " COLLECTED_NUMBER_FORMAT
955
- " collected_value = " COLLECTED_NUMBER_FORMAT
963
+ " last_collected_value = " NETDATA_DOUBLE_FORMAT
964
+ " collected_value = " NETDATA_DOUBLE_FORMAT
965
" last_calculated_value = " NETDATA_DOUBLE_FORMAT
966
" calculated_value = " NETDATA_DOUBLE_FORMAT
967
, rrddim_name(rd)
959
- , rd->collector.last_collected_value
960
- , rd->collector.collected_value
968
+ , rrddim_last_collected_as_double(rd)
969
+ , rrddim_collected_as_double(rd)
970
, rd->collector.last_calculated_value
971
, rd->collector.calculated_value
972
);