* 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,
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) {
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) {
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;
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,
};
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;
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) {
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);
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));
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++;
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) {
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) {
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;
}
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) {
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;
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include <math.h>
#include "distribution.h"
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;
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);
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) {
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) {
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;
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);
}
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) {
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);
}
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);
}
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);
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++) {
}
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);
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;
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);
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);