From: Svetlana Date: Fri, 14 Aug 2020 11:12:02 +0000 (+0000) Subject: fix codestyle in distribution data structure X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=347a84b84c760b4460a51580cd5e171fa557fb8e;p=thirdparty%2Fcollectd.git fix codestyle in distribution data structure --- diff --git a/src/daemon/distribution.c b/src/daemon/distribution.c index f573e1a43..229791446 100644 --- a/src/daemon/distribution.c +++ b/src/daemon/distribution.c @@ -40,7 +40,8 @@ struct distribution_s { * This way the tree contained N buckets contains 2 * N - 1 nodes * Thus, left subtree has 2 * (mid - left + 1) - 1 nodes, * therefore the right subtree starts at node_index + 2 * (mid - left + 1). - * For a detailed explanation, see https://docs.google.com/document/d/1ccsg5ffUfqt9-mBDGTymRn8X-9Wk1CuGYeMlRxmxiok/edit?usp=sharing". + * For a detailed explanation, see + * https://docs.google.com/document/d/1ccsg5ffUfqt9-mBDGTymRn8X-9Wk1CuGYeMlRxmxiok/edit?usp=sharing". */ static size_t left_child_index(size_t node_index, @@ -54,18 +55,17 @@ static size_t right_child_index(size_t node_index, size_t left, size_t right) { return node_index + 2 * (mid - left + 1); } -static size_t tree_size(size_t num_buckets) { - return 2 * num_buckets - 1; -} +static size_t tree_size(size_t num_buckets) { return 2 * num_buckets - 1; } static bucket_t merge_buckets(bucket_t left_child, bucket_t right_child) { - return (bucket_t) { + return (bucket_t){ .bucket_counter = left_child.bucket_counter + right_child.bucket_counter, .maximum = right_child.maximum, }; } -static void build_tree(distribution_t *d, bucket_t *buckets, size_t node_index, size_t left, size_t right) { +static void build_tree(distribution_t *d, bucket_t *buckets, size_t node_index, + size_t left, size_t right) { if (left > right) return; if (left == right) { @@ -77,10 +77,13 @@ static void build_tree(distribution_t *d, bucket_t *buckets, size_t node_index, size_t right_child = right_child_index(node_index, left, right); build_tree(d, buckets, left_child, left, mid); build_tree(d, buckets, right_child, mid + 1, right); - d->tree[node_index] = merge_buckets(d->tree[left_child], d->tree[right_child]); + d->tree[node_index] = + merge_buckets(d->tree[left_child], d->tree[right_child]); } -static distribution_t* build_distribution_from_bucket_array(size_t num_buckets, bucket_t *bucket_array) { +static distribution_t * +build_distribution_from_bucket_array(size_t num_buckets, + bucket_t *bucket_array) { distribution_t *new_distribution = calloc(1, sizeof(*new_distribution)); bucket_t *nodes = calloc(tree_size(num_buckets), sizeof(*nodes)); if (new_distribution == NULL || nodes == NULL) { @@ -96,7 +99,7 @@ static distribution_t* build_distribution_from_bucket_array(size_t num_buckets, return new_distribution; } -distribution_t* distribution_new_linear(size_t num_buckets, double size) { +distribution_t *distribution_new_linear(size_t num_buckets, double size) { if (num_buckets == 0 || size <= 0) { errno = EINVAL; return NULL; @@ -104,7 +107,7 @@ distribution_t* distribution_new_linear(size_t num_buckets, double size) { bucket_t bucket_array[num_buckets]; for (size_t i = 0; i < num_buckets; i++) { - bucket_array[i] = (bucket_t) { + bucket_array[i] = (bucket_t){ .bucket_counter = 0, .maximum = (i == num_buckets - 1) ? INFINITY : (i + 1) * size, }; @@ -112,7 +115,8 @@ distribution_t* distribution_new_linear(size_t num_buckets, double size) { return build_distribution_from_bucket_array(num_buckets, bucket_array); } -distribution_t* distribution_new_exponential(size_t num_buckets, double base, double factor) { +distribution_t *distribution_new_exponential(size_t num_buckets, double base, + double factor) { if (num_buckets == 0 || base <= 1 || factor <= 0) { errno = EINVAL; return NULL; @@ -120,15 +124,18 @@ distribution_t* distribution_new_exponential(size_t num_buckets, double base, do bucket_t bucket_array[num_buckets]; for (size_t i = 0; i < num_buckets; i++) { - bucket_array[i] = (bucket_t) { + bucket_array[i] = (bucket_t){ .bucket_counter = 0, - .maximum = (i == num_buckets - 1) ? INFINITY : factor * pow(base, i), //check if it's slow + .maximum = (i == num_buckets - 1) + ? INFINITY + : factor * pow(base, i), // check if it's slow }; } return build_distribution_from_bucket_array(num_buckets, bucket_array); } -distribution_t* distribution_new_custom(size_t array_size, double *custom_buckets_boundaries) { +distribution_t *distribution_new_custom(size_t array_size, + double *custom_buckets_boundaries) { for (size_t i = 0; i < array_size; i++) { double previous_boundary = 0; if (i > 0) { @@ -147,9 +154,10 @@ distribution_t* distribution_new_custom(size_t array_size, double *custom_bucket size_t num_buckets = array_size + 1; bucket_t bucket_array[num_buckets]; for (size_t i = 0; i < num_buckets; i++) { - bucket_array[i] = (bucket_t) { + bucket_array[i] = (bucket_t){ .bucket_counter = 0, - .maximum = (i == num_buckets - 1) ? INFINITY : custom_buckets_boundaries[i], + .maximum = + (i == num_buckets - 1) ? INFINITY : custom_buckets_boundaries[i], }; } return build_distribution_from_bucket_array(num_buckets, bucket_array); @@ -163,7 +171,7 @@ void distribution_destroy(distribution_t *d) { free(d); } -distribution_t* distribution_clone(distribution_t *dist) { +distribution_t *distribution_clone(distribution_t *dist) { if (dist == NULL) return NULL; distribution_t *new_distribution = calloc(1, sizeof(*new_distribution)); @@ -183,7 +191,8 @@ distribution_t* distribution_clone(distribution_t *dist) { return new_distribution; } -static void update_tree(distribution_t *dist, size_t node_index, size_t left, size_t right, double gauge) { +static void update_tree(distribution_t *dist, size_t node_index, size_t left, + size_t right, double gauge) { if (left > right) return; dist->tree[node_index].bucket_counter++; @@ -212,8 +221,8 @@ void distribution_update(distribution_t *dist, double gauge) { pthread_mutex_unlock(&dist->mutex); } -static double tree_get_counter(distribution_t *d, size_t node_index, size_t left, - size_t right, uint64_t counter) { +static double tree_get_counter(distribution_t *d, size_t node_index, + size_t left, size_t right, uint64_t counter) { if (left > right) return NAN; if (left == right) { @@ -225,7 +234,8 @@ static double tree_get_counter(distribution_t *d, size_t node_index, size_t left if (d->tree[left_child].bucket_counter >= counter) return tree_get_counter(d, left_child, left, mid, counter); else - return tree_get_counter(d, right_child, mid + 1, right, counter - d->tree[left_child].bucket_counter); + return tree_get_counter(d, right_child, mid + 1, right, + counter - d->tree[left_child].bucket_counter); } double distribution_percentile(distribution_t *dist, double percent) { @@ -237,7 +247,8 @@ double distribution_percentile(distribution_t *dist, double percent) { if (dist->tree[0].bucket_counter == 0) return NAN; uint64_t counter = ceil(dist->tree[0].bucket_counter * percent / 100.0); - double percentile = tree_get_counter(dist, 0, 0, dist->num_buckets - 1, counter); + double percentile = + tree_get_counter(dist, 0, 0, dist->num_buckets - 1, counter); pthread_mutex_unlock(&dist->mutex); return percentile; } @@ -258,7 +269,9 @@ size_t distribution_num_buckets(distribution_t *dist) { return dist->num_buckets; } -static void tree_write_leave_buckets(distribution_t *dist, bucket_t *write_ptr, size_t node_index, size_t left, size_t right) { +static void tree_write_leave_buckets(distribution_t *dist, bucket_t *write_ptr, + size_t node_index, size_t left, + size_t right) { if (left > right) return; if (left == right) { @@ -269,13 +282,15 @@ static void tree_write_leave_buckets(distribution_t *dist, bucket_t *write_ptr, size_t left_child = left_child_index(node_index, left, right); size_t right_child = right_child_index(node_index, left, right); tree_write_leave_buckets(dist, write_ptr, left_child, left, mid); - tree_write_leave_buckets(dist, write_ptr, right_child, mid + 1, right); -} + tree_write_leave_buckets(dist, write_ptr, right_child, mid + 1, right); +} buckets_array_t get_buckets(distribution_t *dist) { buckets_array_t bucket_array = { - .num_buckets = dist == NULL ? 0 : dist->num_buckets, - .buckets = dist == NULL ? NULL : calloc(dist->num_buckets, sizeof(*bucket_array.buckets)), + .num_buckets = dist == NULL ? 0 : dist->num_buckets, + .buckets = dist == NULL + ? NULL + : calloc(dist->num_buckets, sizeof(*bucket_array.buckets)), }; if (dist == NULL) return bucket_array; diff --git a/src/daemon/distribution.h b/src/daemon/distribution.h index 8f5f4ba62..fdb771293 100644 --- a/src/daemon/distribution.h +++ b/src/daemon/distribution.h @@ -27,7 +27,7 @@ #ifndef COLLECTD_DISTRIBUTION_H #define COLLECTD_DISTRIBUTION_H -#include"collectd.h" +#include "collectd.h" typedef struct bucket_s { uint64_t bucket_counter; @@ -42,35 +42,44 @@ typedef struct buckets_array_s { bucket_t *buckets; } buckets_array_t; -//constructor functions: +// constructor functions: /** * function creates new distribution with the linear buckets: * [0; size) [size; 2 * size) ... [(num_buckets - 1) * size; infinity) * @param num_buckets - number of buckets. Should be greater than 0 * @param size - size of each bucket. Should be greater than 0 - * @return - pointer to a new distribution or null pointer if parameters are wrong or memory allocation fails + * @return - pointer to a new distribution or null pointer if parameters are + * wrong or memory allocation fails */ -distribution_t* distribution_new_linear(size_t num_buckets, double size); +distribution_t *distribution_new_linear(size_t num_buckets, double size); /** * function creates new distribution with the exponential buckets: - * [0; factor) [factor; factor * base) ... [factor * base^{num_buckets - 2}; infinity) + * [0; factor) [factor; factor * base) ... [factor * base^{num_buckets - 2}; + * infinity) * @param num_buckets - number of buckets. Should be greater than 0 * @param base - base of geometric progression. Should be greater than 1 * @param factor - size of the first bucket. Should be greater than 0 - * @return - pointer to a new distribution or null pointer if parameters are wrong or memory allocation fails + * @return - pointer to a new distribution or null pointer if parameters are + * wrong or memory allocation fails */ -distribution_t* distribution_new_exponential(size_t num_buckets, double base, double factor); +distribution_t *distribution_new_exponential(size_t num_buckets, double base, + double factor); /** * function creates new distribution with the custom buckets: - * [0; custom_bucket_boundaries[0]) [custom_bucket_boundaries[0]; custom_bucket_boundaries[1]) ... + * [0; custom_bucket_boundaries[0]) [custom_bucket_boundaries[0]; + * custom_bucket_boundaries[1]) ... * ... [custom_bucket_boundaries[array_size - 1], infinity) - * @param array_size - size of array of bucket boundaries. Number of buckets is array_size + 1 - * @param custom_buckets_boundaries - array with bucket boundaries. Should be increasing and positive - * @return - pointer to a new distribution or null pointer if parameters are wrong or memory allocation fails + * @param array_size - size of array of bucket boundaries. Number of buckets is + * array_size + 1 + * @param custom_buckets_boundaries - array with bucket boundaries. Should be + * increasing and positive + * @return - pointer to a new distribution or null pointer if parameters are + * wrong or memory allocation fails */ -distribution_t* distribution_new_custom(size_t array_size, double *custom_buckets_boundaries); +distribution_t *distribution_new_custom(size_t array_size, + double *custom_buckets_boundaries); /** add new value to a distribution **/ void distribution_update(distribution_t *dist, double gauge); @@ -78,16 +87,19 @@ void distribution_update(distribution_t *dist, double gauge); /** * @param percent - should be in (0; 100] range * @return - an approximation of percent percentile - * (upper bound of such bucket that all less or equal buckets contain more than percent percents of values) - * or NAN if parameters are wrong or distribution is empty + * (upper bound of such bucket that all less or equal buckets contain more than + * percent percents of values) or NAN if parameters are wrong or distribution is + * empty */ double distribution_percentile(distribution_t *dist, double percent); -/** @return - average of all values in distribution or NAN if distribution is empty */ +/** @return - average of all values in distribution or NAN if distribution is + * empty */ double distribution_average(distribution_t *dist); -/** @return - pointer to the copy of distribution or null if memory allocation fails */ -distribution_t* distribution_clone(distribution_t *dist); +/** @return - pointer to the copy of distribution or null if memory allocation + * fails */ +distribution_t *distribution_clone(distribution_t *dist); /** destroy the distribution and free memory **/ void distribution_destroy(distribution_t *d); diff --git a/src/daemon/distribution_benchmark.c b/src/daemon/distribution_benchmark.c index c81e1d529..b48069d75 100644 --- a/src/daemon/distribution_benchmark.c +++ b/src/daemon/distribution_benchmark.c @@ -1,7 +1,7 @@ +#include #include #include #include -#include #include "distribution.h" @@ -14,7 +14,7 @@ distribution_t *build(size_t num_buckets) { double custom[num_buckets - 1]; custom[0] = rand() % 100; for (size_t i = 1; i < num_buckets - 1; i++) { - custom[i] = custom[i - 1] + rand() % 100 + 1; + custom[i] = custom[i - 1] + rand() % 100 + 1; } distribution_t *dist = distribution_new_custom(num_buckets - 1, custom); return dist; @@ -23,7 +23,8 @@ distribution_t *build(size_t num_buckets) { double calculate_update_time(distribution_t *dist) { double *updates = calloc(NUM_UPDATES, sizeof(*updates)); for (size_t i = 0; i < NUM_UPDATES; i++) { - updates[i] = (rand() * RAND_MAX + rand()) % (distribution_num_buckets(dist) * 100); + updates[i] = + (rand() * RAND_MAX + rand()) % (distribution_num_buckets(dist) * 100); } struct timespec start, finish; clock_gettime(CLOCK_MONOTONIC, &start); @@ -31,10 +32,11 @@ double calculate_update_time(distribution_t *dist) { distribution_update(dist, updates[i]); } clock_gettime(CLOCK_MONOTONIC, &finish); - double update_dur = 1000.0 * (finish.tv_sec - start.tv_sec) + 1e-6 * (finish.tv_nsec - start.tv_nsec); + double update_dur = 1000.0 * (finish.tv_sec - start.tv_sec) + + 1e-6 * (finish.tv_nsec - start.tv_nsec); double average = update_dur / NUM_UPDATES * 1000000.0; free(updates); - return average; + return average; } double calculate_percentile_time(distribution_t *dist) { @@ -48,10 +50,11 @@ double calculate_percentile_time(distribution_t *dist) { distribution_percentile(dist, percentiles[i]); } clock_gettime(CLOCK_MONOTONIC, &finish); - double percentile_dur = 1000.0 * (finish.tv_sec - start.tv_sec) + 1e-6 * (finish.tv_nsec - start.tv_nsec); + double percentile_dur = 1000.0 * (finish.tv_sec - start.tv_sec) + + 1e-6 * (finish.tv_nsec - start.tv_nsec); double average = percentile_dur / NUM_PERCENTILES * 1000000.0; free(percentiles); - return average; + return average; } double mixed(size_t num_buckets) { @@ -59,7 +62,7 @@ double mixed(size_t num_buckets) { double *updates = calloc(MIXED / 10 * 9, sizeof(*updates)); double *percentiles = calloc(MIXED / 10, sizeof(*percentiles)); for (size_t i = 0; i < MIXED / 10 * 9; i++) - updates[i] = (rand() * RAND_MAX + rand()) % (num_buckets * 100); + updates[i] = (rand() * RAND_MAX + rand()) % (num_buckets * 100); for (size_t i = 0; i < MIXED / 10; i++) percentiles[i] = 100.0 * rand() / RAND_MAX; @@ -69,33 +72,37 @@ double mixed(size_t num_buckets) { clock_gettime(CLOCK_MONOTONIC, &start); double val = 0; for (size_t i = 0; i < MIXED; i++) { - if (i % 10 == 9) { + if (i % 10 == 9) { double d = distribution_percentile(dist, percentiles[pid++]); if (d != INFINITY) val += d; - } - else + } else distribution_update(dist, updates[uid++]); } clock_gettime(CLOCK_MONOTONIC, &finish); - double dur = 1000.0 * (finish.tv_sec - start.tv_sec) + 1e-6 * (finish.tv_nsec - start.tv_nsec); + double dur = 1000.0 * (finish.tv_sec - start.tv_sec) + + 1e-6 * (finish.tv_nsec - start.tv_nsec); distribution_destroy(dist); free(percentiles); free(updates); - //printf("%f\n", val); + // printf("%f\n", val); return dur; } int main() { FILE *fout = fopen("benchmark_small.csv", "w"); - fprintf(fout, "Number of buckets,Average for update,Average for percentile,Total for %lu mixed iterations\n", MIXED); + fprintf(fout, + "Number of buckets,Average for update,Average for percentile,Total " + "for %lu mixed iterations\n", + MIXED); for (size_t num_buckets = 50; num_buckets <= 5000; num_buckets += 50) { distribution_t *dist = build(num_buckets); fprintf(fout, "%lu,", num_buckets); fprintf(fout, "%f,", calculate_update_time(dist)); fprintf(fout, "%f,", calculate_percentile_time(dist)); fprintf(fout, "%f\n", mixed(num_buckets)); - //fprintf(fout, "%lu,%f,%f,%f\n", num_buckets, calculate_update_time(dist), calculate_percentile_time(dist), mixed(num_buckets)); + // fprintf(fout, "%lu,%f,%f,%f\n", num_buckets, calculate_update_time(dist), + // calculate_percentile_time(dist), mixed(num_buckets)); distribution_destroy(dist); printf("OK %lu\n", num_buckets); } diff --git a/src/daemon/distribution_test.c b/src/daemon/distribution_test.c index bfc8e96cc..1238d7f71 100644 --- a/src/daemon/distribution_test.c +++ b/src/daemon/distribution_test.c @@ -37,13 +37,16 @@ static double *linear_upper_bounds(size_t num, double size) { return linear_upper_bounds; } -static double *exponential_upper_bounds(size_t num, double base, double factor) { - double *exponential_upper_bounds = calloc(num, sizeof(*exponential_upper_bounds)); +static double *exponential_upper_bounds(size_t num, double base, + double factor) { + double *exponential_upper_bounds = + calloc(num, sizeof(*exponential_upper_bounds)); exponential_upper_bounds[0] = factor; for (size_t i = 1; i + 1 < num; i++) - exponential_upper_bounds[i] = factor * pow(base, i); //exponential_upper_bounds[i - 1] * base; + exponential_upper_bounds[i] = + factor * pow(base, i); // exponential_upper_bounds[i - 1] * base; exponential_upper_bounds[num - 1] = INFINITY; - return exponential_upper_bounds; + return exponential_upper_bounds; } DEF_TEST(distribution_new_linear) { @@ -53,71 +56,74 @@ DEF_TEST(distribution_new_linear) { double *want_get; int want_err; } cases[] = { - { - .num_buckets = 0, - .size = 5, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 3, - .size = -5, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 5, - .size = 0, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 3, - .size = 2.5, - .want_get = linear_upper_bounds(3, 2.5), - }, - { - .num_buckets = 5, - .size = 5.75, - .want_get = linear_upper_bounds(5, 5.75), - }, - { - .num_buckets = 151, - .size = 0.7, - .want_get = linear_upper_bounds(151, 0.7), - }, - { - .num_buckets = 111, - .size = 1074, - .want_get = linear_upper_bounds(111, 1074), - }, - { - .num_buckets = 77, - .size = 1.0 / 3.0, - .want_get = linear_upper_bounds(77, 1.0 / 3.0), - }, - { - .num_buckets = 1, - .size = 100, - .want_get = linear_upper_bounds(1, 100), - }, + { + .num_buckets = 0, + .size = 5, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 3, + .size = -5, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 5, + .size = 0, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 3, + .size = 2.5, + .want_get = linear_upper_bounds(3, 2.5), + }, + { + .num_buckets = 5, + .size = 5.75, + .want_get = linear_upper_bounds(5, 5.75), + }, + { + .num_buckets = 151, + .size = 0.7, + .want_get = linear_upper_bounds(151, 0.7), + }, + { + .num_buckets = 111, + .size = 1074, + .want_get = linear_upper_bounds(111, 1074), + }, + { + .num_buckets = 77, + .size = 1.0 / 3.0, + .want_get = linear_upper_bounds(77, 1.0 / 3.0), + }, + { + .num_buckets = 1, + .size = 100, + .want_get = linear_upper_bounds(1, 100), + }, }; - for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { printf("## Case %zu:\n", i); if (cases[i].want_err != 0) { - EXPECT_EQ_PTR(cases[i].want_get, distribution_new_linear(cases[i].num_buckets, cases[i].size)); + EXPECT_EQ_PTR( + cases[i].want_get, + distribution_new_linear(cases[i].num_buckets, cases[i].size)); EXPECT_EQ_INT(cases[i].want_err, errno); continue; } distribution_t *d; - CHECK_NOT_NULL(d = distribution_new_linear(cases[i].num_buckets, cases[i].size)); + CHECK_NOT_NULL( + d = distribution_new_linear(cases[i].num_buckets, cases[i].size)); buckets_array_t buckets_array = get_buckets(d); for (size_t j = 0; j < cases[i].num_buckets; j++) { EXPECT_EQ_DOUBLE(cases[i].want_get[j], buckets_array.buckets[j].maximum); - } - destroy_buckets_array(buckets_array); + } + destroy_buckets_array(buckets_array); distribution_destroy(d); - } + } for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { free(cases[i].want_get); } @@ -132,83 +138,86 @@ DEF_TEST(distribution_new_exponential) { double *want_get; int want_err; } cases[] = { - { - .num_buckets = 0, - .factor = 5, - .base = 8, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 5, - .factor = 0.2, - .base = -1, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 8, - .factor = 100, - .base = 0.5, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 100, - .factor = 5.87, - .base = 1, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 6, - .factor = 0, - .base = 9.005, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 16, - .factor = -153, - .base = 1.41, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .num_buckets = 1, - .factor = 10, - .base = 1.05, - .want_get = exponential_upper_bounds(1, 10, 1.05), - }, - { - .num_buckets = 63, - .factor = 1, - .base = 2, - .want_get = exponential_upper_bounds(63, 2, 1), - }, - { - .num_buckets = 600, - .factor = 0.55, - .base = 1.055, - .want_get = exponential_upper_bounds(600, 1.055, 0.55), - }, + { + .num_buckets = 0, + .factor = 5, + .base = 8, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 5, + .factor = 0.2, + .base = -1, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 8, + .factor = 100, + .base = 0.5, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 100, + .factor = 5.87, + .base = 1, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 6, + .factor = 0, + .base = 9.005, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 16, + .factor = -153, + .base = 1.41, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .num_buckets = 1, + .factor = 10, + .base = 1.05, + .want_get = exponential_upper_bounds(1, 10, 1.05), + }, + { + .num_buckets = 63, + .factor = 1, + .base = 2, + .want_get = exponential_upper_bounds(63, 2, 1), + }, + { + .num_buckets = 600, + .factor = 0.55, + .base = 1.055, + .want_get = exponential_upper_bounds(600, 1.055, 0.55), + }, }; - for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { + for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { printf("## Case %zu:\n", i); if (cases[i].want_err != 0) { - EXPECT_EQ_PTR(cases[i].want_get, distribution_new_exponential(cases[i].num_buckets, cases[i].base, cases[i].factor)); + EXPECT_EQ_PTR(cases[i].want_get, + distribution_new_exponential( + cases[i].num_buckets, cases[i].base, cases[i].factor)); EXPECT_EQ_INT(cases[i].want_err, errno); continue; } distribution_t *d; - CHECK_NOT_NULL(d = distribution_new_exponential(cases[i].num_buckets, cases[i].base, cases[i].factor)); + CHECK_NOT_NULL(d = distribution_new_exponential( + cases[i].num_buckets, cases[i].base, cases[i].factor)); buckets_array_t buckets_array = get_buckets(d); for (size_t j = 0; j < cases[i].num_buckets; j++) { EXPECT_EQ_DOUBLE(cases[i].want_get[j], buckets_array.buckets[j].maximum); } - destroy_buckets_array(buckets_array); + destroy_buckets_array(buckets_array); distribution_destroy(d); - } + } for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { free(cases[i].want_get); } @@ -222,60 +231,65 @@ DEF_TEST(distribution_new_custom) { double *want_get; int want_err; } cases[] = { - { - .array_size = 0, - .want_get = (double[]){INFINITY}, - }, - { - .array_size = 5, - .custom_boundaries = (double[]){0, 1, 2, 3, 4}, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .array_size = 3, - .custom_boundaries = (double[]){-5, 7, 3}, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .array_size = 4, - .custom_boundaries = (double[]){5.7, 6.0, 6.0, 7.0}, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .array_size = 1, - .custom_boundaries = (double[]){105.055}, - .want_get = (double[]){105.055, INFINITY}, - }, - { - .array_size = 5, - .custom_boundaries = (double[]){8, 100, 1000, 1008, INFINITY}, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .array_size = 7, - .custom_boundaries = (double[]){2, 4, 8, 6, 2, 16, 77.5}, - .want_get = NULL, - .want_err = EINVAL, - }, - { - .array_size = 10, - .custom_boundaries = (double[]){77.5, 100.203, 122.01, 137.23, 200, 205, 210, 220, 230, 256}, - .want_get = (double[]){77.5, 100.203, 122.01, 137.23, 200, 205, 210, 220, 230, 256, INFINITY}, - }, + { + .array_size = 0, + .want_get = (double[]){INFINITY}, + }, + { + .array_size = 5, + .custom_boundaries = (double[]){0, 1, 2, 3, 4}, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .array_size = 3, + .custom_boundaries = (double[]){-5, 7, 3}, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .array_size = 4, + .custom_boundaries = (double[]){5.7, 6.0, 6.0, 7.0}, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .array_size = 1, + .custom_boundaries = (double[]){105.055}, + .want_get = (double[]){105.055, INFINITY}, + }, + { + .array_size = 5, + .custom_boundaries = (double[]){8, 100, 1000, 1008, INFINITY}, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .array_size = 7, + .custom_boundaries = (double[]){2, 4, 8, 6, 2, 16, 77.5}, + .want_get = NULL, + .want_err = EINVAL, + }, + { + .array_size = 10, + .custom_boundaries = (double[]){77.5, 100.203, 122.01, 137.23, 200, + 205, 210, 220, 230, 256}, + .want_get = (double[]){77.5, 100.203, 122.01, 137.23, 200, 205, 210, + 220, 230, 256, INFINITY}, + }, }; for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { if (cases[i].want_err != 0) { - EXPECT_EQ_PTR(cases[i].want_get, distribution_new_custom(cases[i].array_size, cases[i].custom_boundaries)); + EXPECT_EQ_PTR(cases[i].want_get, + distribution_new_custom(cases[i].array_size, + cases[i].custom_boundaries)); EXPECT_EQ_INT(cases[i].want_err, errno); continue; } distribution_t *d; - CHECK_NOT_NULL(d = distribution_new_custom(cases[i].array_size, cases[i].custom_boundaries)); + CHECK_NOT_NULL(d = distribution_new_custom(cases[i].array_size, + cases[i].custom_boundaries)); buckets_array_t buckets_array = get_buckets(d); for (size_t j = 0; j < cases[i].array_size + 1; j++) { EXPECT_EQ_DOUBLE(cases[i].want_get[j], buckets_array.buckets[j].maximum); @@ -294,36 +308,36 @@ DEF_TEST(update) { uint64_t *want_counters; int want_err; } cases[] = { - { - .dist = distribution_new_linear(6, 5), - .num_gauges = 10, - .gauges = (double[]){25, 30, 5, 7, 11, 10.5, 8.03, 1112.4, 35, 12.7}, - .want_counters = (uint64_t[]){0, 3, 3, 0, 0, 4}, - }, - { - .dist = distribution_new_exponential(4, 1.41, 1), - .num_gauges = 0, - .gauges = NULL, - .want_counters = (uint64_t[]){0, 0, 0, 0}, - }, - { - .dist = distribution_new_exponential(5, 2, 3), - .num_gauges = 5, - .gauges = (double[]){1, 7, 3, 10, 77}, - .want_counters = (uint64_t[]){1, 1, 2, 0, 1}, - }, - { - .dist = distribution_new_linear(100, 22), - .num_gauges = 3, - .gauges = (double[]){1000, 2, -8}, - .want_err = EINVAL, - }, - { - .dist = distribution_new_custom(3, (double[]) {5, 20, 35}), - .num_gauges = 7, - .gauges = (double[]){7.05, 22.37, 40.83, 90.55, 12.34, 14.2, 6.0}, - .want_counters = (uint64_t[]){0, 4, 1, 2}, - }, + { + .dist = distribution_new_linear(6, 5), + .num_gauges = 10, + .gauges = (double[]){25, 30, 5, 7, 11, 10.5, 8.03, 1112.4, 35, 12.7}, + .want_counters = (uint64_t[]){0, 3, 3, 0, 0, 4}, + }, + { + .dist = distribution_new_exponential(4, 1.41, 1), + .num_gauges = 0, + .gauges = NULL, + .want_counters = (uint64_t[]){0, 0, 0, 0}, + }, + { + .dist = distribution_new_exponential(5, 2, 3), + .num_gauges = 5, + .gauges = (double[]){1, 7, 3, 10, 77}, + .want_counters = (uint64_t[]){1, 1, 2, 0, 1}, + }, + { + .dist = distribution_new_linear(100, 22), + .num_gauges = 3, + .gauges = (double[]){1000, 2, -8}, + .want_err = EINVAL, + }, + { + .dist = distribution_new_custom(3, (double[]){5, 20, 35}), + .num_gauges = 7, + .gauges = (double[]){7.05, 22.37, 40.83, 90.55, 12.34, 14.2, 6.0}, + .want_counters = (uint64_t[]){0, 4, 1, 2}, + }, }; for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { for (size_t j = 0; j < cases[i].num_gauges; j++) { @@ -336,7 +350,8 @@ DEF_TEST(update) { } buckets_array_t buckets_array = get_buckets(cases[i].dist); for (size_t j = 0; j < buckets_array.num_buckets; j++) { - EXPECT_EQ_INT(cases[i].want_counters[j], buckets_array.buckets[j].bucket_counter); + EXPECT_EQ_INT(cases[i].want_counters[j], + buckets_array.buckets[j].bucket_counter); } destroy_buckets_array(buckets_array); distribution_destroy(cases[i].dist); @@ -351,29 +366,30 @@ DEF_TEST(average) { double *update_gauges; double want_average; } cases[] = { - { - .dist = distribution_new_linear(6, 2), - .num_gauges = 0, - .want_average = NAN, - }, - { - .dist = distribution_new_linear(7, 10), - .num_gauges = 5, - .update_gauges = (double[]){3, 2, 5.7, 22.3, 7.5}, - .want_average = 40.5 / 5.0, - }, - { - .dist = distribution_new_exponential(10, 2, 0.75), - .num_gauges = 8, - .update_gauges = (double[]){2, 4, 6, 8, 22, 11, 77, 1005}, - .want_average = 1135.0 / 8.0, - }, - }; + { + .dist = distribution_new_linear(6, 2), + .num_gauges = 0, + .want_average = NAN, + }, + { + .dist = distribution_new_linear(7, 10), + .num_gauges = 5, + .update_gauges = (double[]){3, 2, 5.7, 22.3, 7.5}, + .want_average = 40.5 / 5.0, + }, + { + .dist = distribution_new_exponential(10, 2, 0.75), + .num_gauges = 8, + .update_gauges = (double[]){2, 4, 6, 8, 22, 11, 77, 1005}, + .want_average = 1135.0 / 8.0, + }, + }; for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { for (size_t j = 0; j < cases[i].num_gauges; j++) { distribution_update(cases[i].dist, cases[i].update_gauges[j]); } - EXPECT_EQ_DOUBLE(cases[i].want_average, distribution_average(cases[i].dist)); + EXPECT_EQ_DOUBLE(cases[i].want_average, + distribution_average(cases[i].dist)); distribution_destroy(cases[i].dist); } return 0; @@ -388,48 +404,49 @@ DEF_TEST(percentile) { double want_percentile; int want_err; } cases[] = { - { - .dist = distribution_new_linear(5, 7), - .num_gauges = 1, - .update_gauges = (double[]){4}, - .percent = 105, - .want_percentile = NAN, - .want_err = EINVAL, - }, - { - .dist = distribution_new_linear(8, 10), - .num_gauges = 0, - .percent = 20, - .want_percentile = NAN, - }, - { - .dist = distribution_new_exponential(5, 2, 0.2), - .num_gauges = 2, - .update_gauges = (double[]){4, 30.08}, - .percent = -5, - .want_percentile = NAN, - .want_err = EINVAL, - }, - { - .dist = distribution_new_exponential(10, 2, 0.75), - .num_gauges = 8, - .update_gauges = (double[]){2, 4, 6, 8, 22, 11, 77, 1005}, - .percent = 50, - .want_percentile = 12, - }, - { - .dist = distribution_new_custom(3, (double[]){5, 20, 35}), - .num_gauges = 7, - .update_gauges = (double[]){5.5, 10.5, 11.3, 6.7, 24.7, 40.05, 35}, - .percent = 4.0 / 7.0 * 100, - .want_percentile = 20, - }, + { + .dist = distribution_new_linear(5, 7), + .num_gauges = 1, + .update_gauges = (double[]){4}, + .percent = 105, + .want_percentile = NAN, + .want_err = EINVAL, + }, + { + .dist = distribution_new_linear(8, 10), + .num_gauges = 0, + .percent = 20, + .want_percentile = NAN, + }, + { + .dist = distribution_new_exponential(5, 2, 0.2), + .num_gauges = 2, + .update_gauges = (double[]){4, 30.08}, + .percent = -5, + .want_percentile = NAN, + .want_err = EINVAL, + }, + { + .dist = distribution_new_exponential(10, 2, 0.75), + .num_gauges = 8, + .update_gauges = (double[]){2, 4, 6, 8, 22, 11, 77, 1005}, + .percent = 50, + .want_percentile = 12, + }, + { + .dist = distribution_new_custom(3, (double[]){5, 20, 35}), + .num_gauges = 7, + .update_gauges = (double[]){5.5, 10.5, 11.3, 6.7, 24.7, 40.05, 35}, + .percent = 4.0 / 7.0 * 100, + .want_percentile = 20, + }, }; for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { for (size_t j = 0; j < cases[i].num_gauges; j++) { distribution_update(cases[i].dist, cases[i].update_gauges[j]); } - EXPECT_EQ_DOUBLE(cases[i].want_percentile, distribution_percentile(cases[i].dist, cases[i].percent)); + EXPECT_EQ_DOUBLE(cases[i].want_percentile, + distribution_percentile(cases[i].dist, cases[i].percent)); if (cases[i].want_err != 0) EXPECT_EQ_INT(cases[i].want_err, errno); distribution_destroy(cases[i].dist); @@ -455,7 +472,7 @@ DEF_TEST(clone) { int main() { RUN_TEST(distribution_new_linear); RUN_TEST(distribution_new_exponential); - RUN_TEST(distribution_new_custom); + RUN_TEST(distribution_new_custom); RUN_TEST(update); RUN_TEST(average); RUN_TEST(percentile);