Class: RedisClient::HashRing

Inherits:
Object
  • Object
show all
Defined in:
lib/redis_client/hash_ring.rb

Constant Summary collapse

POINTS_PER_SERVER =
160

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nodes = [], replicas: POINTS_PER_SERVER, digest: self.class.digest) ⇒ HashRing

Returns a new instance of HashRing.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/redis_client/hash_ring.rb', line 22

def initialize(nodes = [], replicas: POINTS_PER_SERVER, digest: self.class.digest)
  @replicas = replicas
  @ring = {}
  @digest = digest
  ids = {}
  @nodes = nodes.dup.freeze
  nodes.each do |node|
    id = node.id || node.config.server_url
    if ids[id]
      raise ArgumentError, "duplicate node id: #{id.inspect}"
    end

    ids[id] = true

    replicas.times do |i|
      @ring[server_hash_for("#{id}:#{i}".freeze)] = node
    end
  end
  @sorted_keys = @ring.keys
  @sorted_keys.sort!
end

Class Attribute Details

.digestObject



12
13
14
15
16
17
# File 'lib/redis_client/hash_ring.rb', line 12

def digest
  @digest ||= begin
    require 'digest/md5'
    Digest::MD5
  end
end

Instance Attribute Details

#nodesObject (readonly)

Returns the value of attribute nodes.



20
21
22
# File 'lib/redis_client/hash_ring.rb', line 20

def nodes
  @nodes
end

Instance Method Details

#node_for(key) ⇒ Object

get the node in the hash ring for this key



45
46
47
48
49
# File 'lib/redis_client/hash_ring.rb', line 45

def node_for(key)
  hash = hash_for(key)
  idx = binary_search(@sorted_keys, hash)
  @ring[@sorted_keys[idx]]
end

#nodes_for(*keys) ⇒ Object



51
52
53
54
55
56
57
58
# File 'lib/redis_client/hash_ring.rb', line 51

def nodes_for(*keys)
  keys.flatten!
  mapping = {}
  keys.each do |key|
    (mapping[node_for(key)] ||= []) << key
  end
  mapping
end