Class: Redis::HashRing
- Inherits:
- 
      Object
      
        - Object
- Redis::HashRing
 
- Defined in:
- lib/redis/hash_ring.rb
Constant Summary collapse
- POINTS_PER_SERVER =
          this is the default in libmemcached 
- 160
Instance Attribute Summary collapse
- 
  
    
      #nodes  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute nodes. 
- 
  
    
      #replicas  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute replicas. 
- 
  
    
      #ring  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute ring. 
- 
  
    
      #sorted_keys  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute sorted_keys. 
Class Method Summary collapse
- 
  
    
      .binary_search(ary, value)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Find the closest index in HashRing with value <= the given value. 
Instance Method Summary collapse
- 
  
    
      #add_node(node)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Adds a ‘node` to the hash ring (including a number of replicas). 
- 
  
    
      #get_node(key)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    get the node in the hash ring for this key. 
- #get_node_pos(key) ⇒ Object
- 
  
    
      #initialize(nodes = [], replicas = POINTS_PER_SERVER)  ⇒ HashRing 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    nodes is a list of objects that have a proper to_s representation. 
- #iter_nodes(key) ⇒ Object
- #remove_node(node) ⇒ Object
Constructor Details
#initialize(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.
| 14 15 16 17 18 19 20 21 22 | # File 'lib/redis/hash_ring.rb', line 14 def initialize(nodes = [], replicas = POINTS_PER_SERVER) @replicas = replicas @ring = {} @nodes = [] @sorted_keys = [] nodes.each do |node| add_node(node) end end | 
Instance Attribute Details
#nodes ⇒ Object (readonly)
Returns the value of attribute nodes.
| 9 10 11 | # File 'lib/redis/hash_ring.rb', line 9 def nodes @nodes end | 
#replicas ⇒ Object (readonly)
Returns the value of attribute replicas.
| 9 10 11 | # File 'lib/redis/hash_ring.rb', line 9 def replicas @replicas end | 
#ring ⇒ Object (readonly)
Returns the value of attribute ring.
| 9 10 11 | # File 'lib/redis/hash_ring.rb', line 9 def ring @ring end | 
#sorted_keys ⇒ Object (readonly)
Returns the value of attribute sorted_keys.
| 9 10 11 | # File 'lib/redis/hash_ring.rb', line 9 def sorted_keys @sorted_keys end | 
Class Method Details
.binary_search(ary, value) ⇒ Object
Find the closest index in HashRing with value <= the given value
| 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | # File 'lib/redis/hash_ring.rb', line 67 def self.binary_search(ary, value) upper = ary.size - 1 lower = 0 idx = 0 while lower <= upper idx = (lower + upper) / 2 comp = ary[idx] <=> value if comp == 0 return idx elsif comp > 0 upper = idx - 1 else lower = idx + 1 end end upper = ary.size - 1 if upper < 0 upper end | 
Instance Method Details
#add_node(node) ⇒ Object
Adds a ‘node` to the hash ring (including a number of replicas).
| 25 26 27 28 29 30 31 32 33 | # File 'lib/redis/hash_ring.rb', line 25 def add_node(node) @nodes << node @replicas.times do |i| key = Zlib.crc32("#{node.id}:#{i}") @ring[key] = node @sorted_keys << key end @sorted_keys.sort! end | 
#get_node(key) ⇒ Object
get the node in the hash ring for this key
| 45 46 47 | # File 'lib/redis/hash_ring.rb', line 45 def get_node(key) get_node_pos(key)[0] end | 
#get_node_pos(key) ⇒ Object
| 49 50 51 52 53 54 55 | # File 'lib/redis/hash_ring.rb', line 49 def get_node_pos(key) return [nil, nil] if @ring.empty? crc = Zlib.crc32(key) idx = HashRing.binary_search(@sorted_keys, crc) [@ring[@sorted_keys[idx]], idx] end | 
#iter_nodes(key) ⇒ Object
| 57 58 59 60 61 62 63 64 | # File 'lib/redis/hash_ring.rb', line 57 def iter_nodes(key) return [nil, nil] if @ring.empty? _, pos = get_node_pos(key) @ring.size.times do |n| yield @ring[@sorted_keys[(pos + n) % @ring.size]] end end | 
#remove_node(node) ⇒ Object
| 35 36 37 38 39 40 41 42 | # File 'lib/redis/hash_ring.rb', line 35 def remove_node(node) @nodes.reject! { |n| n.id == node.id } @replicas.times do |i| key = Zlib.crc32("#{node.id}:#{i}") @ring.delete(key) @sorted_keys.reject! { |k| k == key } end end |