Skip to content

Commit e70a783

Browse files
committed
Optimize getting server for key in Redis::Distributed
1 parent 926fd27 commit e70a783

File tree

2 files changed

+23
-33
lines changed

2 files changed

+23
-33
lines changed

lib/redis/distributed.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,8 @@ def node_index_for(key)
10041004
end
10051005

10061006
def key_tag(key)
1007-
key.to_s[@tag, 1] if @tag
1007+
key = key.to_s
1008+
key[@tag, 1] if key.match?(@tag)
10081009
end
10091010

10101011
def ensure_same_node(command, keys)

lib/redis/hash_ring.rb

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,49 +44,21 @@ def remove_node(node)
4444

4545
# get the node in the hash ring for this key
4646
def get_node(key)
47-
get_node_pos(key)[0]
48-
end
49-
50-
def get_node_pos(key)
51-
return [nil, nil] if @ring.empty?
52-
5347
hash = hash_for(key)
54-
idx = HashRing.binary_search(@sorted_keys, hash)
55-
[@ring[@sorted_keys[idx]], idx]
48+
idx = binary_search(@sorted_keys, hash)
49+
@ring[@sorted_keys[idx]]
5650
end
5751

5852
def iter_nodes(key)
5953
return [nil, nil] if @ring.empty?
6054

61-
_, pos = get_node_pos(key)
55+
crc = hash_for(key)
56+
pos = binary_search(@sorted_keys, crc)
6257
@ring.size.times do |n|
6358
yield @ring[@sorted_keys[(pos + n) % @ring.size]]
6459
end
6560
end
6661

67-
# Find the closest index in HashRing with value <= the given value
68-
def self.binary_search(ary, value)
69-
upper = ary.size - 1
70-
lower = 0
71-
idx = 0
72-
73-
while lower <= upper
74-
idx = (lower + upper) / 2
75-
comp = ary[idx] <=> value
76-
77-
if comp == 0
78-
return idx
79-
elsif comp > 0
80-
upper = idx - 1
81-
else
82-
lower = idx + 1
83-
end
84-
end
85-
86-
upper = ary.size - 1 if upper < 0
87-
upper
88-
end
89-
9062
private
9163

9264
def hash_for(key)
@@ -96,5 +68,22 @@ def hash_for(key)
9668
def server_hash_for(key)
9769
Digest::MD5.digest(key).unpack1("L>")
9870
end
71+
72+
# Find the closest index in HashRing with value <= the given value
73+
def binary_search(ary, value)
74+
upper = ary.size
75+
lower = 0
76+
77+
while lower < upper
78+
mid = (lower + upper) / 2
79+
if ary[mid] > value
80+
upper = mid
81+
else
82+
lower = mid + 1
83+
end
84+
end
85+
86+
upper - 1
87+
end
9988
end
10089
end

0 commit comments

Comments
 (0)