class ABSplit::Functions::WeightedSplit
Weighted split based on hash value.
Non persistent - No collisions are possible
Based on memory position
Constants
- MAX_POSITIONS
Public Class Methods
value_for(value, *params)
click to toggle source
# File lib/a_b_split/functions/weighted_split.rb, line 14 def value_for(value, *params) given_weights = validate(params) experiments = split_weights(params, params.size, given_weights) select_experiment_for(value, experiments) end
Protected Class Methods
select_experiment_for(value, experiments)
click to toggle source
# File lib/a_b_split/functions/weighted_split.rb, line 53 def select_experiment_for(value, experiments) x_position = value.hash markers(experiments).each_with_index do |limit, i| return experiments[i]['name'] if x_position <= limit end experiments.last['name'] end
split_weights(experiments, parts, given_percentage)
click to toggle source
# File lib/a_b_split/functions/weighted_split.rb, line 36 def split_weights(experiments, parts, given_percentage) return experiments if given_percentage.size >= parts missing_weights = parts - given_percentage.size missing_percentage = 100 - given_percentage.reduce(0, &:+) experiments.map do |experiment| experiment['weight'] = if experiment['weight'] experiment['weight'].to_f else missing_percentage.to_f / missing_weights end experiment end end
validate(experiments)
click to toggle source
# File lib/a_b_split/functions/weighted_split.rb, line 24 def validate(experiments) given_weights = experiments.each_with_object([]) do |param, memo| memo << param['weight'] if param.key?('weight') end unless experiments.any? && experiments.size > 1 && given_weights.reduce(0, &:+) <= 100 raise ABSplit::NoValidExperiment end given_weights end
Private Class Methods
markers(experiments)
click to toggle source
# File lib/a_b_split/functions/weighted_split.rb, line 65 def markers(experiments) experiments.map do |experiment| (self::MAX_POSITIONS * (experiment['weight'] / 100)) - (self::MAX_POSITIONS / 2) end end