mirror of https://github.com/redis/redis.git
The code is based on upstream https://github.com/HdrHistogram/HdrHistogram_c master branch latest commit (e4448cf6d1cd08fff519812d3b1e58bd5a94ac42). The reason to pull this in now is that their final version of our optimization is even faster. See: https://github.com/HdrHistogram/HdrHistogram_c/pull/107.
This commit is contained in:
parent
18cb4a7d93
commit
cb6933e346
|
@ -100,8 +100,8 @@ Hdr_Histogram
|
||||||
---
|
---
|
||||||
|
|
||||||
Updated source can be found here: https://github.com/HdrHistogram/HdrHistogram_c
|
Updated source can be found here: https://github.com/HdrHistogram/HdrHistogram_c
|
||||||
We use a customized version 0.11.5
|
We use a customized version based on master branch commit e4448cf6d1cd08fff519812d3b1e58bd5a94ac42.
|
||||||
1. Compare all changes under /hdr_histogram directory to version 0.11.5
|
1. Compare all changes under /hdr_histogram directory to upstream master commit e4448cf6d1cd08fff519812d3b1e58bd5a94ac42
|
||||||
2. Copy updated files from newer version onto files in /hdr_histogram.
|
2. Copy updated files from newer version onto files in /hdr_histogram.
|
||||||
3. Apply the changes from 1 above to the updated files.
|
3. Apply the changes from 1 above to the updated files.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,78 @@
|
||||||
HdrHistogram_c v0.11.5
|
HdrHistogram_c: 'C' port of High Dynamic Range (HDR) Histogram
|
||||||
|
|
||||||
|
HdrHistogram
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
This port contains a subset of the 'C' version of High Dynamic Range (HDR) Histogram available at [github.com/HdrHistogram/HdrHistogram_c](https://github.com/HdrHistogram/HdrHistogram_c).
|
[](https://gitter.im/HdrHistogram/HdrHistogram)
|
||||||
|
|
||||||
|
This port contains a subset of the functionality supported by the Java
|
||||||
|
implementation. The current supported features are:
|
||||||
|
|
||||||
The code present on `hdr_histogram.c`, `hdr_histogram.h`, and `hdr_atomic.c` was Written by Gil Tene, Michael Barker,
|
* Standard histogram with 64 bit counts (32/16 bit counts not supported)
|
||||||
and Matt Warren, and released to the public domain, as explained at
|
* All iterator types (all values, recorded, percentiles, linear, logarithmic)
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/.
|
* Histogram serialisation (encoding version 1.2, decoding 1.0-1.2)
|
||||||
|
* Reader/writer phaser and interval recorder
|
||||||
|
|
||||||
|
Features not supported, but planned
|
||||||
|
|
||||||
|
* Auto-resizing of histograms
|
||||||
|
|
||||||
|
Features unlikely to be implemented
|
||||||
|
|
||||||
|
* Double histograms
|
||||||
|
* Atomic/Concurrent histograms
|
||||||
|
* 16/32 bit histograms
|
||||||
|
|
||||||
|
# Simple Tutorial
|
||||||
|
|
||||||
|
## Recording values
|
||||||
|
|
||||||
|
```C
|
||||||
|
#include <hdr_histogram.h>
|
||||||
|
|
||||||
|
struct hdr_histogram* histogram;
|
||||||
|
|
||||||
|
// Initialise the histogram
|
||||||
|
hdr_init(
|
||||||
|
1, // Minimum value
|
||||||
|
INT64_C(3600000000), // Maximum value
|
||||||
|
3, // Number of significant figures
|
||||||
|
&histogram) // Pointer to initialise
|
||||||
|
|
||||||
|
// Record value
|
||||||
|
hdr_record_value(
|
||||||
|
histogram, // Histogram to record to
|
||||||
|
value) // Value to record
|
||||||
|
|
||||||
|
// Record value n times
|
||||||
|
hdr_record_values(
|
||||||
|
histogram, // Histogram to record to
|
||||||
|
value, // Value to record
|
||||||
|
10) // Record value 10 times
|
||||||
|
|
||||||
|
// Record value with correction for co-ordinated omission.
|
||||||
|
hdr_record_corrected_value(
|
||||||
|
histogram, // Histogram to record to
|
||||||
|
value, // Value to record
|
||||||
|
1000) // Record with expected interval of 1000.
|
||||||
|
|
||||||
|
// Print out the values of the histogram
|
||||||
|
hdr_percentiles_print(
|
||||||
|
histogram,
|
||||||
|
stdout, // File to write to
|
||||||
|
5, // Granularity of printed values
|
||||||
|
1.0, // Multiplier for results
|
||||||
|
CLASSIC); // Format CLASSIC/CSV supported.
|
||||||
|
```
|
||||||
|
|
||||||
|
## More examples
|
||||||
|
|
||||||
|
For more detailed examples of recording and logging results look at the
|
||||||
|
[hdr_decoder](examples/hdr_decoder.c)
|
||||||
|
and [hiccup](examples/hiccup.c)
|
||||||
|
examples. You can run hiccup and decoder
|
||||||
|
and pipe the results of one into the other.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./examples/hiccup | ./examples/hdr_decoder
|
||||||
|
```
|
||||||
|
|
|
@ -165,16 +165,6 @@ static int32_t count_leading_zeros_64(int64_t value)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t get_count_at_index_given_bucket_base_idx(const struct hdr_histogram* h, int32_t bucket_base_idx, int32_t sub_bucket_idx)
|
|
||||||
{
|
|
||||||
return h->counts[(bucket_base_idx + sub_bucket_idx) - h->sub_bucket_half_count];
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t get_bucket_base_index(const struct hdr_histogram* h, int32_t bucket_index)
|
|
||||||
{
|
|
||||||
return (bucket_index + 1) << h->sub_bucket_half_count_magnitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int32_t get_bucket_index(const struct hdr_histogram* h, int64_t value)
|
static int32_t get_bucket_index(const struct hdr_histogram* h, int64_t value)
|
||||||
{
|
{
|
||||||
int32_t pow2ceiling = 64 - count_leading_zeros_64(value | h->sub_bucket_mask); /* smallest power of 2 containing value */
|
int32_t pow2ceiling = 64 - count_leading_zeros_64(value | h->sub_bucket_mask); /* smallest power of 2 containing value */
|
||||||
|
@ -679,33 +669,21 @@ int64_t hdr_min(const struct hdr_histogram* h)
|
||||||
static int64_t get_value_from_idx_up_to_count(const struct hdr_histogram* h, int64_t count_at_percentile)
|
static int64_t get_value_from_idx_up_to_count(const struct hdr_histogram* h, int64_t count_at_percentile)
|
||||||
{
|
{
|
||||||
int64_t count_to_idx = 0;
|
int64_t count_to_idx = 0;
|
||||||
int64_t value_from_idx = 0;
|
|
||||||
int32_t sub_bucket_idx = -1;
|
|
||||||
int32_t bucket_idx = 0;
|
|
||||||
int32_t bucket_base_idx = get_bucket_base_index(h, bucket_idx);
|
|
||||||
|
|
||||||
// Overflow check
|
count_at_percentile = 0 < count_at_percentile ? count_at_percentile : 1;
|
||||||
if (count_at_percentile > h->total_count)
|
for (int32_t idx = 0; idx < h->counts_len; idx++)
|
||||||
{
|
{
|
||||||
count_at_percentile = h->total_count;
|
count_to_idx += h->counts[idx];
|
||||||
}
|
if (count_to_idx >= count_at_percentile)
|
||||||
|
|
||||||
while (count_to_idx < count_at_percentile)
|
|
||||||
{
|
|
||||||
// increment bucket
|
|
||||||
sub_bucket_idx++;
|
|
||||||
if (sub_bucket_idx >= h->sub_bucket_count)
|
|
||||||
{
|
{
|
||||||
sub_bucket_idx = h->sub_bucket_half_count;
|
return hdr_value_at_index(h, idx);
|
||||||
bucket_idx++;
|
|
||||||
bucket_base_idx = get_bucket_base_index(h, bucket_idx);
|
|
||||||
}
|
}
|
||||||
count_to_idx += get_count_at_index_given_bucket_base_idx(h, bucket_base_idx, sub_bucket_idx);
|
|
||||||
value_from_idx = ((int64_t)(sub_bucket_idx)) << (((int64_t)(bucket_idx)) + h->unit_magnitude);
|
|
||||||
}
|
}
|
||||||
return value_from_idx;
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile)
|
int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile)
|
||||||
{
|
{
|
||||||
double requested_percentile = percentile < 100.0 ? percentile : 100.0;
|
double requested_percentile = percentile < 100.0 ? percentile : 100.0;
|
||||||
|
|
Loading…
Reference in New Issue