diff options
author | Costa Tsaousis <costa@tsaousis.gr> | 2018-11-04 21:53:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-04 21:53:19 +0200 |
commit | 36199f449852f8077ea915a3a14a33fa2aff6d85 (patch) | |
tree | 32ec6bf604b074da7218b56e53efc54a82c64094 /libnetdata | |
parent | 839d1488571623413aad7ba2019c0437a4f980c4 (diff) |
incremental overflows should not show zeros values (#4538)
* incremental overflows do not show zeros; fixes #4533
* use the max per metric per session for detecting counter size
Diffstat (limited to 'libnetdata')
-rw-r--r-- | libnetdata/storage_number/storage_number.c | 59 | ||||
-rw-r--r-- | libnetdata/storage_number/storage_number.h | 30 |
2 files changed, 50 insertions, 39 deletions
diff --git a/libnetdata/storage_number/storage_number.c b/libnetdata/storage_number/storage_number.c index db4cb700b4..6825fa7d03 100644 --- a/libnetdata/storage_number/storage_number.c +++ b/libnetdata/storage_number/storage_number.c @@ -2,19 +2,20 @@ #include "../libnetdata.h" -storage_number pack_storage_number(calculated_number value, uint32_t flags) -{ +storage_number pack_storage_number(calculated_number value, uint32_t flags) { // bit 32 = sign 0:positive, 1:negative // bit 31 = 0:divide, 1:multiply // bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total) - // bit 27, 26, 25 flags + // bit 27 SN_EXISTS_100 + // bit 26 SN_EXISTS_RESET + // bit 25 SN_EXISTS // bit 24 to bit 1 = the value storage_number r = get_storage_number_flags(flags); if(!value) return r; int m = 0; - calculated_number n = value; + calculated_number n = value, factor = 10; // if the value is negative // add the sign bit and make it positive @@ -23,11 +24,16 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) n = -n; } + if(n / 10000000.0 > 0x00ffffff) { + factor = 100; + r |= SN_EXISTS_100; + } + // make its integer part fit in 0x00ffffff // by dividing it by 10 up to 7 times // and increasing the multiplier while(m < 7 && n > (calculated_number)0x00ffffff) { - n /= 10; + n /= factor; m++; } @@ -71,35 +77,44 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) return r; } -calculated_number unpack_storage_number(storage_number value) -{ +calculated_number unpack_storage_number(storage_number value) { if(!value) return 0; int sign = 0, exp = 0; + int factor = 10; - value ^= get_storage_number_flags(value); - - if(value & (1 << 31)) { + // bit 32 = 0:positive, 1:negative + if(unlikely(value & (1 << 31))) sign = 1; - value ^= 1 << 31; - } - if(value & (1 << 30)) { + // bit 31 = 0:divide, 1:multiply + if(unlikely(value & (1 << 30))) exp = 1; - value ^= 1 << 30; - } - int mul = value >> 27; - value ^= mul << 27; + // bit 27 SN_EXISTS_100 + if(unlikely(value & (1 << 26))) + factor = 100; + + // bit 26 SN_EXISTS_RESET + // bit 25 SN_EXISTS + + // bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total) + int mul = (value & ((1<<29)|(1<<28)|(1<<27))) >> 27; + + // bit 24 to bit 1 = the value, so remove all other bits + value ^= value & ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24)); calculated_number n = value; - // fprintf(stderr, "UNPACK: %08X, sign = %d, exp = %d, mul = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, n); + // fprintf(stderr, "UNPACK: %08X, sign = %d, exp = %d, mul = %d, factor = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, factor, n); - while(mul > 0) { - if(exp) n *= 10; - else n /= 10; - mul--; + if(exp) { + for(; mul; mul--) + n *= factor; + } + else { + for( ; mul ; mul--) + n /= 10; } if(sign) n = -n; diff --git a/libnetdata/storage_number/storage_number.h b/libnetdata/storage_number/storage_number.h index 5353ab60b9..af7d29f3a3 100644 --- a/libnetdata/storage_number/storage_number.h +++ b/libnetdata/storage_number/storage_number.h @@ -23,7 +23,7 @@ typedef double calculated_number; #define LONG_DOUBLE_MODIFIER "f" typedef double LONG_DOUBLE; -#else +#else // NETDATA_WITHOUT_LONG_DOUBLE typedef long double calculated_number; #define CALCULATED_NUMBER_FORMAT "%0.7Lf" @@ -33,7 +33,7 @@ typedef long double calculated_number; #define LONG_DOUBLE_MODIFIER "Lf" typedef long double LONG_DOUBLE; -#endif +#endif // NETDATA_WITHOUT_LONG_DOUBLE //typedef long long calculated_number; //#define CALCULATED_NUMBER_FORMAT "%lld" @@ -50,6 +50,7 @@ typedef long double collected_number; #define calculated_number_llrint(x) llrintl(x) #define calculated_number_round(x) roundl(x) #define calculated_number_fabs(x) fabsl(x) +#define calculated_number_pow(x, y) powl(x, y) #define calculated_number_epsilon (calculated_number)0.0000001 #define calculated_number_equal(a, b) (calculated_number_fabs((a) - (b)) < calculated_number_epsilon) @@ -57,18 +58,12 @@ typedef long double collected_number; typedef uint32_t storage_number; #define STORAGE_NUMBER_FORMAT "%u" -#define SN_NOT_EXISTS (0x0 << 24) -#define SN_EXISTS (0x1 << 24) -#define SN_EXISTS_RESET (0x2 << 24) -#define SN_EXISTS_UNDEF1 (0x3 << 24) -#define SN_EXISTS_UNDEF2 (0x4 << 24) -#define SN_EXISTS_UNDEF3 (0x5 << 24) -#define SN_EXISTS_UNDEF4 (0x6 << 24) - -#define SN_FLAGS_MASK (~(0x6 << 24)) +#define SN_EXISTS (1 << 24) // the value exists +#define SN_EXISTS_RESET (1 << 25) // the value has been overflown +#define SN_EXISTS_100 (1 << 26) // very large value (multipler is 100 instead of 10) // extract the flags -#define get_storage_number_flags(value) ((((storage_number)(value)) & (1 << 24)) | (((storage_number)(value)) & (2 << 24)) | (((storage_number)(value)) & (4 << 24))) +#define get_storage_number_flags(value) ((((storage_number)(value)) & (1 << 24)) | (((storage_number)(value)) & (1 << 25)) | (((storage_number)(value)) & (1 << 26))) #define SN_EMPTY_SLOT 0x00000000 // checks @@ -80,13 +75,14 @@ calculated_number unpack_storage_number(storage_number value); int print_calculated_number(char *str, calculated_number value); -#define STORAGE_NUMBER_POSITIVE_MAX (167772150000000.0) -#define STORAGE_NUMBER_POSITIVE_MIN (0.0000001) -#define STORAGE_NUMBER_NEGATIVE_MAX (-0.0000001) -#define STORAGE_NUMBER_NEGATIVE_MIN (-167772150000000.0) +// sign div/mul <--- multiplier / divider ---> 10/100 RESET EXISTS VALUE +#define STORAGE_NUMBER_POSITIVE_MAX_RAW (storage_number)( (0 << 31) | (1 << 30) | (1 << 29) | (1 << 28) | (1<<27) | (1 << 26) | (0 << 25) | (1 << 24) | 0x00ffffff ) +#define STORAGE_NUMBER_POSITIVE_MIN_RAW (storage_number)( (0 << 31) | (0 << 30) | (1 << 29) | (1 << 28) | (1<<27) | (0 << 26) | (0 << 25) | (1 << 24) | 0x00000001 ) +#define STORAGE_NUMBER_NEGATIVE_MAX_RAW (storage_number)( (1 << 31) | (0 << 30) | (1 << 29) | (1 << 28) | (1<<27) | (0 << 26) | (0 << 25) | (1 << 24) | 0x00000001 ) +#define STORAGE_NUMBER_NEGATIVE_MIN_RAW (storage_number)( (1 << 31) | (1 << 30) | (1 << 29) | (1 << 28) | (1<<27) | (1 << 26) | (0 << 25) | (1 << 24) | 0x00ffffff ) // accepted accuracy loss -#define ACCURACY_LOSS 0.0001 +#define ACCURACY_LOSS_ACCEPTED_PERCENT 0.0001 #define accuracy_loss(t1, t2) (((t1) == (t2) || (t1) == 0.0 || (t2) == 0.0) ? 0.0 : (100.0 - (((t1) > (t2)) ? ((t2) * 100.0 / (t1) ) : ((t1) * 100.0 / (t2))))) #endif /* NETDATA_STORAGE_NUMBER_H */ |