class Redis::HashRing
Constants
- POINTS_PER_SERVER
Attributes
nodes[R]
replicas[R]
ring[R]
sorted_keys[R]
Public Class Methods
new(nodes = [], replicas = POINTS_PER_SERVER)
click to toggle source
nodes is a list of objects that have a proper to_s representation. replicas indicates how many virtual points should be used pr. node, replicas are required to improve the distribution.
# File lib/redis/hash_ring.rb, line 15 def initialize(nodes = [], replicas = POINTS_PER_SERVER) @replicas = replicas @ring = {} @nodes = [] @sorted_keys = [] nodes.each do |node| add_node(node) end end
Public Instance Methods
add_node(node)
click to toggle source
Adds a ‘node` to the hash ring (including a number of replicas).
# File lib/redis/hash_ring.rb, line 26 def add_node(node) @nodes << node @replicas.times do |i| key = server_hash_for("#{node.id}:#{i}") @ring[key] = node @sorted_keys << key end @sorted_keys.sort! end
get_node(key)
click to toggle source
get the node in the hash ring for this key
# File lib/redis/hash_ring.rb, line 46 def get_node(key) hash = hash_for(key) idx = binary_search(@sorted_keys, hash) @ring[@sorted_keys[idx]] end
iter_nodes(key) { |ring[sorted_keys| ... }
click to toggle source
# File lib/redis/hash_ring.rb, line 52 def iter_nodes(key) return [nil, nil] if @ring.empty? crc = hash_for(key) pos = binary_search(@sorted_keys, crc) @ring.size.times do |n| yield @ring[@sorted_keys[(pos + n) % @ring.size]] end end
remove_node(node)
click to toggle source
# File lib/redis/hash_ring.rb, line 36 def remove_node(node) @nodes.reject! { |n| n.id == node.id } @replicas.times do |i| key = server_hash_for("#{node.id}:#{i}") @ring.delete(key) @sorted_keys.reject! { |k| k == key } end end
Private Instance Methods
binary_search(ary, value)
click to toggle source
Find the closest index in HashRing
with value <= the given value
# File lib/redis/hash_ring.rb, line 73 def binary_search(ary, value) upper = ary.size lower = 0 while lower < upper mid = (lower + upper) / 2 if ary[mid] > value upper = mid else lower = mid + 1 end end upper - 1 end
hash_for(key)
click to toggle source
# File lib/redis/hash_ring.rb, line 64 def hash_for(key) Zlib.crc32(key) end
server_hash_for(key)
click to toggle source
# File lib/redis/hash_ring.rb, line 68 def server_hash_for(key) Digest::MD5.digest(key).unpack1("L>") end