11cb0ef41Sopenharmony_ci/** 21cb0ef41Sopenharmony_ci * hdr_histogram.h 31cb0ef41Sopenharmony_ci * Written by Michael Barker and released to the public domain, 41cb0ef41Sopenharmony_ci * as explained at http://creativecommons.org/publicdomain/zero/1.0/ 51cb0ef41Sopenharmony_ci * 61cb0ef41Sopenharmony_ci * The source for the hdr_histogram utilises a few C99 constructs, specifically 71cb0ef41Sopenharmony_ci * the use of stdint/stdbool and inline variable declaration. 81cb0ef41Sopenharmony_ci */ 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci#ifndef HDR_HISTOGRAM_H 111cb0ef41Sopenharmony_ci#define HDR_HISTOGRAM_H 1 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci#include <stdint.h> 141cb0ef41Sopenharmony_ci#include <stdbool.h> 151cb0ef41Sopenharmony_ci#include <stdio.h> 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_cistruct hdr_histogram 181cb0ef41Sopenharmony_ci{ 191cb0ef41Sopenharmony_ci int64_t lowest_discernible_value; 201cb0ef41Sopenharmony_ci int64_t highest_trackable_value; 211cb0ef41Sopenharmony_ci int32_t unit_magnitude; 221cb0ef41Sopenharmony_ci int32_t significant_figures; 231cb0ef41Sopenharmony_ci int32_t sub_bucket_half_count_magnitude; 241cb0ef41Sopenharmony_ci int32_t sub_bucket_half_count; 251cb0ef41Sopenharmony_ci int64_t sub_bucket_mask; 261cb0ef41Sopenharmony_ci int32_t sub_bucket_count; 271cb0ef41Sopenharmony_ci int32_t bucket_count; 281cb0ef41Sopenharmony_ci int64_t min_value; 291cb0ef41Sopenharmony_ci int64_t max_value; 301cb0ef41Sopenharmony_ci int32_t normalizing_index_offset; 311cb0ef41Sopenharmony_ci double conversion_ratio; 321cb0ef41Sopenharmony_ci int32_t counts_len; 331cb0ef41Sopenharmony_ci int64_t total_count; 341cb0ef41Sopenharmony_ci int64_t* counts; 351cb0ef41Sopenharmony_ci}; 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci#ifdef __cplusplus 381cb0ef41Sopenharmony_ciextern "C" { 391cb0ef41Sopenharmony_ci#endif 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci/** 421cb0ef41Sopenharmony_ci * Allocate the memory and initialise the hdr_histogram. 431cb0ef41Sopenharmony_ci * 441cb0ef41Sopenharmony_ci * Due to the size of the histogram being the result of some reasonably 451cb0ef41Sopenharmony_ci * involved math on the input parameters this function it is tricky to stack allocate. 461cb0ef41Sopenharmony_ci * The histogram should be released with hdr_close 471cb0ef41Sopenharmony_ci * 481cb0ef41Sopenharmony_ci * @param lowest_discernible_value The smallest possible value that is distinguishable from 0. 491cb0ef41Sopenharmony_ci * Must be a positive integer that is >= 1. May be internally rounded down to nearest power of 2. 501cb0ef41Sopenharmony_ci * @param highest_trackable_value The largest possible value to be put into the 511cb0ef41Sopenharmony_ci * histogram. 521cb0ef41Sopenharmony_ci * @param significant_figures The level of precision for this histogram, i.e. the number 531cb0ef41Sopenharmony_ci * of figures in a decimal number that will be maintained. E.g. a value of 3 will mean 541cb0ef41Sopenharmony_ci * the results from the histogram will be accurate up to the first three digits. Must 551cb0ef41Sopenharmony_ci * be a value between 1 and 5 (inclusive). 561cb0ef41Sopenharmony_ci * @param result Output parameter to capture allocated histogram. 571cb0ef41Sopenharmony_ci * @return 0 on success, EINVAL if lowest_discernible_value is < 1 or the 581cb0ef41Sopenharmony_ci * significant_figure value is outside of the allowed range, ENOMEM if malloc 591cb0ef41Sopenharmony_ci * failed. 601cb0ef41Sopenharmony_ci */ 611cb0ef41Sopenharmony_ciint hdr_init( 621cb0ef41Sopenharmony_ci int64_t lowest_discernible_value, 631cb0ef41Sopenharmony_ci int64_t highest_trackable_value, 641cb0ef41Sopenharmony_ci int significant_figures, 651cb0ef41Sopenharmony_ci struct hdr_histogram** result); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci/** 681cb0ef41Sopenharmony_ci * Free the memory and close the hdr_histogram. 691cb0ef41Sopenharmony_ci * 701cb0ef41Sopenharmony_ci * @param h The histogram you want to close. 711cb0ef41Sopenharmony_ci */ 721cb0ef41Sopenharmony_civoid hdr_close(struct hdr_histogram* h); 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci/** 751cb0ef41Sopenharmony_ci * Allocate the memory and initialise the hdr_histogram. This is the equivalent of calling 761cb0ef41Sopenharmony_ci * hdr_init(1, highest_trackable_value, significant_figures, result); 771cb0ef41Sopenharmony_ci * 781cb0ef41Sopenharmony_ci * @deprecated use hdr_init. 791cb0ef41Sopenharmony_ci */ 801cb0ef41Sopenharmony_ciint hdr_alloc(int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result); 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci/** 841cb0ef41Sopenharmony_ci * Reset a histogram to zero - empty out a histogram and re-initialise it 851cb0ef41Sopenharmony_ci * 861cb0ef41Sopenharmony_ci * If you want to re-use an existing histogram, but reset everything back to zero, this 871cb0ef41Sopenharmony_ci * is the routine to use. 881cb0ef41Sopenharmony_ci * 891cb0ef41Sopenharmony_ci * @param h The histogram you want to reset to empty. 901cb0ef41Sopenharmony_ci * 911cb0ef41Sopenharmony_ci */ 921cb0ef41Sopenharmony_civoid hdr_reset(struct hdr_histogram* h); 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci/** 951cb0ef41Sopenharmony_ci * Get the memory size of the hdr_histogram. 961cb0ef41Sopenharmony_ci * 971cb0ef41Sopenharmony_ci * @param h "This" pointer 981cb0ef41Sopenharmony_ci * @return The amount of memory used by the hdr_histogram in bytes 991cb0ef41Sopenharmony_ci */ 1001cb0ef41Sopenharmony_cisize_t hdr_get_memory_size(struct hdr_histogram* h); 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci/** 1031cb0ef41Sopenharmony_ci * Records a value in the histogram, will round this value of to a precision at or better 1041cb0ef41Sopenharmony_ci * than the significant_figure specified at construction time. 1051cb0ef41Sopenharmony_ci * 1061cb0ef41Sopenharmony_ci * @param h "This" pointer 1071cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 1081cb0ef41Sopenharmony_ci * @return false if the value is larger than the highest_trackable_value and can't be recorded, 1091cb0ef41Sopenharmony_ci * true otherwise. 1101cb0ef41Sopenharmony_ci */ 1111cb0ef41Sopenharmony_cibool hdr_record_value(struct hdr_histogram* h, int64_t value); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ci/** 1141cb0ef41Sopenharmony_ci * Records a value in the histogram, will round this value of to a precision at or better 1151cb0ef41Sopenharmony_ci * than the significant_figure specified at construction time. 1161cb0ef41Sopenharmony_ci * 1171cb0ef41Sopenharmony_ci * Will record this value atomically, however the whole structure may appear inconsistent 1181cb0ef41Sopenharmony_ci * when read concurrently with this update. Do NOT mix calls to this method with calls 1191cb0ef41Sopenharmony_ci * to non-atomic updates. 1201cb0ef41Sopenharmony_ci * 1211cb0ef41Sopenharmony_ci * @param h "This" pointer 1221cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 1231cb0ef41Sopenharmony_ci * @return false if the value is larger than the highest_trackable_value and can't be recorded, 1241cb0ef41Sopenharmony_ci * true otherwise. 1251cb0ef41Sopenharmony_ci */ 1261cb0ef41Sopenharmony_cibool hdr_record_value_atomic(struct hdr_histogram* h, int64_t value); 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci/** 1291cb0ef41Sopenharmony_ci * Records count values in the histogram, will round this value of to a 1301cb0ef41Sopenharmony_ci * precision at or better than the significant_figure specified at construction 1311cb0ef41Sopenharmony_ci * time. 1321cb0ef41Sopenharmony_ci * 1331cb0ef41Sopenharmony_ci * @param h "This" pointer 1341cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 1351cb0ef41Sopenharmony_ci * @param count Number of 'value's to add to the histogram 1361cb0ef41Sopenharmony_ci * @return false if any value is larger than the highest_trackable_value and can't be recorded, 1371cb0ef41Sopenharmony_ci * true otherwise. 1381cb0ef41Sopenharmony_ci */ 1391cb0ef41Sopenharmony_cibool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count); 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci/** 1421cb0ef41Sopenharmony_ci * Records count values in the histogram, will round this value of to a 1431cb0ef41Sopenharmony_ci * precision at or better than the significant_figure specified at construction 1441cb0ef41Sopenharmony_ci * time. 1451cb0ef41Sopenharmony_ci * 1461cb0ef41Sopenharmony_ci * Will record this value atomically, however the whole structure may appear inconsistent 1471cb0ef41Sopenharmony_ci * when read concurrently with this update. Do NOT mix calls to this method with calls 1481cb0ef41Sopenharmony_ci * to non-atomic updates. 1491cb0ef41Sopenharmony_ci * 1501cb0ef41Sopenharmony_ci * @param h "This" pointer 1511cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 1521cb0ef41Sopenharmony_ci * @param count Number of 'value's to add to the histogram 1531cb0ef41Sopenharmony_ci * @return false if any value is larger than the highest_trackable_value and can't be recorded, 1541cb0ef41Sopenharmony_ci * true otherwise. 1551cb0ef41Sopenharmony_ci */ 1561cb0ef41Sopenharmony_cibool hdr_record_values_atomic(struct hdr_histogram* h, int64_t value, int64_t count); 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_ci/** 1591cb0ef41Sopenharmony_ci * Record a value in the histogram and backfill based on an expected interval. 1601cb0ef41Sopenharmony_ci * 1611cb0ef41Sopenharmony_ci * Records a value in the histogram, will round this value of to a precision at or better 1621cb0ef41Sopenharmony_ci * than the significant_figure specified at construction time. This is specifically used 1631cb0ef41Sopenharmony_ci * for recording latency. If the value is larger than the expected_interval then the 1641cb0ef41Sopenharmony_ci * latency recording system has experienced co-ordinated omission. This method fills in the 1651cb0ef41Sopenharmony_ci * values that would have occurred had the client providing the load not been blocked. 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci * @param h "This" pointer 1681cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 1691cb0ef41Sopenharmony_ci * @param expected_interval The delay between recording values. 1701cb0ef41Sopenharmony_ci * @return false if the value is larger than the highest_trackable_value and can't be recorded, 1711cb0ef41Sopenharmony_ci * true otherwise. 1721cb0ef41Sopenharmony_ci */ 1731cb0ef41Sopenharmony_cibool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expected_interval); 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci/** 1761cb0ef41Sopenharmony_ci * Record a value in the histogram and backfill based on an expected interval. 1771cb0ef41Sopenharmony_ci * 1781cb0ef41Sopenharmony_ci * Records a value in the histogram, will round this value of to a precision at or better 1791cb0ef41Sopenharmony_ci * than the significant_figure specified at construction time. This is specifically used 1801cb0ef41Sopenharmony_ci * for recording latency. If the value is larger than the expected_interval then the 1811cb0ef41Sopenharmony_ci * latency recording system has experienced co-ordinated omission. This method fills in the 1821cb0ef41Sopenharmony_ci * values that would have occurred had the client providing the load not been blocked. 1831cb0ef41Sopenharmony_ci * 1841cb0ef41Sopenharmony_ci * Will record this value atomically, however the whole structure may appear inconsistent 1851cb0ef41Sopenharmony_ci * when read concurrently with this update. Do NOT mix calls to this method with calls 1861cb0ef41Sopenharmony_ci * to non-atomic updates. 1871cb0ef41Sopenharmony_ci * 1881cb0ef41Sopenharmony_ci * @param h "This" pointer 1891cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 1901cb0ef41Sopenharmony_ci * @param expected_interval The delay between recording values. 1911cb0ef41Sopenharmony_ci * @return false if the value is larger than the highest_trackable_value and can't be recorded, 1921cb0ef41Sopenharmony_ci * true otherwise. 1931cb0ef41Sopenharmony_ci */ 1941cb0ef41Sopenharmony_cibool hdr_record_corrected_value_atomic(struct hdr_histogram* h, int64_t value, int64_t expected_interval); 1951cb0ef41Sopenharmony_ci 1961cb0ef41Sopenharmony_ci/** 1971cb0ef41Sopenharmony_ci * Record a value in the histogram 'count' times. Applies the same correcting logic 1981cb0ef41Sopenharmony_ci * as 'hdr_record_corrected_value'. 1991cb0ef41Sopenharmony_ci * 2001cb0ef41Sopenharmony_ci * @param h "This" pointer 2011cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 2021cb0ef41Sopenharmony_ci * @param count Number of 'value's to add to the histogram 2031cb0ef41Sopenharmony_ci * @param expected_interval The delay between recording values. 2041cb0ef41Sopenharmony_ci * @return false if the value is larger than the highest_trackable_value and can't be recorded, 2051cb0ef41Sopenharmony_ci * true otherwise. 2061cb0ef41Sopenharmony_ci */ 2071cb0ef41Sopenharmony_cibool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci/** 2101cb0ef41Sopenharmony_ci * Record a value in the histogram 'count' times. Applies the same correcting logic 2111cb0ef41Sopenharmony_ci * as 'hdr_record_corrected_value'. 2121cb0ef41Sopenharmony_ci * 2131cb0ef41Sopenharmony_ci * Will record this value atomically, however the whole structure may appear inconsistent 2141cb0ef41Sopenharmony_ci * when read concurrently with this update. Do NOT mix calls to this method with calls 2151cb0ef41Sopenharmony_ci * to non-atomic updates. 2161cb0ef41Sopenharmony_ci * 2171cb0ef41Sopenharmony_ci * @param h "This" pointer 2181cb0ef41Sopenharmony_ci * @param value Value to add to the histogram 2191cb0ef41Sopenharmony_ci * @param count Number of 'value's to add to the histogram 2201cb0ef41Sopenharmony_ci * @param expected_interval The delay between recording values. 2211cb0ef41Sopenharmony_ci * @return false if the value is larger than the highest_trackable_value and can't be recorded, 2221cb0ef41Sopenharmony_ci * true otherwise. 2231cb0ef41Sopenharmony_ci */ 2241cb0ef41Sopenharmony_cibool hdr_record_corrected_values_atomic(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval); 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci/** 2271cb0ef41Sopenharmony_ci * Adds all of the values from 'from' to 'this' histogram. Will return the 2281cb0ef41Sopenharmony_ci * number of values that are dropped when copying. Values will be dropped 2291cb0ef41Sopenharmony_ci * if they around outside of h.lowest_discernible_value and 2301cb0ef41Sopenharmony_ci * h.highest_trackable_value. 2311cb0ef41Sopenharmony_ci * 2321cb0ef41Sopenharmony_ci * @param h "This" pointer 2331cb0ef41Sopenharmony_ci * @param from Histogram to copy values from. 2341cb0ef41Sopenharmony_ci * @return The number of values dropped when copying. 2351cb0ef41Sopenharmony_ci */ 2361cb0ef41Sopenharmony_ciint64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from); 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci/** 2391cb0ef41Sopenharmony_ci * Adds all of the values from 'from' to 'this' histogram. Will return the 2401cb0ef41Sopenharmony_ci * number of values that are dropped when copying. Values will be dropped 2411cb0ef41Sopenharmony_ci * if they around outside of h.lowest_discernible_value and 2421cb0ef41Sopenharmony_ci * h.highest_trackable_value. 2431cb0ef41Sopenharmony_ci * 2441cb0ef41Sopenharmony_ci * @param h "This" pointer 2451cb0ef41Sopenharmony_ci * @param from Histogram to copy values from. 2461cb0ef41Sopenharmony_ci * @return The number of values dropped when copying. 2471cb0ef41Sopenharmony_ci */ 2481cb0ef41Sopenharmony_ciint64_t hdr_add_while_correcting_for_coordinated_omission( 2491cb0ef41Sopenharmony_ci struct hdr_histogram* h, struct hdr_histogram* from, int64_t expected_interval); 2501cb0ef41Sopenharmony_ci 2511cb0ef41Sopenharmony_ci/** 2521cb0ef41Sopenharmony_ci * Get minimum value from the histogram. Will return 2^63-1 if the histogram 2531cb0ef41Sopenharmony_ci * is empty. 2541cb0ef41Sopenharmony_ci * 2551cb0ef41Sopenharmony_ci * @param h "This" pointer 2561cb0ef41Sopenharmony_ci */ 2571cb0ef41Sopenharmony_ciint64_t hdr_min(const struct hdr_histogram* h); 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci/** 2601cb0ef41Sopenharmony_ci * Get maximum value from the histogram. Will return 0 if the histogram 2611cb0ef41Sopenharmony_ci * is empty. 2621cb0ef41Sopenharmony_ci * 2631cb0ef41Sopenharmony_ci * @param h "This" pointer 2641cb0ef41Sopenharmony_ci */ 2651cb0ef41Sopenharmony_ciint64_t hdr_max(const struct hdr_histogram* h); 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci/** 2681cb0ef41Sopenharmony_ci * Get the value at a specific percentile. 2691cb0ef41Sopenharmony_ci * 2701cb0ef41Sopenharmony_ci * @param h "This" pointer. 2711cb0ef41Sopenharmony_ci * @param percentile The percentile to get the value for 2721cb0ef41Sopenharmony_ci */ 2731cb0ef41Sopenharmony_ciint64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile); 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ci/** 2761cb0ef41Sopenharmony_ci * Get the values at the given percentiles. 2771cb0ef41Sopenharmony_ci * 2781cb0ef41Sopenharmony_ci * @param h "This" pointer. 2791cb0ef41Sopenharmony_ci * @param percentiles The ordered percentiles array to get the values for. 2801cb0ef41Sopenharmony_ci * @param length Number of elements in the arrays. 2811cb0ef41Sopenharmony_ci * @param values Destination array containing the values at the given percentiles. 2821cb0ef41Sopenharmony_ci * The values array should be allocated by the caller. 2831cb0ef41Sopenharmony_ci * @return 0 on success, ENOMEM if the provided destination array is null. 2841cb0ef41Sopenharmony_ci */ 2851cb0ef41Sopenharmony_ciint hdr_value_at_percentiles(const struct hdr_histogram *h, const double *percentiles, int64_t *values, size_t length); 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ci/** 2881cb0ef41Sopenharmony_ci * Gets the standard deviation for the values in the histogram. 2891cb0ef41Sopenharmony_ci * 2901cb0ef41Sopenharmony_ci * @param h "This" pointer 2911cb0ef41Sopenharmony_ci * @return The standard deviation 2921cb0ef41Sopenharmony_ci */ 2931cb0ef41Sopenharmony_cidouble hdr_stddev(const struct hdr_histogram* h); 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci/** 2961cb0ef41Sopenharmony_ci * Gets the mean for the values in the histogram. 2971cb0ef41Sopenharmony_ci * 2981cb0ef41Sopenharmony_ci * @param h "This" pointer 2991cb0ef41Sopenharmony_ci * @return The mean 3001cb0ef41Sopenharmony_ci */ 3011cb0ef41Sopenharmony_cidouble hdr_mean(const struct hdr_histogram* h); 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci/** 3041cb0ef41Sopenharmony_ci * Determine if two values are equivalent with the histogram's resolution. 3051cb0ef41Sopenharmony_ci * Where "equivalent" means that value samples recorded for any two 3061cb0ef41Sopenharmony_ci * equivalent values are counted in a common total count. 3071cb0ef41Sopenharmony_ci * 3081cb0ef41Sopenharmony_ci * @param h "This" pointer 3091cb0ef41Sopenharmony_ci * @param a first value to compare 3101cb0ef41Sopenharmony_ci * @param b second value to compare 3111cb0ef41Sopenharmony_ci * @return 'true' if values are equivalent with the histogram's resolution. 3121cb0ef41Sopenharmony_ci */ 3131cb0ef41Sopenharmony_cibool hdr_values_are_equivalent(const struct hdr_histogram* h, int64_t a, int64_t b); 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci/** 3161cb0ef41Sopenharmony_ci * Get the lowest value that is equivalent to the given value within the histogram's resolution. 3171cb0ef41Sopenharmony_ci * Where "equivalent" means that value samples recorded for any two 3181cb0ef41Sopenharmony_ci * equivalent values are counted in a common total count. 3191cb0ef41Sopenharmony_ci * 3201cb0ef41Sopenharmony_ci * @param h "This" pointer 3211cb0ef41Sopenharmony_ci * @param value The given value 3221cb0ef41Sopenharmony_ci * @return The lowest value that is equivalent to the given value within the histogram's resolution. 3231cb0ef41Sopenharmony_ci */ 3241cb0ef41Sopenharmony_ciint64_t hdr_lowest_equivalent_value(const struct hdr_histogram* h, int64_t value); 3251cb0ef41Sopenharmony_ci 3261cb0ef41Sopenharmony_ci/** 3271cb0ef41Sopenharmony_ci * Get the count of recorded values at a specific value 3281cb0ef41Sopenharmony_ci * (to within the histogram resolution at the value level). 3291cb0ef41Sopenharmony_ci * 3301cb0ef41Sopenharmony_ci * @param h "This" pointer 3311cb0ef41Sopenharmony_ci * @param value The value for which to provide the recorded count 3321cb0ef41Sopenharmony_ci * @return The total count of values recorded in the histogram within the value range that is 3331cb0ef41Sopenharmony_ci * {@literal >=} lowestEquivalentValue(<i>value</i>) and {@literal <=} highestEquivalentValue(<i>value</i>) 3341cb0ef41Sopenharmony_ci */ 3351cb0ef41Sopenharmony_ciint64_t hdr_count_at_value(const struct hdr_histogram* h, int64_t value); 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ciint64_t hdr_count_at_index(const struct hdr_histogram* h, int32_t index); 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ciint64_t hdr_value_at_index(const struct hdr_histogram* h, int32_t index); 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_cistruct hdr_iter_percentiles 3421cb0ef41Sopenharmony_ci{ 3431cb0ef41Sopenharmony_ci bool seen_last_value; 3441cb0ef41Sopenharmony_ci int32_t ticks_per_half_distance; 3451cb0ef41Sopenharmony_ci double percentile_to_iterate_to; 3461cb0ef41Sopenharmony_ci double percentile; 3471cb0ef41Sopenharmony_ci}; 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_cistruct hdr_iter_recorded 3501cb0ef41Sopenharmony_ci{ 3511cb0ef41Sopenharmony_ci int64_t count_added_in_this_iteration_step; 3521cb0ef41Sopenharmony_ci}; 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_cistruct hdr_iter_linear 3551cb0ef41Sopenharmony_ci{ 3561cb0ef41Sopenharmony_ci int64_t value_units_per_bucket; 3571cb0ef41Sopenharmony_ci int64_t count_added_in_this_iteration_step; 3581cb0ef41Sopenharmony_ci int64_t next_value_reporting_level; 3591cb0ef41Sopenharmony_ci int64_t next_value_reporting_level_lowest_equivalent; 3601cb0ef41Sopenharmony_ci}; 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_cistruct hdr_iter_log 3631cb0ef41Sopenharmony_ci{ 3641cb0ef41Sopenharmony_ci double log_base; 3651cb0ef41Sopenharmony_ci int64_t count_added_in_this_iteration_step; 3661cb0ef41Sopenharmony_ci int64_t next_value_reporting_level; 3671cb0ef41Sopenharmony_ci int64_t next_value_reporting_level_lowest_equivalent; 3681cb0ef41Sopenharmony_ci}; 3691cb0ef41Sopenharmony_ci 3701cb0ef41Sopenharmony_ci/** 3711cb0ef41Sopenharmony_ci * The basic iterator. This is a generic structure 3721cb0ef41Sopenharmony_ci * that supports all of the types of iteration. Use 3731cb0ef41Sopenharmony_ci * the appropriate initialiser to get the desired 3741cb0ef41Sopenharmony_ci * iteration. 3751cb0ef41Sopenharmony_ci * 3761cb0ef41Sopenharmony_ci * @ 3771cb0ef41Sopenharmony_ci */ 3781cb0ef41Sopenharmony_cistruct hdr_iter 3791cb0ef41Sopenharmony_ci{ 3801cb0ef41Sopenharmony_ci const struct hdr_histogram* h; 3811cb0ef41Sopenharmony_ci /** raw index into the counts array */ 3821cb0ef41Sopenharmony_ci int32_t counts_index; 3831cb0ef41Sopenharmony_ci /** snapshot of the length at the time the iterator is created */ 3841cb0ef41Sopenharmony_ci int64_t total_count; 3851cb0ef41Sopenharmony_ci /** value directly from array for the current counts_index */ 3861cb0ef41Sopenharmony_ci int64_t count; 3871cb0ef41Sopenharmony_ci /** sum of all of the counts up to and including the count at this index */ 3881cb0ef41Sopenharmony_ci int64_t cumulative_count; 3891cb0ef41Sopenharmony_ci /** The current value based on counts_index */ 3901cb0ef41Sopenharmony_ci int64_t value; 3911cb0ef41Sopenharmony_ci int64_t highest_equivalent_value; 3921cb0ef41Sopenharmony_ci int64_t lowest_equivalent_value; 3931cb0ef41Sopenharmony_ci int64_t median_equivalent_value; 3941cb0ef41Sopenharmony_ci int64_t value_iterated_from; 3951cb0ef41Sopenharmony_ci int64_t value_iterated_to; 3961cb0ef41Sopenharmony_ci 3971cb0ef41Sopenharmony_ci union 3981cb0ef41Sopenharmony_ci { 3991cb0ef41Sopenharmony_ci struct hdr_iter_percentiles percentiles; 4001cb0ef41Sopenharmony_ci struct hdr_iter_recorded recorded; 4011cb0ef41Sopenharmony_ci struct hdr_iter_linear linear; 4021cb0ef41Sopenharmony_ci struct hdr_iter_log log; 4031cb0ef41Sopenharmony_ci } specifics; 4041cb0ef41Sopenharmony_ci 4051cb0ef41Sopenharmony_ci bool (* _next_fp)(struct hdr_iter* iter); 4061cb0ef41Sopenharmony_ci 4071cb0ef41Sopenharmony_ci}; 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci/** 4101cb0ef41Sopenharmony_ci * Initalises the basic iterator. 4111cb0ef41Sopenharmony_ci * 4121cb0ef41Sopenharmony_ci * @param itr 'This' pointer 4131cb0ef41Sopenharmony_ci * @param h The histogram to iterate over 4141cb0ef41Sopenharmony_ci */ 4151cb0ef41Sopenharmony_civoid hdr_iter_init(struct hdr_iter* iter, const struct hdr_histogram* h); 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci/** 4181cb0ef41Sopenharmony_ci * Initialise the iterator for use with percentiles. 4191cb0ef41Sopenharmony_ci */ 4201cb0ef41Sopenharmony_civoid hdr_iter_percentile_init(struct hdr_iter* iter, const struct hdr_histogram* h, int32_t ticks_per_half_distance); 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_ci/** 4231cb0ef41Sopenharmony_ci * Initialise the iterator for use with recorded values. 4241cb0ef41Sopenharmony_ci */ 4251cb0ef41Sopenharmony_civoid hdr_iter_recorded_init(struct hdr_iter* iter, const struct hdr_histogram* h); 4261cb0ef41Sopenharmony_ci 4271cb0ef41Sopenharmony_ci/** 4281cb0ef41Sopenharmony_ci * Initialise the iterator for use with linear values. 4291cb0ef41Sopenharmony_ci */ 4301cb0ef41Sopenharmony_civoid hdr_iter_linear_init( 4311cb0ef41Sopenharmony_ci struct hdr_iter* iter, 4321cb0ef41Sopenharmony_ci const struct hdr_histogram* h, 4331cb0ef41Sopenharmony_ci int64_t value_units_per_bucket); 4341cb0ef41Sopenharmony_ci 4351cb0ef41Sopenharmony_ci/** 4361cb0ef41Sopenharmony_ci * Initialise the iterator for use with logarithmic values 4371cb0ef41Sopenharmony_ci */ 4381cb0ef41Sopenharmony_civoid hdr_iter_log_init( 4391cb0ef41Sopenharmony_ci struct hdr_iter* iter, 4401cb0ef41Sopenharmony_ci const struct hdr_histogram* h, 4411cb0ef41Sopenharmony_ci int64_t value_units_first_bucket, 4421cb0ef41Sopenharmony_ci double log_base); 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ci/** 4451cb0ef41Sopenharmony_ci * Iterate to the next value for the iterator. If there are no more values 4461cb0ef41Sopenharmony_ci * available return faluse. 4471cb0ef41Sopenharmony_ci * 4481cb0ef41Sopenharmony_ci * @param itr 'This' pointer 4491cb0ef41Sopenharmony_ci * @return 'false' if there are no values remaining for this iterator. 4501cb0ef41Sopenharmony_ci */ 4511cb0ef41Sopenharmony_cibool hdr_iter_next(struct hdr_iter* iter); 4521cb0ef41Sopenharmony_ci 4531cb0ef41Sopenharmony_citypedef enum 4541cb0ef41Sopenharmony_ci{ 4551cb0ef41Sopenharmony_ci CLASSIC, 4561cb0ef41Sopenharmony_ci CSV 4571cb0ef41Sopenharmony_ci} format_type; 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ci/** 4601cb0ef41Sopenharmony_ci * Print out a percentile based histogram to the supplied stream. Note that 4611cb0ef41Sopenharmony_ci * this call will not flush the FILE, this is left up to the user. 4621cb0ef41Sopenharmony_ci * 4631cb0ef41Sopenharmony_ci * @param h 'This' pointer 4641cb0ef41Sopenharmony_ci * @param stream The FILE to write the output to 4651cb0ef41Sopenharmony_ci * @param ticks_per_half_distance The number of iteration steps per half-distance to 100% 4661cb0ef41Sopenharmony_ci * @param value_scale Scale the output values by this amount 4671cb0ef41Sopenharmony_ci * @param format_type Format to use, e.g. CSV. 4681cb0ef41Sopenharmony_ci * @return 0 on success, error code on failure. EIO if an error occurs writing 4691cb0ef41Sopenharmony_ci * the output. 4701cb0ef41Sopenharmony_ci */ 4711cb0ef41Sopenharmony_ciint hdr_percentiles_print( 4721cb0ef41Sopenharmony_ci struct hdr_histogram* h, FILE* stream, int32_t ticks_per_half_distance, 4731cb0ef41Sopenharmony_ci double value_scale, format_type format); 4741cb0ef41Sopenharmony_ci 4751cb0ef41Sopenharmony_ci/** 4761cb0ef41Sopenharmony_ci* Internal allocation methods, used by hdr_dbl_histogram. 4771cb0ef41Sopenharmony_ci*/ 4781cb0ef41Sopenharmony_cistruct hdr_histogram_bucket_config 4791cb0ef41Sopenharmony_ci{ 4801cb0ef41Sopenharmony_ci int64_t lowest_discernible_value; 4811cb0ef41Sopenharmony_ci int64_t highest_trackable_value; 4821cb0ef41Sopenharmony_ci int64_t unit_magnitude; 4831cb0ef41Sopenharmony_ci int64_t significant_figures; 4841cb0ef41Sopenharmony_ci int32_t sub_bucket_half_count_magnitude; 4851cb0ef41Sopenharmony_ci int32_t sub_bucket_half_count; 4861cb0ef41Sopenharmony_ci int64_t sub_bucket_mask; 4871cb0ef41Sopenharmony_ci int32_t sub_bucket_count; 4881cb0ef41Sopenharmony_ci int32_t bucket_count; 4891cb0ef41Sopenharmony_ci int32_t counts_len; 4901cb0ef41Sopenharmony_ci}; 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ciint hdr_calculate_bucket_config( 4931cb0ef41Sopenharmony_ci int64_t lowest_discernible_value, 4941cb0ef41Sopenharmony_ci int64_t highest_trackable_value, 4951cb0ef41Sopenharmony_ci int significant_figures, 4961cb0ef41Sopenharmony_ci struct hdr_histogram_bucket_config* cfg); 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_civoid hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_config* cfg); 4991cb0ef41Sopenharmony_ci 5001cb0ef41Sopenharmony_ciint64_t hdr_size_of_equivalent_value_range(const struct hdr_histogram* h, int64_t value); 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ciint64_t hdr_next_non_equivalent_value(const struct hdr_histogram* h, int64_t value); 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ciint64_t hdr_median_equivalent_value(const struct hdr_histogram* h, int64_t value); 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci/** 5071cb0ef41Sopenharmony_ci * Used to reset counters after importing data manually into the histogram, used by the logging code 5081cb0ef41Sopenharmony_ci * and other custom serialisation tools. 5091cb0ef41Sopenharmony_ci */ 5101cb0ef41Sopenharmony_civoid hdr_reset_internal_counters(struct hdr_histogram* h); 5111cb0ef41Sopenharmony_ci 5121cb0ef41Sopenharmony_ci#ifdef __cplusplus 5131cb0ef41Sopenharmony_ci} 5141cb0ef41Sopenharmony_ci#endif 5151cb0ef41Sopenharmony_ci 5161cb0ef41Sopenharmony_ci#endif 517