splitclient-rb 4.5.1-java
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 +45 -0
- data/CHANGES.txt +147 -0
- data/Detailed-README.md +571 -0
- data/Gemfile +4 -0
- data/LICENSE +13 -0
- data/NEWS +75 -0
- data/README.md +43 -0
- data/Rakefile +24 -0
- data/exe/splitio +96 -0
- data/ext/murmurhash/MurmurHash3.java +162 -0
- data/lib/murmurhash/base.rb +58 -0
- data/lib/murmurhash/murmurhash.jar +0 -0
- data/lib/murmurhash/murmurhash_mri.rb +3 -0
- data/lib/splitclient-rb.rb +90 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapter.rb +12 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb +133 -0
- data/lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb +44 -0
- data/lib/splitclient-rb/cache/adapters/redis_adapter.rb +165 -0
- data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +30 -0
- data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +29 -0
- data/lib/splitclient-rb/cache/repositories/events_repository.rb +41 -0
- data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +49 -0
- data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +78 -0
- data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +21 -0
- data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +129 -0
- data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +98 -0
- data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +22 -0
- data/lib/splitclient-rb/cache/repositories/repository.rb +23 -0
- data/lib/splitclient-rb/cache/repositories/segments_repository.rb +82 -0
- data/lib/splitclient-rb/cache/repositories/splits_repository.rb +106 -0
- data/lib/splitclient-rb/cache/routers/impression_router.rb +52 -0
- data/lib/splitclient-rb/cache/senders/events_sender.rb +47 -0
- data/lib/splitclient-rb/cache/senders/impressions_formatter.rb +73 -0
- data/lib/splitclient-rb/cache/senders/impressions_sender.rb +67 -0
- data/lib/splitclient-rb/cache/senders/metrics_sender.rb +49 -0
- data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +48 -0
- data/lib/splitclient-rb/cache/stores/segment_store.rb +82 -0
- data/lib/splitclient-rb/cache/stores/split_store.rb +97 -0
- data/lib/splitclient-rb/clients/localhost_split_client.rb +92 -0
- data/lib/splitclient-rb/clients/split_client.rb +214 -0
- data/lib/splitclient-rb/engine/api/client.rb +74 -0
- data/lib/splitclient-rb/engine/api/events.rb +48 -0
- data/lib/splitclient-rb/engine/api/faraday_middleware/gzip.rb +55 -0
- data/lib/splitclient-rb/engine/api/impressions.rb +42 -0
- data/lib/splitclient-rb/engine/api/metrics.rb +61 -0
- data/lib/splitclient-rb/engine/api/segments.rb +62 -0
- data/lib/splitclient-rb/engine/api/splits.rb +60 -0
- data/lib/splitclient-rb/engine/evaluator/splitter.rb +123 -0
- data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +46 -0
- data/lib/splitclient-rb/engine/matchers/between_matcher.rb +56 -0
- data/lib/splitclient-rb/engine/matchers/combiners.rb +9 -0
- data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +86 -0
- data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +21 -0
- data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +19 -0
- data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +30 -0
- data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +20 -0
- data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +26 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +27 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +54 -0
- data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +19 -0
- data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +53 -0
- data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +53 -0
- data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +24 -0
- data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +60 -0
- data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +23 -0
- data/lib/splitclient-rb/engine/matchers/set_matcher.rb +20 -0
- data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +26 -0
- data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +45 -0
- data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +66 -0
- data/lib/splitclient-rb/engine/metrics/binary_search_latency_tracker.rb +128 -0
- data/lib/splitclient-rb/engine/metrics/metrics.rb +83 -0
- data/lib/splitclient-rb/engine/models/label.rb +8 -0
- data/lib/splitclient-rb/engine/models/split.rb +17 -0
- data/lib/splitclient-rb/engine/models/treatment.rb +3 -0
- data/lib/splitclient-rb/engine/parser/condition.rb +210 -0
- data/lib/splitclient-rb/engine/parser/evaluator.rb +118 -0
- data/lib/splitclient-rb/engine/parser/partition.rb +35 -0
- data/lib/splitclient-rb/engine/parser/split_adapter.rb +88 -0
- data/lib/splitclient-rb/exceptions/impressions_shutdown_exception.rb +4 -0
- data/lib/splitclient-rb/exceptions/sdk_blocker_timeout_expired_exception.rb +4 -0
- data/lib/splitclient-rb/localhost_split_factory.rb +13 -0
- data/lib/splitclient-rb/localhost_utils.rb +36 -0
- data/lib/splitclient-rb/managers/localhost_split_manager.rb +45 -0
- data/lib/splitclient-rb/managers/split_manager.rb +77 -0
- data/lib/splitclient-rb/split_config.rb +391 -0
- data/lib/splitclient-rb/split_factory.rb +35 -0
- data/lib/splitclient-rb/split_factory_builder.rb +16 -0
- data/lib/splitclient-rb/utilitites.rb +41 -0
- data/lib/splitclient-rb/version.rb +3 -0
- data/splitclient-rb.gemspec +50 -0
- data/splitio.yml.example +7 -0
- data/tasks/benchmark_get_treatment.rake +43 -0
- data/tasks/irb.rake +4 -0
- data/tasks/rspec.rake +3 -0
- metadata +321 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
class LessThanOrEqualToMatcher
|
|
3
|
+
MATCHER_TYPE = 'LESS_THAN_OR_EQUAL_TO'.freeze
|
|
4
|
+
|
|
5
|
+
attr_reader :attribute
|
|
6
|
+
|
|
7
|
+
def initialize(attribute_hash)
|
|
8
|
+
@attribute = attribute_hash[:attribute]
|
|
9
|
+
@data_type = attribute_hash[:data_type]
|
|
10
|
+
@value = formatted_value(attribute_hash[:value], true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def match?(args)
|
|
14
|
+
return false if !args.key?(:attributes) && !args.key?(:value)
|
|
15
|
+
return false if args.key?(:value) && args[:value].nil?
|
|
16
|
+
return false if args.key?(:attributes) && args[:attributes].nil?
|
|
17
|
+
|
|
18
|
+
value = formatted_value(args[:value] || args[:attributes][@attribute.to_sym])
|
|
19
|
+
|
|
20
|
+
value.is_a?(Integer) ? (value <= @value) : false
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def equals?(obj)
|
|
24
|
+
if obj.nil?
|
|
25
|
+
false
|
|
26
|
+
elsif !obj.instance_of?(LessThanOrEqualToMatcher)
|
|
27
|
+
false
|
|
28
|
+
elsif self.equal?(obj)
|
|
29
|
+
true
|
|
30
|
+
else
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def string_type?
|
|
36
|
+
false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def formatted_value(value, sdk_data = false)
|
|
42
|
+
case @data_type
|
|
43
|
+
when 'NUMBER'
|
|
44
|
+
return value
|
|
45
|
+
when 'DATETIME'
|
|
46
|
+
value = value / 1000 if sdk_data # sdk returns already miliseconds, turning to seconds to do a correct zero_our
|
|
47
|
+
return SplitIoClient::Utilities.to_milis_zero_out_from_seconds(value)
|
|
48
|
+
else
|
|
49
|
+
@logger.error('Invalid data type')
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
class MatchesStringMatcher
|
|
3
|
+
MATCHER_TYPE = 'MATCHES_STRING'.freeze
|
|
4
|
+
|
|
5
|
+
attr_reader :attribute
|
|
6
|
+
|
|
7
|
+
def initialize(attribute, regexp_string)
|
|
8
|
+
@attribute = attribute
|
|
9
|
+
@regexp_string = @regexp_string.is_a?(Regexp) ? regexp_string : Regexp.new(regexp_string)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def match?(args)
|
|
13
|
+
value = args[:value] || args[:attributes].fetch(@attribute) do |a|
|
|
14
|
+
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
(value =~ @regexp_string) != nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def string_type?
|
|
21
|
+
true
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
#
|
|
3
|
+
# class to implement the negation of a matcher
|
|
4
|
+
#
|
|
5
|
+
class NegationMatcher
|
|
6
|
+
MATCHER_TYPE = 'NEGATION_MATCHER'.freeze
|
|
7
|
+
|
|
8
|
+
def initialize(matcher = nil)
|
|
9
|
+
@matcher = matcher
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# evaluates if the key matches the negation of the matcher
|
|
14
|
+
#
|
|
15
|
+
# @param key [string] key value to be matched
|
|
16
|
+
#
|
|
17
|
+
# @return [boolean] evaluation of the negation matcher
|
|
18
|
+
def match?(args)
|
|
19
|
+
!@matcher.match?(args)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def respond_to?(method)
|
|
23
|
+
@matcher.respond_to? method
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def attribute
|
|
27
|
+
@matcher.attribute
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def string_type?
|
|
31
|
+
@matcher.string_type?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# evaluates if the given object equals the matcher
|
|
36
|
+
#
|
|
37
|
+
# @param obj [object] object to be evaluated
|
|
38
|
+
#
|
|
39
|
+
# @returns [boolean] true if obj equals the matcher
|
|
40
|
+
def equals?(obj)
|
|
41
|
+
if obj.nil?
|
|
42
|
+
false
|
|
43
|
+
elsif !obj.instance_of?(NegationMatcher)
|
|
44
|
+
false
|
|
45
|
+
elsif self.equal?(obj)
|
|
46
|
+
true
|
|
47
|
+
else
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# function to print string value for this matcher
|
|
54
|
+
#
|
|
55
|
+
# @reutrn [string] string value of this matcher
|
|
56
|
+
def to_s
|
|
57
|
+
"not #{@matcher}"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
class PartOfSetMatcher < SetMatcher
|
|
3
|
+
MATCHER_TYPE = 'PART_OF_SET'.freeze
|
|
4
|
+
|
|
5
|
+
attr_reader :attribute
|
|
6
|
+
|
|
7
|
+
def initialize(attribute, remote_array)
|
|
8
|
+
super(attribute, remote_array)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def match?(args)
|
|
12
|
+
@local_set = local_set(args[:attributes], @attribute)
|
|
13
|
+
|
|
14
|
+
return false if @local_set.empty?
|
|
15
|
+
|
|
16
|
+
@local_set.subset? @remote_set
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def string_type?
|
|
20
|
+
false
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
|
|
3
|
+
module SplitIoClient
|
|
4
|
+
class SetMatcher
|
|
5
|
+
protected
|
|
6
|
+
|
|
7
|
+
def initialize(attribute, remote_array)
|
|
8
|
+
@attribute = attribute
|
|
9
|
+
@remote_set = remote_array.to_set
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def local_set(data, attribute)
|
|
13
|
+
data = data.fetch(attribute) { |a| data[a.to_s] || data[a.to_sym] }
|
|
14
|
+
# Allow user to pass individual elements as well
|
|
15
|
+
local_array = data.kind_of?(Array) ? data : [data]
|
|
16
|
+
|
|
17
|
+
local_array.to_set
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
class StartsWithMatcher
|
|
3
|
+
MATCHER_TYPE = 'STARTS_WITH'.freeze
|
|
4
|
+
|
|
5
|
+
attr_reader :attribute
|
|
6
|
+
|
|
7
|
+
def initialize(attribute, prefix_list)
|
|
8
|
+
@attribute = attribute
|
|
9
|
+
@prefix_list = prefix_list
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def match?(args)
|
|
13
|
+
value = args[:value] || args[:attributes].fetch(@attribute) do |a|
|
|
14
|
+
args[:attributes][a.to_s] || args[:attributes][a.to_sym]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
return false if @prefix_list.empty?
|
|
18
|
+
|
|
19
|
+
@prefix_list.any? { |prefix| value.to_s.start_with? prefix }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def string_type?
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
#
|
|
3
|
+
# class to implement the user defined matcher
|
|
4
|
+
#
|
|
5
|
+
class UserDefinedSegmentMatcher
|
|
6
|
+
MATCHER_TYPE = 'IN_SEGMENT'.freeze
|
|
7
|
+
|
|
8
|
+
def initialize(segments_repository, segment_name)
|
|
9
|
+
@segments_repository = segments_repository
|
|
10
|
+
@segment_name = segment_name
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# evaluates if the key matches the matcher
|
|
15
|
+
#
|
|
16
|
+
# @param key [string] key value to be matched
|
|
17
|
+
#
|
|
18
|
+
# @return [boolean] evaluation of the key against the segment
|
|
19
|
+
def match?(args)
|
|
20
|
+
@segments_repository.in_segment?(@segment_name, args[:value] || args[:matching_key])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# evaluates if the given object equals the matcher
|
|
25
|
+
#
|
|
26
|
+
# @param obj [object] object to be evaluated
|
|
27
|
+
#
|
|
28
|
+
# @returns [boolean] true if obj equals the matcher
|
|
29
|
+
def equals?(obj)
|
|
30
|
+
if obj.nil?
|
|
31
|
+
false
|
|
32
|
+
elsif !obj.instance_of?(UserDefinedSegmentMatcher)
|
|
33
|
+
false
|
|
34
|
+
elsif self.equal?(obj)
|
|
35
|
+
true
|
|
36
|
+
else
|
|
37
|
+
false
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def string_type?
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
#
|
|
3
|
+
# class to implement the user defined matcher
|
|
4
|
+
#
|
|
5
|
+
class WhitelistMatcher < NoMethodError
|
|
6
|
+
MATCHER_TYPE = 'WHITELIST_MATCHER'
|
|
7
|
+
|
|
8
|
+
attr_reader :attribute
|
|
9
|
+
|
|
10
|
+
def initialize(whitelist_data)
|
|
11
|
+
@whitelist = case whitelist_data
|
|
12
|
+
when Array
|
|
13
|
+
whitelist_data
|
|
14
|
+
when Hash
|
|
15
|
+
@matcher_type = 'ATTR_WHITELIST'
|
|
16
|
+
@attribute = whitelist_data[:attribute]
|
|
17
|
+
|
|
18
|
+
whitelist_data[:value]
|
|
19
|
+
else
|
|
20
|
+
[]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def match?(args)
|
|
25
|
+
return @whitelist.include?(args[:value] || args[:matching_key]) unless @matcher_type == 'ATTR_WHITELIST'
|
|
26
|
+
|
|
27
|
+
return false if !args.key?(:attributes) && !args.key?(:value)
|
|
28
|
+
return false if args.key?(:value) && args[:value].nil?
|
|
29
|
+
return false if args.key?(:attributes) && args[:attributes].nil?
|
|
30
|
+
|
|
31
|
+
return @whitelist.include?(args[:value] || args[:attributes][@attribute.to_sym])
|
|
32
|
+
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#
|
|
37
|
+
# evaluates if the given object equals the matcher
|
|
38
|
+
#
|
|
39
|
+
# @param obj [object] object to be evaluated
|
|
40
|
+
#
|
|
41
|
+
# @returns [boolean] true if obj equals the matcher
|
|
42
|
+
def equals?(obj)
|
|
43
|
+
if obj.nil?
|
|
44
|
+
false
|
|
45
|
+
elsif !obj.instance_of?(WhitelistMatcher)
|
|
46
|
+
false
|
|
47
|
+
elsif self.equal?(obj)
|
|
48
|
+
true
|
|
49
|
+
else
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def string_type?
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#
|
|
59
|
+
# function to print string value for this matcher
|
|
60
|
+
#
|
|
61
|
+
# @reutrn [string] string value of this matcher
|
|
62
|
+
def to_s
|
|
63
|
+
"in segment #{@whitelist}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module SplitIoClient
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Tracks latencies pero bucket of time.
|
|
5
|
+
# Each bucket represent a latency greater than the one before
|
|
6
|
+
# and each number within each bucket is a number of calls in the range.
|
|
7
|
+
#
|
|
8
|
+
# (1) 1.00
|
|
9
|
+
# (2) 1.50
|
|
10
|
+
# (3) 2.25
|
|
11
|
+
# (4) 3.38
|
|
12
|
+
# (5) 5.06
|
|
13
|
+
# (6) 7.59
|
|
14
|
+
# (7) 11.39
|
|
15
|
+
# (8) 17.09
|
|
16
|
+
# (9) 25.63
|
|
17
|
+
# (10) 38.44
|
|
18
|
+
# (11) 57.67
|
|
19
|
+
# (12) 86.50
|
|
20
|
+
# (13) 129.75
|
|
21
|
+
# (14) 194.62
|
|
22
|
+
# (15) 291.93
|
|
23
|
+
# (16) 437.89
|
|
24
|
+
# (17) 656.84
|
|
25
|
+
# (18) 985.26
|
|
26
|
+
# (19) 1,477.89
|
|
27
|
+
# (20) 2,216.84
|
|
28
|
+
# (21) 3,325.26
|
|
29
|
+
# (22) 4,987.89
|
|
30
|
+
# (23) 7,481.83
|
|
31
|
+
#
|
|
32
|
+
# Created by fvitale on 2/17/16 based on java implementation by patricioe.
|
|
33
|
+
#
|
|
34
|
+
|
|
35
|
+
class BinarySearchLatencyTracker < NoMethodError
|
|
36
|
+
|
|
37
|
+
BUCKETS = [ 1000, 1500, 2250, 3375, 5063,
|
|
38
|
+
7594, 11391, 17086, 25629, 38443,
|
|
39
|
+
57665, 86498, 129746, 194620, 291929,
|
|
40
|
+
437894, 656841, 985261, 1477892, 2216838,
|
|
41
|
+
3325257, 4987885, 7481828 ].freeze
|
|
42
|
+
|
|
43
|
+
MAX_LATENCY = 7481828
|
|
44
|
+
|
|
45
|
+
attr_accessor :latencies
|
|
46
|
+
|
|
47
|
+
def initialize
|
|
48
|
+
@latencies = Array.new(BUCKETS.length, 0)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#
|
|
52
|
+
# Increment the internal counter for the bucket this latency falls into.
|
|
53
|
+
# @param millis
|
|
54
|
+
#
|
|
55
|
+
def add_latency_millis(millis, return_index = false)
|
|
56
|
+
index = find_bucket_index(millis * 1000)
|
|
57
|
+
|
|
58
|
+
return index if return_index
|
|
59
|
+
|
|
60
|
+
@latencies[index] += 1
|
|
61
|
+
@latencies
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Increment the internal counter for the bucket this latency falls into.
|
|
65
|
+
# @param micros
|
|
66
|
+
def add_latency_micros(micros, return_index = false)
|
|
67
|
+
index = find_bucket_index(micros)
|
|
68
|
+
|
|
69
|
+
return index if return_index
|
|
70
|
+
|
|
71
|
+
@latencies[index] += 1
|
|
72
|
+
@latencies
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns the list of latencies buckets as an array.
|
|
76
|
+
#
|
|
77
|
+
#
|
|
78
|
+
# @return the list of latencies buckets as an array.
|
|
79
|
+
def get_latencies
|
|
80
|
+
@latencies
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def get_latency(index)
|
|
84
|
+
return @latencies[index]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def clear
|
|
88
|
+
@latencies = Array.new(BUCKETS.length, 0)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
#
|
|
92
|
+
# Returns the counts in the bucket this latency falls into.
|
|
93
|
+
# The latencies will not be updated.
|
|
94
|
+
# @param latency
|
|
95
|
+
# @return the bucket content for the latency.
|
|
96
|
+
#
|
|
97
|
+
def get_bucket_for_latency_millis(latency)
|
|
98
|
+
return @latencies[find_bucket_index(latency * 1000)]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
#
|
|
102
|
+
# Returns the counts in the bucket this latency falls into.
|
|
103
|
+
# The latencies will not be updated.
|
|
104
|
+
# @param latency
|
|
105
|
+
# @return the bucket content for the latency.
|
|
106
|
+
#
|
|
107
|
+
def get_bucket_for_latency_micros(latency)
|
|
108
|
+
return @latencies[find_bucket_index(latency)]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def find_bucket_index(micros)
|
|
114
|
+
if (micros > MAX_LATENCY) then
|
|
115
|
+
return BUCKETS.length - 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
if (micros < 1500) then
|
|
119
|
+
return 0
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
index = BUCKETS.find_index(BUCKETS.bsearch {|x| x >= micros })
|
|
123
|
+
|
|
124
|
+
return index
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
end
|