summaryrefslogtreecommitdiffstats
path: root/libnetdata/storage_number
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-06-09 04:52:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-06-09 04:52:57 +0000
commit00151562145df50cc65e9902d52d5fa77f89fe50 (patch)
tree2737716802f6725a5074d606ec8fe5422c58a83c /libnetdata/storage_number
parentReleasing debian version 1.34.1-1. (diff)
downloadnetdata-00151562145df50cc65e9902d52d5fa77f89fe50.tar.xz
netdata-00151562145df50cc65e9902d52d5fa77f89fe50.zip
Merging upstream version 1.35.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libnetdata/storage_number')
-rw-r--r--libnetdata/storage_number/storage_number.c55
-rw-r--r--libnetdata/storage_number/storage_number.h39
2 files changed, 52 insertions, 42 deletions
diff --git a/libnetdata/storage_number/storage_number.c b/libnetdata/storage_number/storage_number.c
index 3e6a9f45c..ba7a66874 100644
--- a/libnetdata/storage_number/storage_number.c
+++ b/libnetdata/storage_number/storage_number.c
@@ -91,48 +91,21 @@ RET_SN:
return r;
}
-calculated_number unpack_storage_number(storage_number value) {
- if(!value) return 0;
-
- int sign = 0, exp = 0;
- int factor = 10;
-
- // bit 32 = 0:positive, 1:negative
- if(unlikely(value & (1 << 31)))
- sign = 1;
-
- // bit 31 = 0:divide, 1:multiply
- if(unlikely(value & (1 << 30)))
- exp = 1;
-
- // bit 27 SN_EXISTS_100
- if(unlikely(value & (1 << 26)))
- factor = 100;
-
- // bit 26 SN_EXISTS_RESET
- // 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;
-
- // 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, factor = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, factor, n);
-
- if(exp) {
- for(; mul; mul--)
- n *= factor;
+// Lookup table to make storage number unpacking efficient.
+calculated_number unpack_storage_number_lut10x[4 * 8];
+
+__attribute__((constructor)) void initialize_lut(void) {
+ // The lookup table is partitioned in 4 subtables based on the
+ // values of the factor and exp bits.
+ for (int i = 0; i < 8; i++) {
+ // factor = 0
+ unpack_storage_number_lut10x[0 * 8 + i] = 1 / pow(10, i); // exp = 0
+ unpack_storage_number_lut10x[1 * 8 + i] = pow(10, i); // exp = 1
+
+ // factor = 1
+ unpack_storage_number_lut10x[2 * 8 + i] = 1 / pow(100, i); // exp = 0
+ unpack_storage_number_lut10x[3 * 8 + i] = pow(100, i); // exp = 1
}
- else {
- for( ; mul ; mul--)
- n /= 10;
- }
-
- if(sign) n = -n;
- return n;
}
/*
diff --git a/libnetdata/storage_number/storage_number.h b/libnetdata/storage_number/storage_number.h
index 4101f69e0..7e7b511b0 100644
--- a/libnetdata/storage_number/storage_number.h
+++ b/libnetdata/storage_number/storage_number.h
@@ -80,7 +80,7 @@ typedef uint32_t storage_number;
#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);
+static inline calculated_number unpack_storage_number(storage_number value) __attribute__((const));
int print_calculated_number(char *str, calculated_number value);
@@ -98,4 +98,41 @@ int print_calculated_number(char *str, calculated_number value);
// period of at least every other 10 samples.
#define MAX_INCREMENTAL_PERCENT_RATE 10
+
+static inline calculated_number unpack_storage_number(storage_number value) {
+ extern calculated_number unpack_storage_number_lut10x[4 * 8];
+
+ if(!value) return 0;
+
+ int sign = 1, exp = 0;
+ int factor = 0;
+
+ // bit 32 = 0:positive, 1:negative
+ if(unlikely(value & (1 << 31)))
+ sign = -1;
+
+ // bit 31 = 0:divide, 1:multiply
+ if(unlikely(value & (1 << 30)))
+ exp = 1;
+
+ // bit 27 SN_EXISTS_100
+ if(unlikely(value & (1 << 26)))
+ factor = 1;
+
+ // bit 26 SN_EXISTS_RESET
+ // 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;
+
+ // 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, factor = %d, n = " CALCULATED_NUMBER_FORMAT "\n", value, sign, exp, mul, factor, n);
+
+ return sign * unpack_storage_number_lut10x[(factor * 16) + (exp * 8) + mul] * n;
+}
+
#endif /* NETDATA_STORAGE_NUMBER_H */