diff options
Diffstat (limited to 'src/metrics/python_api.c')
| -rw-r--r-- | src/metrics/python_api.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/src/metrics/python_api.c b/src/metrics/python_api.c new file mode 100644 index 0000000..83ad75c --- /dev/null +++ b/src/metrics/python_api.c @@ -0,0 +1,140 @@ +#include <string.h> +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> + +#include "histogram_encoder.h" +#include "base64/b64.h" +#include "st_hyperloglog.h" + +// user must free the buf after use +void *histogram_base64_decode(char *buf) +{ + size_t buffer_size = strlen(buf); + struct hdr_histogram *hdr = histogram_decode_from_b64(buf, buffer_size); + + return hdr; +} + +long long histogram_value_at_percentile(void* h, double percentile) +{ + return hdr_value_at_percentile((const struct hdr_histogram *)h, percentile); +} + +long long histogram_count_le_value(void* h, long long value) +{ + return hdr_count_le_value((const struct hdr_histogram *)h, value); +} + +long long histogram_value_min(void* h) +{ + return hdr_min((const struct hdr_histogram *)h); +} + +long long histogram_value_max(void* h) +{ + return hdr_max((const struct hdr_histogram *)h); +} + +double histogram_value_mean(void* h) +{ + return hdr_mean((const struct hdr_histogram *)h); +} + +double histogram_value_stddev(void* h) +{ + return hdr_stddev((const struct hdr_histogram *)h); +} + +long long histogram_value_total_count(void *h) +{ + return ((struct hdr_histogram *)h)->total_count; +} + +long long histogram_value_sum(void *h) +{ + struct hdr_iter iter; + long long sum = 0; + hdr_iter_recorded_init(&iter, (const struct hdr_histogram *)h); + while (hdr_iter_next(&iter)) + { + sum+=(long long)iter.value; + } + return sum; +} + +void histogram_free(void *h) +{ + hdr_close((struct hdr_histogram *)h); +} + + +/* -------------------------------------------------------------------------- */ +/* hyperloglog */ +/* -------------------------------------------------------------------------- */ +void *hll_base64_decode(char *buf); +double hll_base64_to_count(char *buf) +{ + struct ST_hyperloglog *hll = hll_base64_decode(buf); + double count = ST_hyperloglog_count(hll); + ST_hyperloglog_free(hll); + return count; +} + +#define BigLittleSwap32(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \ + (((uint32_t)(A) & 0x00ff0000) >> 8) | \ + (((uint32_t)(A) & 0x0000ff00) << 8) | \ + (((uint32_t)(A) & 0x000000ff) << 24)) + +void *hll_base64_decode(char *buf) +{ + size_t buffer_size = strlen(buf); + size_t dec_size = 0; + unsigned char *dec = b64_decode_ex(buf, buffer_size, &dec_size); + + unsigned char version; + memcpy(&version, dec, sizeof(unsigned char)); + if (version != 1) { + return NULL; + } + + unsigned char precision; + memcpy(&precision, dec + sizeof(unsigned char), sizeof(unsigned char)); + + struct ST_hyperloglog *hll_from_blob = ST_hyperloglog_new(precision); + + int num_reg = NUM_REG(precision); + int words = INT_CEIL(num_reg, REG_PER_WORD); + size_t reg_size = words * sizeof(uint32_t); + uint32_t *registers = (uint32_t *)malloc(reg_size); + memcpy(registers, dec + 2 * sizeof(unsigned char), reg_size); + for (int i = 0; i < words; i++) { + registers[i] = BigLittleSwap32(registers[i]); + } + memcpy(hll_from_blob->registers, registers, reg_size); + free(registers); + + free(dec); + return hll_from_blob; +} + +void hll_free(void *hll) +{ + ST_hyperloglog_free((struct ST_hyperloglog *)hll); +} + +// cppcheck-suppress [constParameterPointer, unmatchedSuppression] +bool is_hll(char *buf) +{ + size_t dec_size = 0; + unsigned char *dec = b64_decode_ex(buf, 4, &dec_size); // 4: base64 convert every 3 bytes to 4 bytes + char cookie = *(char *)dec; + free(dec); + + if (cookie == 1) { // hll version is 1 + return true; + } + + // histogram cookie is also fixed, it's first byte is always 28, refer to V2_ENCODING_COOKIE (1c == 28) + return false; +} |
