#ifndef COLLECTD_DISTRIBUTION_H
#define COLLECTD_DISTRIBUTION_H
-#include <stdlib.h>
-#include <stdint.h>
+#include <errno.h>
#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
-#include <errno.h>
//#include "collectd.h"
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);
/**
* @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);
#include <unistd.h>
#include "distribution.h"
+#include <math.h>
#include <stdio.h>
#include <time.h>
-#include <math.h>
/* Macro to exit with an error. */
#define error(fmt, args...) \
const size_t iterations = 1000000;
const int dist_number = 3;
-static double * calculate_gauges_arr(double gauges[], size_t iterations) {
- for(size_t i = 0; i < iterations; i++) {
- gauges[i] = (double) (rand() % (int) 1e6);
- }
- return gauges;
+static double *calculate_gauges_arr(double gauges[], size_t iterations) {
+ for (size_t i = 0; i < iterations; i++) {
+ gauges[i] = (double)(rand() % (int)1e6);
+ }
+ return gauges;
}
-static double * calculate_percents_arr(double percents[], size_t iterations) {
- for(size_t i = 0; i < iterations; i++) {
- percents[i] = (double) (rand() % 101);
- }
- return percents;
+static double *calculate_percents_arr(double percents[], size_t iterations) {
+ for (size_t i = 0; i < iterations; i++) {
+ percents[i] = (double)(rand() % 101);
+ }
+ return percents;
}
-static size_t * calculate_dist_index_arr(size_t indexes[], size_t iterations) {
- for(size_t i = 0; i < iterations; i++) {
- indexes[i] = rand() % 3;
- }
- return indexes;
+static size_t *calculate_dist_index_arr(size_t indexes[], size_t iterations) {
+ for (size_t i = 0; i < iterations; i++) {
+ indexes[i] = rand() % 3;
+ }
+ return indexes;
}
double measure_update(distribution_t *dist, size_t iterations, double *gauges) {
- uint64_t start = get_clock();
- for(size_t i = 0; i < iterations; i++) {
- distribution_update(dist, gauges[i]);
- }
- uint64_t end = get_clock();
- double seconds = (end - start) / (double)(NANOS_PER_SEC);
- printf("%f, ", seconds);
- return seconds;
+ uint64_t start = get_clock();
+ for (size_t i = 0; i < iterations; i++) {
+ distribution_update(dist, gauges[i]);
+ }
+ uint64_t end = get_clock();
+ double seconds = (end - start) / (double)(NANOS_PER_SEC);
+ printf("%f, ", seconds);
+ return seconds;
}
-double measure_percentile(distribution_t *dist, size_t iterations, double *percents) {
- uint64_t start = get_clock();
- for(size_t i = 0; i < iterations; i++) {
- volatile double res = distribution_percentile(dist, percents[i]);
- (void)res;
- }
- uint64_t end = get_clock();
- double seconds = (end - start) / (double)(NANOS_PER_SEC);
- printf("%f, ", seconds);
- return seconds;
+double measure_percentile(distribution_t *dist, size_t iterations,
+ double *percents) {
+ uint64_t start = get_clock();
+ for (size_t i = 0; i < iterations; i++) {
+ volatile double res = distribution_percentile(dist, percents[i]);
+ (void)res;
+ }
+ uint64_t end = get_clock();
+ double seconds = (end - start) / (double)(NANOS_PER_SEC);
+ printf("%f, ", seconds);
+ return seconds;
}
-double measure_mixed(distribution_t *dist, size_t iterations, double *percents, double *gauges) {
- uint64_t start = get_clock();
- for(size_t i = 0; i < iterations; i++) {
- if (i % 10 == 0) {
- volatile double res = distribution_percentile(dist, percents[i]);
- (void)res;
- }
- else {
- distribution_update(dist, gauges[i]);
- }
+double measure_mixed(distribution_t *dist, size_t iterations, double *percents,
+ double *gauges) {
+ uint64_t start = get_clock();
+ for (size_t i = 0; i < iterations; i++) {
+ if (i % 10 == 0) {
+ volatile double res = distribution_percentile(dist, percents[i]);
+ (void)res;
+ } else {
+ distribution_update(dist, gauges[i]);
}
- uint64_t end = get_clock();
- double seconds = (end - start) / (double)(NANOS_PER_SEC);
- printf("%f, ", seconds);
- return seconds;
+ }
+ uint64_t end = get_clock();
+ double seconds = (end - start) / (double)(NANOS_PER_SEC);
+ printf("%f, ", seconds);
+ return seconds;
}
-double measure_update_all_dists(distribution_t **dists, size_t iterations, double *gauges, size_t *indexes) {
- uint64_t start = get_clock();
- for(size_t i = 0; i < iterations; i++) {
- distribution_update(dists[indexes[i]], gauges[i]);
- }
- uint64_t end = get_clock();
- double seconds = (end - start) / (double)(NANOS_PER_SEC);
- printf("%f, ", seconds);
- return seconds;
+double measure_update_all_dists(distribution_t **dists, size_t iterations,
+ double *gauges, size_t *indexes) {
+ uint64_t start = get_clock();
+ for (size_t i = 0; i < iterations; i++) {
+ distribution_update(dists[indexes[i]], gauges[i]);
+ }
+ uint64_t end = get_clock();
+ double seconds = (end - start) / (double)(NANOS_PER_SEC);
+ printf("%f, ", seconds);
+ return seconds;
}
-double measure_percentile_all_dists(distribution_t **dists, size_t iterations, double *percents, size_t *indexes) {
- uint64_t start = get_clock();
- for(size_t i = 0; i < iterations; i++) {
- volatile double res = distribution_percentile(dists[indexes[i]], percents[i]);
- (void)res;
- }
- uint64_t end = get_clock();
- double seconds = (end - start) / (double)(NANOS_PER_SEC);
- printf("%f, ", seconds);
- return seconds;
+double measure_percentile_all_dists(distribution_t **dists, size_t iterations,
+ double *percents, size_t *indexes) {
+ uint64_t start = get_clock();
+ for (size_t i = 0; i < iterations; i++) {
+ volatile double res =
+ distribution_percentile(dists[indexes[i]], percents[i]);
+ (void)res;
+ }
+ uint64_t end = get_clock();
+ double seconds = (end - start) / (double)(NANOS_PER_SEC);
+ printf("%f, ", seconds);
+ return seconds;
}
-double measure_mixed_all_dists(distribution_t **dists, size_t iterations, double *percents, double *gauges, size_t *indexes) {
- uint64_t start = get_clock();
- for(size_t i = 0; i < iterations; i++) {
- if (i % 10 == 0) {
- volatile double res = distribution_percentile(dists[indexes[i]], percents[i]);
- (void)res;
- }
- else {
- distribution_update(dists[indexes[i]], gauges[i]);
- }
+double measure_mixed_all_dists(distribution_t **dists, size_t iterations,
+ double *percents, double *gauges,
+ size_t *indexes) {
+ uint64_t start = get_clock();
+ for (size_t i = 0; i < iterations; i++) {
+ if (i % 10 == 0) {
+ volatile double res =
+ distribution_percentile(dists[indexes[i]], percents[i]);
+ (void)res;
+ } else {
+ distribution_update(dists[indexes[i]], gauges[i]);
}
- uint64_t end = get_clock();
- double seconds = (end - start) / (double)(NANOS_PER_SEC);
- printf("%f ", seconds);
- return seconds;
+ }
+ uint64_t end = get_clock();
+ double seconds = (end - start) / (double)(NANOS_PER_SEC);
+ printf("%f ", seconds);
+ return seconds;
}
int main(int argc, char **argv) {
- srand(1770);
- if (argc < 2) {
- printf("No bucket number found.\n");
- exit(EXIT_FAILURE);
- }
-
- int buckets_number = atoi(argv[1]);
- double buckets_size = 25;
-
- double *custom = malloc(sizeof(double) * buckets_number - 1);
- if(custom == NULL) {
- printf("Malloc failed.\n");
- exit(EXIT_FAILURE);
- }
-
- custom[0] = rand() % (100 + 1);
- for (size_t i = 1; i < buckets_number - 1; i++) {
- custom[i] = custom[i - 1] + rand() % 100 + 1;
- }
-
- distribution_t *dists[dist_number];
- dists[0] = distribution_new_linear(buckets_number, buckets_size);
- dists[1] = distribution_new_exponential(buckets_number, 3, 2);
- dists[2] = distribution_new_custom(buckets_number - 1, custom);
- free(custom);
-
- double *gauges = malloc(sizeof(double) * iterations);
- if(gauges == NULL) {
- printf("Malloc failed.\n");
- exit(EXIT_FAILURE);
- }
- gauges = calculate_gauges_arr(gauges, iterations);
-
- double *percents = malloc(sizeof(double) * iterations);
- if(percents == NULL) {
- printf("Malloc failed.\n");
- exit(EXIT_FAILURE);
- }
- percents = calculate_percents_arr(percents, iterations);
-
- size_t *indexes = malloc(sizeof(size_t) * iterations);
- if(indexes == NULL) {
- printf("Malloc failed.\n");
- exit(EXIT_FAILURE);
- }
- indexes = calculate_dist_index_arr(indexes, iterations);
-
- /*printf("Number of buckets,
- Update linear, Percentile linear, Mixed linear,
- Update exponential, Percentile exponential, Mixed exponential,
- Update custom, Percentile custom, Mixed custom,
- Update all, Percentile all, Mixed all");*/
-
- printf("%d, ", buckets_number);
- volatile double res = measure_update(dists[0], iterations, gauges);
- res = measure_percentile(dists[0], iterations, percents);
- res = measure_mixed(dists[0], iterations, percents, gauges);
-
- //printf("%d, ", buckets_number);
- res = measure_update(dists[1], iterations, gauges);
- res = measure_percentile(dists[1], iterations, percents);
- res = measure_mixed(dists[1], iterations, percents, gauges);
-
- //printf("%d, ", buckets_number);
- res = measure_update(dists[2], iterations, gauges);
- res = measure_percentile(dists[2], iterations, percents);
- res = measure_mixed(dists[2], iterations, percents, gauges);
-
- //printf("%d, ", buckets_number);
- res = measure_update_all_dists(dists, iterations, gauges, indexes);
- res = measure_percentile_all_dists(dists, iterations, gauges, indexes);
- res = measure_mixed_all_dists(dists, iterations, percents, gauges, indexes);
- (void)res;
- free(gauges);
- free(percents);
- free(indexes);
- for (size_t i = 0; i < dist_number; i++)
- distribution_destroy(dists[i]);
- printf("\n");
- return 0;
+ srand(1770);
+ if (argc < 2) {
+ printf("No bucket number found.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ int buckets_number = atoi(argv[1]);
+ double buckets_size = 25;
+
+ double *custom = malloc(sizeof(double) * buckets_number - 1);
+ if (custom == NULL) {
+ printf("Malloc failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ custom[0] = rand() % (100 + 1);
+ for (size_t i = 1; i < buckets_number - 1; i++) {
+ custom[i] = custom[i - 1] + rand() % 100 + 1;
+ }
+
+ distribution_t *dists[dist_number];
+ dists[0] = distribution_new_linear(buckets_number, buckets_size);
+ dists[1] = distribution_new_exponential(buckets_number, 3, 2);
+ dists[2] = distribution_new_custom(buckets_number - 1, custom);
+ free(custom);
+
+ double *gauges = malloc(sizeof(double) * iterations);
+ if (gauges == NULL) {
+ printf("Malloc failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ gauges = calculate_gauges_arr(gauges, iterations);
+
+ double *percents = malloc(sizeof(double) * iterations);
+ if (percents == NULL) {
+ printf("Malloc failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ percents = calculate_percents_arr(percents, iterations);
+
+ size_t *indexes = malloc(sizeof(size_t) * iterations);
+ if (indexes == NULL) {
+ printf("Malloc failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ indexes = calculate_dist_index_arr(indexes, iterations);
+
+ /*printf("Number of buckets,
+ Update linear, Percentile linear, Mixed linear,
+ Update exponential, Percentile exponential, Mixed exponential,
+ Update custom, Percentile custom, Mixed custom,
+ Update all, Percentile all, Mixed all");*/
+
+ printf("%d, ", buckets_number);
+ volatile double res = measure_update(dists[0], iterations, gauges);
+ res = measure_percentile(dists[0], iterations, percents);
+ res = measure_mixed(dists[0], iterations, percents, gauges);
+
+ // printf("%d, ", buckets_number);
+ res = measure_update(dists[1], iterations, gauges);
+ res = measure_percentile(dists[1], iterations, percents);
+ res = measure_mixed(dists[1], iterations, percents, gauges);
+
+ // printf("%d, ", buckets_number);
+ res = measure_update(dists[2], iterations, gauges);
+ res = measure_percentile(dists[2], iterations, percents);
+ res = measure_mixed(dists[2], iterations, percents, gauges);
+
+ // printf("%d, ", buckets_number);
+ res = measure_update_all_dists(dists, iterations, gauges, indexes);
+ res = measure_percentile_all_dists(dists, iterations, gauges, indexes);
+ res = measure_mixed_all_dists(dists, iterations, percents, gauges, indexes);
+ (void)res;
+ free(gauges);
+ free(percents);
+ free(indexes);
+ for (size_t i = 0; i < dist_number; i++)
+ distribution_destroy(dists[i]);
+ printf("\n");
+ return 0;
}