HDRHistogram 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +7 -0
- data/Gemfile +4 -0
- data/HDRHistogram.gemspec +37 -0
- data/LICENSE.txt +21 -0
- data/README.md +144 -0
- data/Rakefile +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/ruby_hdr_histogram/extconf.rb +6 -0
- data/ext/ruby_hdr_histogram/hdr_histogram.c +1008 -0
- data/ext/ruby_hdr_histogram/hdr_histogram.h +415 -0
- data/ext/ruby_hdr_histogram/ruby_hdr_histogram.c +152 -0
- data/lib/HDRHistogram.rb +65 -0
- data/lib/HDRHistogram/version.rb +3 -0
- metadata +150 -0
@@ -0,0 +1,415 @@
|
|
1
|
+
/**
|
2
|
+
* hdr_histogram.h
|
3
|
+
* Written by Michael Barker and released to the public domain,
|
4
|
+
* as explained at http://creativecommons.org/publicdomain/zero/1.0/
|
5
|
+
*
|
6
|
+
* The source for the hdr_histogram utilises a few C99 constructs, specifically
|
7
|
+
* the use of stdint/stdbool and inline variable declaration.
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef HDR_HISTOGRAM_H
|
11
|
+
#define HDR_HISTOGRAM_H 1
|
12
|
+
|
13
|
+
#include <stdint.h>
|
14
|
+
#include <stdbool.h>
|
15
|
+
#include <stdio.h>
|
16
|
+
|
17
|
+
struct hdr_histogram
|
18
|
+
{
|
19
|
+
int64_t lowest_trackable_value;
|
20
|
+
int64_t highest_trackable_value;
|
21
|
+
int32_t unit_magnitude;
|
22
|
+
int32_t significant_figures;
|
23
|
+
int32_t sub_bucket_half_count_magnitude;
|
24
|
+
int32_t sub_bucket_half_count;
|
25
|
+
int64_t sub_bucket_mask;
|
26
|
+
int32_t sub_bucket_count;
|
27
|
+
int32_t bucket_count;
|
28
|
+
int64_t min_value;
|
29
|
+
int64_t max_value;
|
30
|
+
int32_t normalizing_index_offset;
|
31
|
+
double conversion_ratio;
|
32
|
+
int32_t counts_len;
|
33
|
+
int64_t total_count;
|
34
|
+
int64_t counts[0];
|
35
|
+
};
|
36
|
+
|
37
|
+
#ifdef __cplusplus
|
38
|
+
extern "C" {
|
39
|
+
#endif
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Allocate the memory and initialise the hdr_histogram.
|
43
|
+
*
|
44
|
+
* Due to the size of the histogram being the result of some reasonably
|
45
|
+
* involved math on the input parameters this function it is tricky to stack allocate.
|
46
|
+
* The histogram is allocated in a single contigious block so can be delete via free,
|
47
|
+
* without any structure specific destructor.
|
48
|
+
*
|
49
|
+
* @param lowest_trackable_value The smallest possible value to be put into the
|
50
|
+
* histogram.
|
51
|
+
* @param highest_trackable_value The largest possible value to be put into the
|
52
|
+
* histogram.
|
53
|
+
* @param significant_figures The level of precision for this histogram, i.e. the number
|
54
|
+
* of figures in a decimal number that will be maintained. E.g. a value of 3 will mean
|
55
|
+
* the results from the histogram will be accurate up to the first three digits. Must
|
56
|
+
* be a value between 1 and 5 (inclusive).
|
57
|
+
* @param result Output parameter to capture allocated histogram.
|
58
|
+
* @return 0 on success, EINVAL if lowest_trackable_value is < 1 or the
|
59
|
+
* significant_figure value is outside of the allowed range, ENOMEM if malloc
|
60
|
+
* failed.
|
61
|
+
*/
|
62
|
+
int hdr_init(
|
63
|
+
int64_t lowest_trackable_value,
|
64
|
+
int64_t highest_trackable_value,
|
65
|
+
int significant_figures,
|
66
|
+
struct hdr_histogram** result);
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Allocate the memory and initialise the hdr_histogram. This is the equivalent of calling
|
70
|
+
* hdr_init(1, highest_trackable_value, significant_figures, result);
|
71
|
+
*
|
72
|
+
* @deprecated use hdr_init.
|
73
|
+
*/
|
74
|
+
int hdr_alloc(int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result);
|
75
|
+
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Reset a histogram to zero - empty out a histogram and re-initialise it
|
79
|
+
*
|
80
|
+
* If you want to re-use an existing histogram, but reset everything back to zero, this
|
81
|
+
* is the routine to use.
|
82
|
+
*
|
83
|
+
* @param h The histogram you want to reset to empty.
|
84
|
+
*
|
85
|
+
*/
|
86
|
+
void hdr_reset(struct hdr_histogram *h);
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Get the memory size of the hdr_histogram.
|
90
|
+
*
|
91
|
+
* @param h "This" pointer
|
92
|
+
* @return The amount of memory used by the hdr_histogram in bytes
|
93
|
+
*/
|
94
|
+
size_t hdr_get_memory_size(struct hdr_histogram *h);
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Records a value in the histogram, will round this value of to a precision at or better
|
98
|
+
* than the significant_figure specified at construction time.
|
99
|
+
*
|
100
|
+
* @param h "This" pointer
|
101
|
+
* @param value Value to add to the histogram
|
102
|
+
* @return false if the value is larger than the highest_trackable_value and can't be recorded,
|
103
|
+
* true otherwise.
|
104
|
+
*/
|
105
|
+
bool hdr_record_value(struct hdr_histogram* h, int64_t value);
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Records count values in the histogram, will round this value of to a
|
109
|
+
* precision at or better than the significant_figure specified at construction
|
110
|
+
* time.
|
111
|
+
*
|
112
|
+
* @param h "This" pointer
|
113
|
+
* @param value Value to add to the histogram
|
114
|
+
* @param count Number of 'value's to add to the histogram
|
115
|
+
* @return false if any value is larger than the highest_trackable_value and can't be recorded,
|
116
|
+
* true otherwise.
|
117
|
+
*/
|
118
|
+
bool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count);
|
119
|
+
|
120
|
+
|
121
|
+
/**
|
122
|
+
* Record a value in the histogram and backfill based on an expected interval.
|
123
|
+
*
|
124
|
+
* Records a value in the histogram, will round this value of to a precision at or better
|
125
|
+
* than the significant_figure specified at contruction time. This is specifically used
|
126
|
+
* for recording latency. If the value is larger than the expected_interval then the
|
127
|
+
* latency recording system has experienced co-ordinated omission. This method fills in the
|
128
|
+
* values that would have occured had the client providing the load not been blocked.
|
129
|
+
|
130
|
+
* @param h "This" pointer
|
131
|
+
* @param value Value to add to the histogram
|
132
|
+
* @param expected_interval The delay between recording values.
|
133
|
+
* @return false if the value is larger than the highest_trackable_value and can't be recorded,
|
134
|
+
* true otherwise.
|
135
|
+
*/
|
136
|
+
bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expexcted_interval);
|
137
|
+
/**
|
138
|
+
* Record a value in the histogram 'count' times. Applies the same correcting logic
|
139
|
+
* as 'hdr_record_corrected_value'.
|
140
|
+
*
|
141
|
+
* @param h "This" pointer
|
142
|
+
* @param value Value to add to the histogram
|
143
|
+
* @param count Number of 'value's to add to the histogram
|
144
|
+
* @param expected_interval The delay between recording values.
|
145
|
+
* @return false if the value is larger than the highest_trackable_value and can't be recorded,
|
146
|
+
* true otherwise.
|
147
|
+
*/
|
148
|
+
bool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval);
|
149
|
+
|
150
|
+
/**
|
151
|
+
* Adds all of the values from 'from' to 'this' histogram. Will return the
|
152
|
+
* number of values that are dropped when copying. Values will be dropped
|
153
|
+
* if they around outside of h.lowest_trackable_value and
|
154
|
+
* h.highest_trackable_value.
|
155
|
+
*
|
156
|
+
* @param h "This" pointer
|
157
|
+
* @param from Histogram to copy values from.
|
158
|
+
* @return The number of values dropped when copying.
|
159
|
+
*/
|
160
|
+
int64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from);
|
161
|
+
|
162
|
+
/**
|
163
|
+
* Adds all of the values from 'from' to 'this' histogram. Will return the
|
164
|
+
* number of values that are dropped when copying. Values will be dropped
|
165
|
+
* if they around outside of h.lowest_trackable_value and
|
166
|
+
* h.highest_trackable_value.
|
167
|
+
*
|
168
|
+
* @param h "This" pointer
|
169
|
+
* @param from Histogram to copy values from.
|
170
|
+
* @return The number of values dropped when copying.
|
171
|
+
*/
|
172
|
+
int64_t hdr_add_while_correcting_for_coordinated_omission(
|
173
|
+
struct hdr_histogram* h, struct hdr_histogram* from, int64_t expected_interval);
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Get minimum value from the histogram. Will return 2^63-1 if the histogram
|
177
|
+
* is empty.
|
178
|
+
*
|
179
|
+
* @param h "This" pointer
|
180
|
+
*/
|
181
|
+
int64_t hdr_min(const struct hdr_histogram* h);
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Get maximum value from the histogram. Will return 0 if the histogram
|
185
|
+
* is empty.
|
186
|
+
*
|
187
|
+
* @param h "This" pointer
|
188
|
+
*/
|
189
|
+
int64_t hdr_max(const struct hdr_histogram* h);
|
190
|
+
|
191
|
+
/**
|
192
|
+
* Get the value at a specific percentile.
|
193
|
+
*
|
194
|
+
* @param h "This" pointer.
|
195
|
+
* @param percentile The percentile to get the value for
|
196
|
+
*/
|
197
|
+
int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile);
|
198
|
+
|
199
|
+
/**
|
200
|
+
* Gets the standard deviation for the values in the histogram.
|
201
|
+
*
|
202
|
+
* @param h "This" pointer
|
203
|
+
* @return The standard deviation
|
204
|
+
*/
|
205
|
+
double hdr_stddev(const struct hdr_histogram* h);
|
206
|
+
|
207
|
+
/**
|
208
|
+
* Gets the mean for the values in the histogram.
|
209
|
+
*
|
210
|
+
* @param h "This" pointer
|
211
|
+
* @return The mean
|
212
|
+
*/
|
213
|
+
double hdr_mean(const struct hdr_histogram* h);
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Determine if two values are equivalent with the histogram's resolution.
|
217
|
+
* Where "equivalent" means that value samples recorded for any two
|
218
|
+
* equivalent values are counted in a common total count.
|
219
|
+
*
|
220
|
+
* @param h "This" pointer
|
221
|
+
* @param a first value to compare
|
222
|
+
* @param b second value to compare
|
223
|
+
* @return 'true' if values are equivalent with the histogram's resolution.
|
224
|
+
*/
|
225
|
+
bool hdr_values_are_equivalent(const struct hdr_histogram* h, int64_t a, int64_t b);
|
226
|
+
|
227
|
+
/**
|
228
|
+
* Get the lowest value that is equivalent to the given value within the histogram's resolution.
|
229
|
+
* Where "equivalent" means that value samples recorded for any two
|
230
|
+
* equivalent values are counted in a common total count.
|
231
|
+
*
|
232
|
+
* @param h "This" pointer
|
233
|
+
* @param value The given value
|
234
|
+
* @return The lowest value that is equivalent to the given value within the histogram's resolution.
|
235
|
+
*/
|
236
|
+
int64_t hdr_lowest_equivalent_value(const struct hdr_histogram* h, int64_t value);
|
237
|
+
|
238
|
+
/**
|
239
|
+
* Get the count of recorded values at a specific value
|
240
|
+
* (to within the histogram resolution at the value level).
|
241
|
+
*
|
242
|
+
* @param h "This" pointer
|
243
|
+
* @param value The value for which to provide the recorded count
|
244
|
+
* @return The total count of values recorded in the histogram within the value range that is
|
245
|
+
* {@literal >=} lowestEquivalentValue(<i>value</i>) and {@literal <=} highestEquivalentValue(<i>value</i>)
|
246
|
+
*/
|
247
|
+
int64_t hdr_count_at_value(const struct hdr_histogram* h, int64_t value);
|
248
|
+
int64_t hdr_count_at_index(const struct hdr_histogram* h, int32_t index);
|
249
|
+
int64_t hdr_value_at_index(const struct hdr_histogram* h, int32_t index);
|
250
|
+
|
251
|
+
struct hdr_iter_percentiles
|
252
|
+
{
|
253
|
+
bool seen_last_value;
|
254
|
+
int32_t ticks_per_half_distance;
|
255
|
+
double percentile_to_iterate_to;
|
256
|
+
double percentile;
|
257
|
+
};
|
258
|
+
|
259
|
+
struct hdr_iter_recorded
|
260
|
+
{
|
261
|
+
int64_t count_added_in_this_iteration_step;
|
262
|
+
};
|
263
|
+
|
264
|
+
struct hdr_iter_linear
|
265
|
+
{
|
266
|
+
int64_t value_units_per_bucket;
|
267
|
+
int64_t count_added_in_this_iteration_step;
|
268
|
+
int64_t next_value_reporting_level;
|
269
|
+
int64_t next_value_reporting_level_lowest_equivalent;
|
270
|
+
};
|
271
|
+
|
272
|
+
struct hdr_iter_log
|
273
|
+
{
|
274
|
+
double log_base;
|
275
|
+
int64_t count_added_in_this_iteration_step;
|
276
|
+
int64_t next_value_reporting_level;
|
277
|
+
int64_t next_value_reporting_level_lowest_equivalent;
|
278
|
+
};
|
279
|
+
|
280
|
+
/**
|
281
|
+
* The basic iterator. This is a generic structure
|
282
|
+
* that supports all of the types of iteration. Use
|
283
|
+
* the appropriate initialiser to get the desired
|
284
|
+
* iteration.
|
285
|
+
*
|
286
|
+
* @
|
287
|
+
*/
|
288
|
+
struct hdr_iter
|
289
|
+
{
|
290
|
+
const struct hdr_histogram* h;
|
291
|
+
/** raw index into the counts array */
|
292
|
+
int32_t counts_index;
|
293
|
+
/** value directly from array for the current counts_index */
|
294
|
+
int64_t count;
|
295
|
+
/** sum of all of the counts up to and including the count at this index */
|
296
|
+
int64_t cumulative_count;
|
297
|
+
/** The current value based on counts_index */
|
298
|
+
int64_t value;
|
299
|
+
int64_t highest_equivalent_value;
|
300
|
+
int64_t lowest_equivalent_value;
|
301
|
+
int64_t median_equivalent_value;
|
302
|
+
int64_t value_iterated_from;
|
303
|
+
int64_t value_iterated_to;
|
304
|
+
|
305
|
+
union
|
306
|
+
{
|
307
|
+
struct hdr_iter_percentiles percentiles;
|
308
|
+
struct hdr_iter_recorded recorded;
|
309
|
+
struct hdr_iter_linear linear;
|
310
|
+
struct hdr_iter_log log;
|
311
|
+
} specifics;
|
312
|
+
|
313
|
+
bool (*_next_fp)(struct hdr_iter* iter);
|
314
|
+
|
315
|
+
};
|
316
|
+
|
317
|
+
/**
|
318
|
+
* Initalises the basic iterator.
|
319
|
+
*
|
320
|
+
* @param itr 'This' pointer
|
321
|
+
* @param h The histogram to iterate over
|
322
|
+
*/
|
323
|
+
void hdr_iter_init(struct hdr_iter* iter, const struct hdr_histogram* h);
|
324
|
+
|
325
|
+
/**
|
326
|
+
* Initialise the iterator for use with percentiles.
|
327
|
+
*/
|
328
|
+
void hdr_iter_percentile_init(struct hdr_iter* iter, const struct hdr_histogram* h, int32_t ticks_per_half_distance);
|
329
|
+
|
330
|
+
/**
|
331
|
+
* Initialise the iterator for use with recorded values.
|
332
|
+
*/
|
333
|
+
void hdr_iter_recorded_init(struct hdr_iter* iter, const struct hdr_histogram* h);
|
334
|
+
|
335
|
+
/**
|
336
|
+
* Initialise the iterator for use with linear values.
|
337
|
+
*/
|
338
|
+
void hdr_iter_linear_init(
|
339
|
+
struct hdr_iter* iter,
|
340
|
+
const struct hdr_histogram* h,
|
341
|
+
int64_t value_units_per_bucket);
|
342
|
+
|
343
|
+
/**
|
344
|
+
* Initialise the iterator for use with logarithmic values
|
345
|
+
*/
|
346
|
+
void hdr_iter_log_init(
|
347
|
+
struct hdr_iter* iter,
|
348
|
+
const struct hdr_histogram* h,
|
349
|
+
int64_t value_units_first_bucket,
|
350
|
+
double log_base);
|
351
|
+
|
352
|
+
/**
|
353
|
+
* Iterate to the next value for the iterator. If there are no more values
|
354
|
+
* available return faluse.
|
355
|
+
*
|
356
|
+
* @param itr 'This' pointer
|
357
|
+
* @return 'false' if there are no values remaining for this iterator.
|
358
|
+
*/
|
359
|
+
bool hdr_iter_next(struct hdr_iter* iter);
|
360
|
+
|
361
|
+
typedef enum {
|
362
|
+
CLASSIC,
|
363
|
+
CSV
|
364
|
+
} format_type;
|
365
|
+
|
366
|
+
/**
|
367
|
+
* Print out a percentile based histogram to the supplied stream. Note that
|
368
|
+
* this call will not flush the FILE, this is left up to the user.
|
369
|
+
*
|
370
|
+
* @param h 'This' pointer
|
371
|
+
* @param stream The FILE to write the output to
|
372
|
+
* @param ticks_per_half_distance The number of iteration steps per half-distance to 100%
|
373
|
+
* @param value_scale Scale the output values by this amount
|
374
|
+
* @param format_type Format to use, e.g. CSV.
|
375
|
+
* @return 0 on success, error code on failure. EIO if an error occurs writing
|
376
|
+
* the output.
|
377
|
+
*/
|
378
|
+
int hdr_percentiles_print(
|
379
|
+
struct hdr_histogram* h, FILE* stream, int32_t ticks_per_half_distance,
|
380
|
+
double value_scale, format_type format);
|
381
|
+
|
382
|
+
/**
|
383
|
+
* Internal allocation methods, used by hdr_dbl_histogram.
|
384
|
+
*/
|
385
|
+
struct hdr_histogram_bucket_config
|
386
|
+
{
|
387
|
+
int64_t lowest_trackable_value;
|
388
|
+
int64_t highest_trackable_value;
|
389
|
+
int64_t unit_magnitude;
|
390
|
+
int64_t significant_figures;
|
391
|
+
int32_t sub_bucket_half_count_magnitude;
|
392
|
+
int32_t sub_bucket_half_count;
|
393
|
+
int64_t sub_bucket_mask;
|
394
|
+
int32_t sub_bucket_count;
|
395
|
+
int32_t bucket_count;
|
396
|
+
int32_t counts_len;
|
397
|
+
};
|
398
|
+
|
399
|
+
int hdr_calculate_bucket_config(
|
400
|
+
int64_t lowest_trackable_value,
|
401
|
+
int64_t highest_trackable_value,
|
402
|
+
int significant_figures,
|
403
|
+
struct hdr_histogram_bucket_config* cfg);
|
404
|
+
|
405
|
+
void hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_config* cfg);
|
406
|
+
|
407
|
+
int64_t hdr_size_of_equivalent_value_range(const struct hdr_histogram *h, int64_t value);
|
408
|
+
int64_t hdr_next_non_equivalent_value(const struct hdr_histogram *h, int64_t value);
|
409
|
+
int64_t hdr_median_equivalent_value(const struct hdr_histogram *h, int64_t value);
|
410
|
+
|
411
|
+
#ifdef __cplusplus
|
412
|
+
}
|
413
|
+
#endif
|
414
|
+
|
415
|
+
#endif
|
@@ -0,0 +1,152 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
//#include "ext_help.h"
|
3
|
+
#include <errno.h>
|
4
|
+
#include <inttypes.h>
|
5
|
+
#include "hdr_histogram.h"
|
6
|
+
|
7
|
+
#define GET_HDRHIST(name, val) \
|
8
|
+
struct hdr_histogram *name; \
|
9
|
+
Data_Get_Struct(val, struct hdr_histogram, name)
|
10
|
+
|
11
|
+
static VALUE HDRHistogram = Qnil;
|
12
|
+
static VALUE HDRHistogramError = Qnil;
|
13
|
+
|
14
|
+
static void histogram_free(void *p) {
|
15
|
+
free(p);
|
16
|
+
}
|
17
|
+
|
18
|
+
static VALUE histogram_new(int argc, VALUE* argv, VALUE class) {
|
19
|
+
VALUE self, lowest_value, highest_value, significant_figures;
|
20
|
+
VALUE opt;
|
21
|
+
|
22
|
+
struct hdr_histogram *hdrh;
|
23
|
+
int ret;
|
24
|
+
|
25
|
+
rb_scan_args(argc, argv, "31", &lowest_value, &highest_value, &significant_figures, &opt);
|
26
|
+
|
27
|
+
lowest_value = rb_funcall(class, rb_intern("adjusted_boundary_val"), 2, lowest_value, opt);
|
28
|
+
highest_value = rb_funcall(class, rb_intern("adjusted_boundary_val"), 2, highest_value, opt);
|
29
|
+
|
30
|
+
ret = hdr_init(NUM2INT(lowest_value), NUM2INT(highest_value), NUM2INT(significant_figures), &hdrh);
|
31
|
+
if(ret == EINVAL) {
|
32
|
+
rb_raise(HDRHistogramError, "%s", "lowest_trackable_value must be >= 1");
|
33
|
+
}
|
34
|
+
else if(ret == ENOMEM) {
|
35
|
+
rb_raise(HDRHistogramError, "%s", "no memory");
|
36
|
+
}
|
37
|
+
|
38
|
+
self = Data_Wrap_Struct(class, NULL, histogram_free, hdrh);
|
39
|
+
rb_obj_call_init(self, argc, argv);
|
40
|
+
|
41
|
+
return self;
|
42
|
+
}
|
43
|
+
|
44
|
+
static VALUE histogram_reset(VALUE self) {
|
45
|
+
GET_HDRHIST(hdr, self);
|
46
|
+
hdr_reset(hdr);
|
47
|
+
return self;
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE histogram_memsize(VALUE self) {
|
51
|
+
GET_HDRHIST(hdr, self);
|
52
|
+
return INT2NUM(hdr_get_memory_size(hdr));
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE histogram_count(VALUE self) {
|
56
|
+
GET_HDRHIST(hdr, self);
|
57
|
+
return INT2NUM(hdr->total_count);
|
58
|
+
}
|
59
|
+
|
60
|
+
static VALUE histogram_record_value(VALUE self, VALUE val) {
|
61
|
+
GET_HDRHIST(hdr, self);
|
62
|
+
return hdr_record_value(hdr, NUM2INT(val)) ? Qtrue : Qfalse;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE histogram_record_corrected_value(VALUE self, VALUE val, VALUE expected_interval) {
|
66
|
+
GET_HDRHIST(hdr, self);
|
67
|
+
return hdr_record_corrected_value(hdr, NUM2INT(val), NUM2INT(expected_interval)) ? Qtrue : Qfalse;
|
68
|
+
}
|
69
|
+
|
70
|
+
static VALUE generic_histogram_intval(VALUE self, int64_t func(const struct hdr_histogram *) ) {
|
71
|
+
GET_HDRHIST(hdr, self);
|
72
|
+
return INT2NUM(hdr->total_count > 0 ? func(hdr) : 0);
|
73
|
+
}
|
74
|
+
|
75
|
+
static VALUE histogram_min(VALUE self) {
|
76
|
+
return generic_histogram_intval(self, hdr_min);
|
77
|
+
}
|
78
|
+
static VALUE histogram_max(VALUE self) {
|
79
|
+
return generic_histogram_intval(self, hdr_max);
|
80
|
+
}
|
81
|
+
|
82
|
+
static VALUE generic_histogram_floatval(VALUE self, double func(const struct hdr_histogram *) ) {
|
83
|
+
GET_HDRHIST(hdr, self);
|
84
|
+
return rb_float_new(hdr->total_count > 0 ? func(hdr) : 0.0);
|
85
|
+
}
|
86
|
+
|
87
|
+
static VALUE histogram_mean(VALUE self) {
|
88
|
+
return generic_histogram_floatval(self, hdr_mean);
|
89
|
+
}
|
90
|
+
|
91
|
+
static VALUE histogram_stddev(VALUE self) {
|
92
|
+
return generic_histogram_floatval(self, hdr_stddev);
|
93
|
+
}
|
94
|
+
|
95
|
+
static VALUE histogram_percentile(VALUE self, VALUE percentile ) {
|
96
|
+
GET_HDRHIST(hdr, self);
|
97
|
+
return INT2NUM(hdr_value_at_percentile(hdr, NUM2DBL(percentile)));
|
98
|
+
}
|
99
|
+
|
100
|
+
static VALUE histogram_merge(VALUE self, VALUE another ) {
|
101
|
+
GET_HDRHIST(hdr, self);
|
102
|
+
GET_HDRHIST(hdr2, another);
|
103
|
+
return INT2NUM(hdr_add(hdr, hdr2));
|
104
|
+
}
|
105
|
+
|
106
|
+
#define HISTOGRAM_GETINT_METHOD(int_name) \
|
107
|
+
static VALUE histogram_##int_name(VALUE self) { \
|
108
|
+
GET_HDRHIST(hdr, self); \
|
109
|
+
return INT2NUM(hdr->int_name); \
|
110
|
+
}
|
111
|
+
|
112
|
+
HISTOGRAM_GETINT_METHOD(lowest_trackable_value)
|
113
|
+
HISTOGRAM_GETINT_METHOD(highest_trackable_value)
|
114
|
+
HISTOGRAM_GETINT_METHOD(unit_magnitude)
|
115
|
+
HISTOGRAM_GETINT_METHOD(significant_figures)
|
116
|
+
HISTOGRAM_GETINT_METHOD(bucket_count)
|
117
|
+
HISTOGRAM_GETINT_METHOD(sub_bucket_count)
|
118
|
+
HISTOGRAM_GETINT_METHOD(counts_len)
|
119
|
+
|
120
|
+
void Init_ruby_hdr_histogram() {
|
121
|
+
HDRHistogram = rb_define_class("HDRHistogram", rb_cObject);
|
122
|
+
HDRHistogramError = rb_define_class_under(HDRHistogram, "HDRHistogramError", rb_eRuntimeError);
|
123
|
+
|
124
|
+
rb_define_singleton_method(HDRHistogram, "new", histogram_new, -1);
|
125
|
+
rb_define_attr(HDRHistogram, "multiplier", 1, 0);
|
126
|
+
rb_define_attr(HDRHistogram, "unit", 1, 0);
|
127
|
+
|
128
|
+
rb_define_method(HDRHistogram, "reset", histogram_reset, 0);
|
129
|
+
rb_define_method(HDRHistogram, "memsize", histogram_memsize, 0);
|
130
|
+
rb_define_method(HDRHistogram, "count", histogram_count, 0);
|
131
|
+
|
132
|
+
rb_define_private_method(HDRHistogram, "raw_record", histogram_record_value, 1);
|
133
|
+
rb_define_private_method(HDRHistogram, "raw_record_corrected", histogram_record_corrected_value, 2);
|
134
|
+
rb_define_private_method(HDRHistogram, "raw_min", histogram_min, 0);
|
135
|
+
rb_define_private_method(HDRHistogram, "raw_max", histogram_max, 0);
|
136
|
+
rb_define_private_method(HDRHistogram, "raw_mean", histogram_mean, 0);
|
137
|
+
rb_define_private_method(HDRHistogram, "raw_stddev", histogram_stddev, 0);
|
138
|
+
rb_define_private_method(HDRHistogram, "raw_percentile", histogram_percentile, 1);
|
139
|
+
rb_define_private_method(HDRHistogram, "raw_merge", histogram_merge, 1);
|
140
|
+
|
141
|
+
|
142
|
+
rb_define_method(HDRHistogram, "lowest_trackable_value", histogram_lowest_trackable_value, 0);
|
143
|
+
rb_define_method(HDRHistogram, "highest_trackable_value", histogram_highest_trackable_value, 0);
|
144
|
+
rb_define_private_method(HDRHistogram, "unit_magnitude", histogram_unit_magnitude, 0);
|
145
|
+
rb_define_method(HDRHistogram, "significant_figures", histogram_significant_figures, 0);
|
146
|
+
rb_define_private_method(HDRHistogram, "bucket_count", histogram_bucket_count, 0);
|
147
|
+
rb_define_private_method(HDRHistogram, "sub_bucket_count", histogram_bucket_count, 0);
|
148
|
+
rb_define_private_method(HDRHistogram, "counts_len", histogram_counts_len, 0);
|
149
|
+
|
150
|
+
//rb_define_private_method(HDRHistogram, "histogram_spectrum", histogram_spectrum, 2);
|
151
|
+
}
|
152
|
+
|