summaryrefslogtreecommitdiffstats
path: root/libnetdata/storage_number
diff options
context:
space:
mode:
Diffstat (limited to 'libnetdata/storage_number')
-rw-r--r--libnetdata/storage_number/storage_number.c18
-rw-r--r--libnetdata/storage_number/storage_number.h17
-rw-r--r--libnetdata/storage_number/tests/test_storage_number.c2
3 files changed, 27 insertions, 10 deletions
diff --git a/libnetdata/storage_number/storage_number.c b/libnetdata/storage_number/storage_number.c
index 8ef1353b0..3e6a9f45c 100644
--- a/libnetdata/storage_number/storage_number.c
+++ b/libnetdata/storage_number/storage_number.c
@@ -2,17 +2,23 @@
#include "../libnetdata.h"
+#define get_storage_number_flags(value) \
+ ((((storage_number)(value)) & (1 << 24)) | \
+ (((storage_number)(value)) & (1 << 25)) | \
+ (((storage_number)(value)) & (1 << 26)))
+
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 SN_EXISTS_100
// bit 26 SN_EXISTS_RESET
- // bit 25 SN_EXISTS
+ // bit 25 SN_ANOMALY_BIT = 0: anomalous, 1: not anomalous
// bit 24 to bit 1 = the value
storage_number r = get_storage_number_flags(flags);
- if(!value) return r;
+ if(!value)
+ goto RET_SN;
int m = 0;
calculated_number n = value, factor = 10;
@@ -47,7 +53,7 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) {
error("Number " CALCULATED_NUMBER_FORMAT " is too big.", value);
#endif
r += 0x00ffffff;
- return r;
+ goto RET_SN;
}
}
else {
@@ -78,6 +84,10 @@ storage_number pack_storage_number(calculated_number value, uint32_t flags) {
r += (storage_number)n;
#endif
+RET_SN:
+ if (r == SN_EMPTY_SLOT)
+ r = SN_ANOMALOUS_ZERO;
+
return r;
}
@@ -100,7 +110,7 @@ calculated_number unpack_storage_number(storage_number value) {
factor = 100;
// bit 26 SN_EXISTS_RESET
- // bit 25 SN_EXISTS
+ // bit 25 SN_ANOMALY_BIT
// bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total)
int mul = (value & ((1<<29)|(1<<28)|(1<<27))) >> 27;
diff --git a/libnetdata/storage_number/storage_number.h b/libnetdata/storage_number/storage_number.h
index 4ad7ff624..4101f69e0 100644
--- a/libnetdata/storage_number/storage_number.h
+++ b/libnetdata/storage_number/storage_number.h
@@ -60,17 +60,24 @@ typedef long double collected_number;
typedef uint32_t storage_number;
#define STORAGE_NUMBER_FORMAT "%u"
-#define SN_EXISTS (1 << 24) // the value exists
+#define SN_ANOMALY_BIT (1 << 24) // the anomaly bit of the value
#define SN_EXISTS_RESET (1 << 25) // the value has been overflown
#define SN_EXISTS_100 (1 << 26) // very large value (multiplier is 100 instead of 10)
-// extract the flags
-#define get_storage_number_flags(value) ((((storage_number)(value)) & (1 << 24)) | (((storage_number)(value)) & (1 << 25)) | (((storage_number)(value)) & (1 << 26)))
+#define SN_DEFAULT_FLAGS SN_ANOMALY_BIT
+
#define SN_EMPTY_SLOT 0x00000000
+// When the calculated number is zero and the value is anomalous (ie. it's bit
+// is zero) we want to return a storage_number representation that is
+// different from the empty slot. We achieve this by mapping zero to
+// SN_EXISTS_100. Unpacking the SN_EXISTS_100 value will return zero because
+// its fraction field (as well as its exponent factor field) will be zero.
+#define SN_ANOMALOUS_ZERO SN_EXISTS_100
+
// checks
-#define does_storage_number_exist(value) ((get_storage_number_flags(value) != 0)?1:0)
-#define did_storage_number_reset(value) ((get_storage_number_flags(value) == SN_EXISTS_RESET)?1:0)
+#define does_storage_number_exist(value) (((storage_number) (value)) != SN_EMPTY_SLOT)
+#define did_storage_number_reset(value) ((((storage_number) (value)) & SN_EXISTS_RESET) != 0)
storage_number pack_storage_number(calculated_number value, uint32_t flags);
calculated_number unpack_storage_number(storage_number value);
diff --git a/libnetdata/storage_number/tests/test_storage_number.c b/libnetdata/storage_number/tests/test_storage_number.c
index 7ef18b1de..f90521cab 100644
--- a/libnetdata/storage_number/tests/test_storage_number.c
+++ b/libnetdata/storage_number/tests/test_storage_number.c
@@ -38,7 +38,7 @@ static void test_number_printing(void **state)
print_calculated_number(value, -9999.9999999);
assert_string_equal(value, "-9999.9999999");
- print_calculated_number(value, unpack_storage_number(pack_storage_number(16.777218L, SN_EXISTS)));
+ print_calculated_number(value, unpack_storage_number(pack_storage_number(16.777218L, SN_DEFAULT_FLAGS)));
assert_string_equal(value, "16.77722");
}