diff options
Diffstat (limited to '')
-rw-r--r-- | src/libnetdata/storage_number/README.md | 21 | ||||
-rw-r--r-- | src/libnetdata/storage_number/storage_number.c (renamed from libnetdata/storage_number/storage_number.c) | 63 | ||||
-rw-r--r-- | src/libnetdata/storage_number/storage_number.h (renamed from libnetdata/storage_number/storage_number.h) | 12 | ||||
-rw-r--r-- | src/libnetdata/storage_number/tests/test_storage_number.c (renamed from libnetdata/storage_number/tests/test_storage_number.c) | 0 |
4 files changed, 27 insertions, 69 deletions
diff --git a/src/libnetdata/storage_number/README.md b/src/libnetdata/storage_number/README.md new file mode 100644 index 000000000..f0096fb9b --- /dev/null +++ b/src/libnetdata/storage_number/README.md @@ -0,0 +1,21 @@ +<!-- +title: "Netdata storage number" +custom_edit_url: https://github.com/netdata/netdata/edit/master/src/libnetdata/storage_number/README.md +sidebar_label: "Storage number" +learn_status: "Published" +learn_topic_type: "Tasks" +learn_rel_path: "Developers/libnetdata" +--> + +# Netdata storage number + +Although `netdata` does all its calculations using `long double`, it stores all values using +a **custom-made 32-bit number**. + +This custom-made number can store in 29 bits values from `-167772150000000.0` to `167772150000000.0` +with a precision of 0.00001 (yes, it's a floating point number, meaning that higher integer values +have less decimal precision) and 3 bits for flags. + +This provides an extremely optimized memory footprint with just 0.0001% max accuracy loss. + + diff --git a/libnetdata/storage_number/storage_number.c b/src/libnetdata/storage_number/storage_number.c index 6468951bd..89a67a532 100644 --- a/libnetdata/storage_number/storage_number.c +++ b/src/libnetdata/storage_number/storage_number.c @@ -147,13 +147,7 @@ storage_number pack_storage_number(NETDATA_DOUBLE value, SN_FLAGS flags) { r += (m << 27); // the divider m } -#ifdef STORAGE_WITH_MATH - // without this there are rounding problems - // example: 0.9 becomes 0.89 r += lrint((double) n); -#else - r += (storage_number)n; -#endif return r; } @@ -174,60 +168,3 @@ __attribute__((constructor)) void initialize_lut(void) { unpack_storage_number_lut10x[3 * 8 + i] = pow(100, i); // exp = 1 } } - -/* -int print_netdata_double(char *str, NETDATA_DOUBLE value) -{ - char *wstr = str; - - int sign = (value < 0) ? 1 : 0; - if(sign) value = -value; - -#ifdef STORAGE_WITH_MATH - // without llrintl() there are rounding problems - // for example 0.9 becomes 0.89 - unsigned long long uvalue = (unsigned long long int) llrintl(value * (NETDATA_DOUBLE)100000); -#else - unsigned long long uvalue = value * (NETDATA_DOUBLE)100000; -#endif - - wstr = print_number_llu_r_smart(str, uvalue); - - // make sure we have 6 bytes at least - while((wstr - str) < 6) *wstr++ = '0'; - - // put the sign back - if(sign) *wstr++ = '-'; - - // reverse it - char *begin = str, *end = --wstr, aux; - while (end > begin) aux = *end, *end-- = *begin, *begin++ = aux; - // wstr--; - // strreverse(str, wstr); - - // remove trailing zeros - int decimal = 5; - while(decimal > 0 && *wstr == '0') { - *wstr-- = '\0'; - decimal--; - } - - // terminate it, one position to the right - // to let space for a dot - wstr[2] = '\0'; - - // make space for the dot - int i; - for(i = 0; i < decimal ;i++) { - wstr[1] = wstr[0]; - wstr--; - } - - // put the dot - if(wstr[2] == '\0') { wstr[1] = '\0'; decimal--; } - else wstr[1] = '.'; - - // return the buffer length - return (int) ((wstr - str) + 2 + decimal ); -} -*/ diff --git a/libnetdata/storage_number/storage_number.h b/src/libnetdata/storage_number/storage_number.h index 82c870d69..9a95203cd 100644 --- a/libnetdata/storage_number/storage_number.h +++ b/src/libnetdata/storage_number/storage_number.h @@ -116,10 +116,10 @@ storage_number pack_storage_number(NETDATA_DOUBLE value, SN_FLAGS flags) __attri static inline NETDATA_DOUBLE unpack_storage_number(storage_number value) __attribute__((const)); // 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 ) +#define STORAGE_NUMBER_POSITIVE_MAX_RAW (storage_number)( (0U << 31) | (1U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (1U << 26) | (0U << 25) | (1U << 24) | 0x00ffffff ) +#define STORAGE_NUMBER_POSITIVE_MIN_RAW (storage_number)( (0U << 31) | (0U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (0U << 26) | (0U << 25) | (1U << 24) | 0x00000001 ) +#define STORAGE_NUMBER_NEGATIVE_MAX_RAW (storage_number)( (1U << 31) | (0U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (0U << 26) | (0U << 25) | (1U << 24) | 0x00000001 ) +#define STORAGE_NUMBER_NEGATIVE_MIN_RAW (storage_number)( (1U << 31) | (1U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (1U << 26) | (0U << 25) | (1U << 24) | 0x00ffffff ) // accepted accuracy loss #define ACCURACY_LOSS_ACCEPTED_PERCENT 0.0001 @@ -155,10 +155,10 @@ static inline NETDATA_DOUBLE unpack_storage_number(storage_number value) { // bit 25 SN_FLAG_NOT_ANOMALOUS // bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total) - int mul = (int)((value & ((1<<29)|(1<<28)|(1<<27))) >> 27); + int mul = (int)((value & ((1U<<29)|(1U<<28)|(1U<<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)); + value ^= value & ((1U <<31)|(1U <<30)|(1U <<29)|(1U <<28)|(1U <<27)|(1U <<26)|(1U <<25)|(1U<<24)); NETDATA_DOUBLE n = value; diff --git a/libnetdata/storage_number/tests/test_storage_number.c b/src/libnetdata/storage_number/tests/test_storage_number.c index 19309e5c2..19309e5c2 100644 --- a/libnetdata/storage_number/tests/test_storage_number.c +++ b/src/libnetdata/storage_number/tests/test_storage_number.c |