Class: Redis::HashRing
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/redis/hash_ring.rb |
Constant Summary
-
POINTS_PER_SERVER =
this is the default in libmemcached
160
Class Method Summary
-
.new(nodes = [], replicas = POINTS_PER_SERVER) ⇒ HashRing
constructor
nodes is a list of objects that have a proper to_s representation.
Instance Attribute Summary
- #nodes readonly
- #replicas readonly
- #ring readonly
- #sorted_keys readonly
Instance Method Summary
-
#add_node(node)
Adds a
node
to the hash ring (including a number of replicas). -
#get_node(key)
get the node in the hash ring for this key.
- #iter_nodes(key)
- #remove_node(node)
-
#binary_search(ary, value)
private
Find the closest index in
HashRing
with value <= the given value. - #hash_for(key) private
- #server_hash_for(key) private
Constructor Details
.new(nodes = [], replicas = POINTS_PER_SERVER) ⇒ HashRing
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.
Instance Attribute Details
#nodes (readonly)
[ GitHub ]# File 'lib/redis/hash_ring.rb', line 10
attr_reader :ring, :sorted_keys, :replicas, :nodes
#replicas (readonly)
[ GitHub ]# File 'lib/redis/hash_ring.rb', line 10
attr_reader :ring, :sorted_keys, :replicas, :nodes
#ring (readonly)
[ GitHub ]# File 'lib/redis/hash_ring.rb', line 10
attr_reader :ring, :sorted_keys, :replicas, :nodes
#sorted_keys (readonly)
[ GitHub ]Instance Method Details
#add_node(node)
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
#binary_search(ary, value) (private)
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
#get_node(key)
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
#hash_for(key) (private)
[ GitHub ]# File 'lib/redis/hash_ring.rb', line 64
def hash_for(key) Zlib.crc32(key) end
#iter_nodes(key)
[ GitHub ]# 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)
[ GitHub ]# 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
#server_hash_for(key) (private)
[ GitHub ]# File 'lib/redis/hash_ring.rb', line 68
def server_hash_for(key) Digest::MD5.digest(key).unpack1("L>") end