p99-ruby 0.0.1 → 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 +4 -4
- data/AUTHORS.md +21 -0
- data/CHANGES.md +35 -0
- data/CONTRIBUTING.md +36 -0
- data/EXAMPLES.md +9 -0
- data/FAQ.md +28 -0
- data/INSTALL.md +41 -0
- data/NEWS.md +10 -0
- data/README.md +55 -7
- data/SECURITY.md +22 -0
- data/TODO.md +20 -0
- data/docs/components/histogram.md +116 -0
- data/docs/guides/README.md +18 -0
- data/docs/guides/recording-and-reading-percentiles.md +134 -0
- data/docs/reference/README.md +39 -0
- data/examples/build_histogram.md +57 -0
- data/examples/build_histogram.rb +149 -0
- data/examples/measure_batch_latency.md +54 -0
- data/examples/measure_batch_latency.rb +87 -0
- data/lib/p99/histogram/pure.rb +666 -0
- data/lib/p99/histogram.rb +85 -0
- data/lib/p99/version.rb +2 -2
- data/lib/p99.rb +1 -0
- data/test/unit/tc_histogram.rb +317 -0
- data/test/unit/tc_version.rb +0 -0
- data/test/unit/ts_all.rb +0 -0
- metadata +24 -3
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
# ######################################################################## #
|
|
3
|
+
# File: p99/histogram.rb
|
|
4
|
+
#
|
|
5
|
+
# Purpose: Histogram loader for p99.Ruby (pure Ruby; C extension later)
|
|
6
|
+
#
|
|
7
|
+
# Created: 4th August 2026
|
|
8
|
+
# Updated: 4th August 2026
|
|
9
|
+
#
|
|
10
|
+
# Home: http://github.com/synesissoftware/p99.Ruby
|
|
11
|
+
#
|
|
12
|
+
# Author: Matthew Wilson
|
|
13
|
+
#
|
|
14
|
+
# Copyright (c) 2026, Matthew Wilson and Synesis Information Systems
|
|
15
|
+
# All rights reserved.
|
|
16
|
+
#
|
|
17
|
+
# Redistribution and use in source and binary forms, with or without
|
|
18
|
+
# modification, are permitted provided that the following conditions are
|
|
19
|
+
# met:
|
|
20
|
+
#
|
|
21
|
+
# * Redistributions of source code must retain the above copyright
|
|
22
|
+
# notice, this list of conditions and the following disclaimer.
|
|
23
|
+
#
|
|
24
|
+
# * Redistributions in binary form must reproduce the above copyright
|
|
25
|
+
# notice, this list of conditions and the following disclaimer in the
|
|
26
|
+
# documentation and/or other materials provided with the distribution.
|
|
27
|
+
#
|
|
28
|
+
# * Neither the names of the copyright holder nor the names of its
|
|
29
|
+
# contributors may be used to endorse or promote products derived from
|
|
30
|
+
# this software without specific prior written permission.
|
|
31
|
+
#
|
|
32
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
33
|
+
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
34
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
35
|
+
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
36
|
+
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
37
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
38
|
+
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
39
|
+
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
40
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
41
|
+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
42
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
43
|
+
#
|
|
44
|
+
# ######################################################################## #
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
=begin
|
|
48
|
+
=end
|
|
49
|
+
|
|
50
|
+
module P99
|
|
51
|
+
|
|
52
|
+
# Loads the Histogram implementation.
|
|
53
|
+
#
|
|
54
|
+
# Prefers a future C extension when present, unless +P99_PURE_RUBY+ is set
|
|
55
|
+
# in the environment; otherwise falls back to the pure-Ruby implementation.
|
|
56
|
+
#
|
|
57
|
+
# @return [String] +"c"+ or +"ruby"+
|
|
58
|
+
def self.load_histogram_implementation
|
|
59
|
+
|
|
60
|
+
if ENV['P99_PURE_RUBY']
|
|
61
|
+
|
|
62
|
+
require 'p99/histogram/pure'
|
|
63
|
+
|
|
64
|
+
return 'ruby'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
begin
|
|
68
|
+
|
|
69
|
+
require 'p99/histogram/ext'
|
|
70
|
+
|
|
71
|
+
'c'
|
|
72
|
+
rescue LoadError
|
|
73
|
+
|
|
74
|
+
require 'p99/histogram/pure'
|
|
75
|
+
|
|
76
|
+
'ruby'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Active Histogram backend: +"ruby"+ (current) or +"c"+ (when available).
|
|
81
|
+
IMPLEMENTATION = load_histogram_implementation
|
|
82
|
+
end # module P99
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# ############################## end of file ############################# #
|
data/lib/p99/version.rb
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Purpose: Version for p99.Ruby library
|
|
6
6
|
#
|
|
7
7
|
# Created: 4th August 2026
|
|
8
|
-
# Updated:
|
|
8
|
+
# Updated: 30th August 2026
|
|
9
9
|
#
|
|
10
10
|
# Home: http://github.com/synesissoftware/p99.Ruby
|
|
11
11
|
#
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
module P99
|
|
51
51
|
|
|
52
52
|
# Current version of the p99.Ruby library
|
|
53
|
-
VERSION = '0.0
|
|
53
|
+
VERSION = '0.1.0'
|
|
54
54
|
|
|
55
55
|
private
|
|
56
56
|
# @!visibility private
|
data/lib/p99.rb
CHANGED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), '../../lib')
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
require 'p99'
|
|
7
|
+
|
|
8
|
+
require 'test/unit'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Test_histogram < Test::Unit::TestCase
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
|
|
15
|
+
@h = P99::Histogram.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_implementation_is_ruby
|
|
19
|
+
|
|
20
|
+
assert_equal 'ruby', P99::IMPLEMENTATION
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_default_histogram
|
|
24
|
+
|
|
25
|
+
assert_equal 0, @h.event_count
|
|
26
|
+
assert_equal 0, @h.event_time_total
|
|
27
|
+
assert_equal 0, @h.event_time_total_raw
|
|
28
|
+
assert_equal false, @h.has_overflowed?
|
|
29
|
+
assert_nil @h.min_event_time
|
|
30
|
+
assert_nil @h.max_event_time
|
|
31
|
+
|
|
32
|
+
buckets = @h.buckets
|
|
33
|
+
|
|
34
|
+
assert_equal P99::BUCKET_COUNT, buckets.size
|
|
35
|
+
|
|
36
|
+
P99::BUCKET_COUNT.times do |i|
|
|
37
|
+
|
|
38
|
+
assert_equal 0, buckets[i]
|
|
39
|
+
assert_equal 0, @h.bucket_value(i)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
assert_nil @h.bucket_value(64)
|
|
43
|
+
assert_nil @h.bucket_value(-1)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_bucket_index
|
|
47
|
+
|
|
48
|
+
cases = [
|
|
49
|
+
[ 0, 0 ],
|
|
50
|
+
[ 1, 0 ],
|
|
51
|
+
[ 2, 1 ],
|
|
52
|
+
[ 3, 1 ],
|
|
53
|
+
[ 4, 2 ],
|
|
54
|
+
[ 7, 2 ],
|
|
55
|
+
[ 8, 3 ],
|
|
56
|
+
[ 15, 3 ],
|
|
57
|
+
[ 1024, 10 ],
|
|
58
|
+
[ 2047, 10 ],
|
|
59
|
+
[ 1 << 63, 63 ],
|
|
60
|
+
[ P99::UINT64_MAX, 63 ],
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
cases.each do |value, bucket|
|
|
64
|
+
|
|
65
|
+
assert_equal bucket, P99.bucket_index(value), "value=#{value}"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_bucket_range
|
|
70
|
+
|
|
71
|
+
cases = [
|
|
72
|
+
[ 0, 0, 1 ],
|
|
73
|
+
[ 1, 2, 3 ],
|
|
74
|
+
[ 2, 4, 7 ],
|
|
75
|
+
[ 3, 8, 15 ],
|
|
76
|
+
[ 4, 16, 31 ],
|
|
77
|
+
[ 10, 1024, 2047 ],
|
|
78
|
+
[ 63, 1 << 63, P99::UINT64_MAX ],
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
cases.each do |index, lower, upper|
|
|
82
|
+
|
|
83
|
+
assert_equal [ lower, upper ], P99.bucket_range(index)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
assert_nil P99.bucket_range(64)
|
|
87
|
+
assert_nil P99.bucket_range(-1)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def test_bucket_placement
|
|
91
|
+
|
|
92
|
+
cases = [
|
|
93
|
+
[ 0, 0 ],
|
|
94
|
+
[ 1, 0 ],
|
|
95
|
+
[ 2, 1 ],
|
|
96
|
+
[ 3, 1 ],
|
|
97
|
+
[ 4, 2 ],
|
|
98
|
+
[ 7, 2 ],
|
|
99
|
+
[ 8, 3 ],
|
|
100
|
+
[ 15, 3 ],
|
|
101
|
+
[ 1024, 10 ],
|
|
102
|
+
[ 2047, 10 ],
|
|
103
|
+
[ 1 << 63, 63 ],
|
|
104
|
+
[ P99::UINT64_MAX, 63 ],
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
cases.each do |value, bucket|
|
|
108
|
+
|
|
109
|
+
@h.clear
|
|
110
|
+
|
|
111
|
+
assert @h.push_event_time_ns(value)
|
|
112
|
+
assert_equal 1, @h.bucket_value(bucket), "value=#{value}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def test_push_events
|
|
117
|
+
|
|
118
|
+
assert @h.push_event_time_ns(1)
|
|
119
|
+
assert @h.push_event_time_ns(3)
|
|
120
|
+
assert @h.push_event_time_us(10)
|
|
121
|
+
assert @h.push_event_time_ms(5)
|
|
122
|
+
assert @h.push_event_time_s(2)
|
|
123
|
+
assert @h.push_event_time_ns(100)
|
|
124
|
+
|
|
125
|
+
assert_equal 6, @h.event_count
|
|
126
|
+
assert_equal false, @h.has_overflowed?
|
|
127
|
+
assert_equal 1, @h.min_event_time
|
|
128
|
+
assert_equal 2_000_000_000, @h.max_event_time
|
|
129
|
+
assert_equal 2_005_010_104, @h.event_time_total
|
|
130
|
+
|
|
131
|
+
buckets = @h.buckets
|
|
132
|
+
|
|
133
|
+
assert_equal 1, buckets[0]
|
|
134
|
+
assert_equal 1, buckets[1]
|
|
135
|
+
assert_equal 1, buckets[6]
|
|
136
|
+
assert_equal 1, buckets[13]
|
|
137
|
+
assert_equal 1, buckets[22]
|
|
138
|
+
assert_equal 1, buckets[30]
|
|
139
|
+
|
|
140
|
+
@h.clear
|
|
141
|
+
|
|
142
|
+
assert_equal 0, @h.event_count
|
|
143
|
+
assert_equal 0, @h.event_time_total
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def test_overflow
|
|
147
|
+
|
|
148
|
+
assert @h.push_event_time_ns(P99::UINT64_MAX)
|
|
149
|
+
assert_equal P99::UINT64_MAX, @h.event_time_total
|
|
150
|
+
assert_equal false, @h.has_overflowed?
|
|
151
|
+
|
|
152
|
+
assert_equal false, @h.push_event_time_ns(1)
|
|
153
|
+
assert_equal true, @h.has_overflowed?
|
|
154
|
+
assert_nil @h.event_time_total
|
|
155
|
+
assert_equal P99::UINT64_MAX, @h.event_time_total_raw
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def test_percentiles_empty
|
|
159
|
+
|
|
160
|
+
assert_nil @h.value_at_percentile(50.0)
|
|
161
|
+
assert_nil @h.value_at_p50
|
|
162
|
+
assert_nil @h.value_at_p99
|
|
163
|
+
assert_nil @h.fixed_percentiles
|
|
164
|
+
assert_nil @h.values_at_percentiles([ 50.0 ])
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def test_percentiles_single_event
|
|
168
|
+
|
|
169
|
+
assert @h.push_event_time_ns(100)
|
|
170
|
+
|
|
171
|
+
[ 0.0, 50.0, 99.0, 100.0 ].each do |percentile|
|
|
172
|
+
|
|
173
|
+
assert_equal 100, @h.value_at_percentile(percentile)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
assert_equal 100, @h.value_at_p50
|
|
177
|
+
assert_equal 100, @h.value_at_p90
|
|
178
|
+
assert_equal 100, @h.value_at_p99
|
|
179
|
+
assert_equal 100, @h.value_at_p99_999_9
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def test_percentiles_interpolation
|
|
183
|
+
|
|
184
|
+
assert @h.push_event_time_ns(100)
|
|
185
|
+
assert @h.push_event_time_ns(200)
|
|
186
|
+
|
|
187
|
+
p50 = @h.value_at_p50
|
|
188
|
+
p99 = @h.value_at_p99
|
|
189
|
+
|
|
190
|
+
assert_operator p50, :>=, 100
|
|
191
|
+
assert_operator p50, :<=, 200
|
|
192
|
+
assert_operator p99, :>=, 100
|
|
193
|
+
assert_operator p99, :<=, 200
|
|
194
|
+
assert_equal 100, @h.value_at_percentile(0.0)
|
|
195
|
+
assert_equal 200, @h.value_at_percentile(100.0)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_percentiles_wide_range
|
|
199
|
+
|
|
200
|
+
values = [
|
|
201
|
+
1,
|
|
202
|
+
10,
|
|
203
|
+
100,
|
|
204
|
+
1_000,
|
|
205
|
+
10_000,
|
|
206
|
+
100_000,
|
|
207
|
+
1_000_000,
|
|
208
|
+
10_000_000,
|
|
209
|
+
100_000_000,
|
|
210
|
+
1_000_000_000,
|
|
211
|
+
10_000_000_000,
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
values.each do |value|
|
|
215
|
+
|
|
216
|
+
assert @h.push_event_time_ns(value)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
assert_equal values.size, @h.event_count
|
|
220
|
+
assert_equal 1, @h.min_event_time
|
|
221
|
+
assert_equal 10_000_000_000, @h.max_event_time
|
|
222
|
+
|
|
223
|
+
fixed = @h.fixed_percentiles
|
|
224
|
+
|
|
225
|
+
refute_nil fixed
|
|
226
|
+
|
|
227
|
+
ordered = [
|
|
228
|
+
fixed['p50'],
|
|
229
|
+
fixed['p75'],
|
|
230
|
+
fixed['p90'],
|
|
231
|
+
fixed['p95'],
|
|
232
|
+
fixed['p99'],
|
|
233
|
+
fixed['p99.5'],
|
|
234
|
+
fixed['p99.9'],
|
|
235
|
+
fixed['p99.99'],
|
|
236
|
+
fixed['p99.999'],
|
|
237
|
+
fixed['p99.9999'],
|
|
238
|
+
]
|
|
239
|
+
|
|
240
|
+
assert_equal ordered.sort, ordered
|
|
241
|
+
assert_operator ordered.first, :>=, 1
|
|
242
|
+
assert_operator ordered.last, :<=, 10_000_000_000
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def test_percentiles_many_events
|
|
246
|
+
|
|
247
|
+
count = 100_000
|
|
248
|
+
|
|
249
|
+
(1..count).each do |i|
|
|
250
|
+
|
|
251
|
+
assert @h.push_event_time_ns(i)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
assert_equal count, @h.event_count
|
|
255
|
+
assert_equal 1, @h.min_event_time
|
|
256
|
+
assert_equal count, @h.max_event_time
|
|
257
|
+
assert_equal 50_000, @h.value_at_p50
|
|
258
|
+
assert_equal 100_000, @h.value_at_p90
|
|
259
|
+
assert_equal 100_000, @h.value_at_p99
|
|
260
|
+
assert_equal 100_000, @h.value_at_p99_9
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def test_compare_float_and_int_percentiles
|
|
264
|
+
|
|
265
|
+
(1..10_000).each do |i|
|
|
266
|
+
|
|
267
|
+
assert @h.push_event_time_ns((i * i) % 1_000_000)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
pairs = [
|
|
271
|
+
[ 50.0, :value_at_p50 ],
|
|
272
|
+
[ 75.0, :value_at_p75 ],
|
|
273
|
+
[ 90.0, :value_at_p90 ],
|
|
274
|
+
[ 95.0, :value_at_p95 ],
|
|
275
|
+
[ 99.0, :value_at_p99 ],
|
|
276
|
+
[ 99.5, :value_at_p99_5 ],
|
|
277
|
+
[ 99.9, :value_at_p99_9 ],
|
|
278
|
+
[ 99.99, :value_at_p99_99 ],
|
|
279
|
+
[ 99.999, :value_at_p99_999 ],
|
|
280
|
+
[ 99.9999, :value_at_p99_999_9 ],
|
|
281
|
+
]
|
|
282
|
+
|
|
283
|
+
pairs.each do |level, method_name|
|
|
284
|
+
|
|
285
|
+
float_value = @h.value_at_percentile(level)
|
|
286
|
+
int_value = @h.send(method_name)
|
|
287
|
+
|
|
288
|
+
refute_nil float_value
|
|
289
|
+
refute_nil int_value
|
|
290
|
+
|
|
291
|
+
tolerance = [ float_value.abs * 0.01, 1.0 ].max
|
|
292
|
+
|
|
293
|
+
assert_operator (float_value - int_value).abs, :<=, tolerance
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def test_values_at_percentiles_empty_levels
|
|
298
|
+
|
|
299
|
+
assert @h.push_event_time_ns(100)
|
|
300
|
+
assert_equal [], @h.values_at_percentiles([])
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def test_values_at_percentiles
|
|
304
|
+
|
|
305
|
+
assert @h.push_event_time_ns(100)
|
|
306
|
+
assert @h.push_event_time_ns(200)
|
|
307
|
+
|
|
308
|
+
results = @h.values_at_percentiles([ 0.0, 100.0 ])
|
|
309
|
+
|
|
310
|
+
assert_equal [ [ 0.0, 100 ], [ 100.0, 200 ] ], results
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def test_clear_returns_self
|
|
314
|
+
|
|
315
|
+
assert_same @h, @h.clear
|
|
316
|
+
end
|
|
317
|
+
end
|
data/test/unit/tc_version.rb
CHANGED
|
File without changes
|
data/test/unit/ts_all.rb
CHANGED
|
File without changes
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: p99-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matt Wilson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: xqsr3
|
|
@@ -33,18 +33,39 @@ dependencies:
|
|
|
33
33
|
description: |
|
|
34
34
|
Low-cost generation of performance percentiles (p50, p90, p99, p99.9, etc.), for Ruby.
|
|
35
35
|
|
|
36
|
-
p99.Ruby is the Ruby implementation of the p99 family of libraries.
|
|
36
|
+
p99.Ruby is the Ruby implementation of the p99 family of libraries. This
|
|
37
|
+
release provides a pure-Ruby Histogram; a C-extension backend is planned.
|
|
37
38
|
email:
|
|
38
39
|
- matthew@synesis.com.au
|
|
39
40
|
executables: []
|
|
40
41
|
extensions: []
|
|
41
42
|
extra_rdoc_files: []
|
|
42
43
|
files:
|
|
44
|
+
- AUTHORS.md
|
|
45
|
+
- CHANGES.md
|
|
46
|
+
- CONTRIBUTING.md
|
|
47
|
+
- EXAMPLES.md
|
|
48
|
+
- FAQ.md
|
|
49
|
+
- INSTALL.md
|
|
43
50
|
- LICENSE
|
|
51
|
+
- NEWS.md
|
|
44
52
|
- README.md
|
|
45
53
|
- Rakefile
|
|
54
|
+
- SECURITY.md
|
|
55
|
+
- TODO.md
|
|
56
|
+
- docs/components/histogram.md
|
|
57
|
+
- docs/guides/README.md
|
|
58
|
+
- docs/guides/recording-and-reading-percentiles.md
|
|
59
|
+
- docs/reference/README.md
|
|
60
|
+
- examples/build_histogram.md
|
|
61
|
+
- examples/build_histogram.rb
|
|
62
|
+
- examples/measure_batch_latency.md
|
|
63
|
+
- examples/measure_batch_latency.rb
|
|
46
64
|
- lib/p99.rb
|
|
65
|
+
- lib/p99/histogram.rb
|
|
66
|
+
- lib/p99/histogram/pure.rb
|
|
47
67
|
- lib/p99/version.rb
|
|
68
|
+
- test/unit/tc_histogram.rb
|
|
48
69
|
- test/unit/tc_version.rb
|
|
49
70
|
- test/unit/ts_all.rb
|
|
50
71
|
homepage: https://github.com/synesissoftware/p99.Ruby
|