Class: ActiveRecord::Turntable::Algorithm::RangeBsearchAlgorithm

Inherits:
Base
  • Object
show all
Defined in:
lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ RangeBsearchAlgorithm

Returns a new instance of RangeBsearchAlgorithm.



5
6
7
8
# File 'lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb', line 5

def initialize(config)
  @config = config
  @config["shards"].sort_by! {|a| a["less_than"]}
end

Instance Method Details

#calculate(key) ⇒ Object



10
11
12
13
14
15
# File 'lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb', line 10

def calculate(key)
  idx = calculate_idx(key)
  @config["shards"][idx]["connection"]
rescue
  raise ActiveRecord::Turntable::CannotSpecifyShardError, "cannot specify shard for key:#{key}"
end

#calculate_idx(key) ⇒ Object



17
18
19
20
21
# File 'lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb', line 17

def calculate_idx(key)
  @config["shards"].bsearch_upper_boundary { |h|
    h["less_than"] <=> key
  }
end

#calculate_used_shards_with_weight(sequence_value) ⇒ Object

{ connection_name => weight, … }



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb', line 24

def calculate_used_shards_with_weight(sequence_value)
  idx = calculate_idx(sequence_value)
  last_connection = calculate(sequence_value)
  shards = @config["shards"][0..idx]
  weighted_hash = Hash.new {|h,k| h[k]=0}
  prev_max = 0
  shards.each_with_index do |h,idx|
    weighted_hash[h["connection"]] += if idx < shards.size - 1
                                        h["less_than"] - prev_max - 1
                                      else
                                        sequence_value - prev_max
                                      end
    prev_max = h["less_than"] - 1
  end
  return weighted_hash
end