Exception: SplitIoClient::Splitter

Inherits:
NoMethodError
  • Object
show all
Defined in:
lib/engine/evaluator/splitter.rb

Overview

Misc class in charge of providing hash functions and determination of treatment based on concept of buckets based on provided key

Class Method Summary collapse

Class Method Details

.bucket(hash_value) ⇒ Object

returns bucket value for the given hash value

Parameters:

  • hash_value (string)

    hash value



104
105
106
# File 'lib/engine/evaluator/splitter.rb', line 104

def self.bucket(hash_value)
  (hash_value.abs % 100) + 1
end

.get_treatment(id, seed, partitions) ⇒ Object

gets the appropriate treatment based on id, seed and partition value

Parameters:

  • id (string)

    user key

  • seed (number)

    seed for the user key

  • partitions (object)

    array of partitions



30
31
32
33
34
35
36
37
38
39
40
# File 'lib/engine/evaluator/splitter.rb', line 30

def self.get_treatment(id, seed, partitions)
  if partitions.empty?
    return Treatments::CONTROL
  end

  if hundred_percent_one_treatment?(partitions)
    return (partitions.first).treatment
  end

  return get_treatment_for_key(bucket(hash(id, seed)), partitions)
end

.get_treatment_for_key(bucket, partitions) ⇒ Object

returns the treatment for a bucket given the partitions

Parameters:

  • bucket (number)

    bucket value

  • parittions (object)

    array of partitions



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/engine/evaluator/splitter.rb', line 86

def self.get_treatment_for_key(bucket, partitions)
  buckets_covered_thus_far = 0
  partitions.each do |p|
    unless p.is_empty?
      buckets_covered_thus_far += p.size
      return p.treatment if buckets_covered_thus_far >= bucket
    end
  end

  return Treatments::CONTROL
end

.hash(key, seed) ⇒ Object

returns a hash value for the give key, sedd pair

Parameters:

  • key (string)

    user key

  • seed (number)

    seed for the user key



49
50
51
52
53
54
55
# File 'lib/engine/evaluator/splitter.rb', line 49

def self.hash(key, seed)
  h = 0
  for i in 0..key.length-1
    h = to_int32(31 * h + key[i].ord)
  end
  h^seed
end

.hundred_percent_one_treatment?(partitions) ⇒ boolean

Checks if the partiotion size is 100%

Parameters:

  • partitions (object)

    array of partitions

Returns:

  • (boolean)

    true if partition is 100% false otherwise



14
15
16
17
18
19
# File 'lib/engine/evaluator/splitter.rb', line 14

def self.hundred_percent_one_treatment?(partitions)
  if partitions.size != 1
    return false
  end
  return (partitions.first).size == 100
end

.to_int32(number) ⇒ int

misc method to convert ruby number to int 32 since overflow is handled different to java

Parameters:

  • number (number)

    ruby number value

Returns:

  • (int)

    returns the int 32 value of the provided number



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/engine/evaluator/splitter.rb', line 63

def self.to_int32(number)
  begin
    sign = number < 0 ? -1 : 1
    abs = number.abs
    return 0 if abs == 0 || abs == Float::INFINITY
  rescue
    return 0
  end

  pos_int = sign * abs.floor
  int_32bit = pos_int % 2**32

  return int_32bit - 2**32 if int_32bit >= 2**31
  int_32bit
end