redis 4.1.4 → 4.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +141 -0
  3. data/README.md +52 -27
  4. data/lib/redis/client.rb +122 -87
  5. data/lib/redis/cluster/command.rb +4 -6
  6. data/lib/redis/cluster/command_loader.rb +8 -9
  7. data/lib/redis/cluster/node.rb +17 -1
  8. data/lib/redis/cluster/node_loader.rb +8 -11
  9. data/lib/redis/cluster/option.rb +18 -5
  10. data/lib/redis/cluster/slot.rb +28 -14
  11. data/lib/redis/cluster/slot_loader.rb +11 -15
  12. data/lib/redis/cluster.rb +37 -13
  13. data/lib/redis/commands/bitmaps.rb +63 -0
  14. data/lib/redis/commands/cluster.rb +45 -0
  15. data/lib/redis/commands/connection.rb +58 -0
  16. data/lib/redis/commands/geo.rb +84 -0
  17. data/lib/redis/commands/hashes.rb +251 -0
  18. data/lib/redis/commands/hyper_log_log.rb +37 -0
  19. data/lib/redis/commands/keys.rb +411 -0
  20. data/lib/redis/commands/lists.rb +289 -0
  21. data/lib/redis/commands/pubsub.rb +72 -0
  22. data/lib/redis/commands/scripting.rb +114 -0
  23. data/lib/redis/commands/server.rb +188 -0
  24. data/lib/redis/commands/sets.rb +207 -0
  25. data/lib/redis/commands/sorted_sets.rb +812 -0
  26. data/lib/redis/commands/streams.rb +382 -0
  27. data/lib/redis/commands/strings.rb +313 -0
  28. data/lib/redis/commands/transactions.rb +139 -0
  29. data/lib/redis/commands.rb +242 -0
  30. data/lib/redis/connection/command_helper.rb +4 -2
  31. data/lib/redis/connection/hiredis.rb +6 -7
  32. data/lib/redis/connection/registry.rb +1 -1
  33. data/lib/redis/connection/ruby.rb +106 -114
  34. data/lib/redis/connection/synchrony.rb +16 -10
  35. data/lib/redis/connection.rb +2 -1
  36. data/lib/redis/distributed.rb +200 -65
  37. data/lib/redis/errors.rb +10 -0
  38. data/lib/redis/hash_ring.rb +14 -14
  39. data/lib/redis/pipeline.rb +133 -10
  40. data/lib/redis/subscribe.rb +10 -12
  41. data/lib/redis/version.rb +2 -1
  42. data/lib/redis.rb +158 -3358
  43. metadata +32 -10
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
- require_relative "hash_ring"
2
+
3
+ require "redis/hash_ring"
3
4
 
4
5
  class Redis
5
6
  class Distributed
6
-
7
7
  class CannotDistribute < RuntimeError
8
8
  def initialize(command)
9
9
  @command = command
10
10
  end
11
11
 
12
12
  def message
13
- "#{@command.to_s.upcase} cannot be used in Redis::Distributed because the keys involved need to be on the same server or because we cannot guarantee that the operation will be atomic."
13
+ "#{@command.to_s.upcase} cannot be used in Redis::Distributed because the keys involved need " \
14
+ "to be on the same server or because we cannot guarantee that the operation will be atomic."
14
15
  end
15
16
  end
16
17
 
@@ -23,10 +24,14 @@ class Redis
23
24
  @default_options = options.dup
24
25
  node_configs.each { |node_config| add_node(node_config) }
25
26
  @subscribed_node = nil
27
+ @watch_key = nil
26
28
  end
27
29
 
28
30
  def node_for(key)
29
- @ring.get_node(key_tag(key.to_s) || key.to_s)
31
+ key = key_tag(key.to_s) || key.to_s
32
+ raise CannotDistribute, :watch if @watch_key && @watch_key != key
33
+
34
+ @ring.get_node(key)
30
35
  end
31
36
 
32
37
  def nodes
@@ -34,9 +39,9 @@ class Redis
34
39
  end
35
40
 
36
41
  def add_node(options)
37
- options = { :url => options } if options.is_a?(String)
42
+ options = { url: options } if options.is_a?(String)
38
43
  options = @default_options.merge(options)
39
- @ring.add_node Redis.new( options )
44
+ @ring.add_node Redis.new(options)
40
45
  end
41
46
 
42
47
  # Change the selected database for the current connection.
@@ -145,12 +150,12 @@ class Redis
145
150
  end
146
151
 
147
152
  # Create a key using the serialized value, previously obtained using DUMP.
148
- def restore(key, ttl, serialized_value, options = {})
149
- node_for(key).restore(key, ttl, serialized_value, options)
153
+ def restore(key, ttl, serialized_value, **options)
154
+ node_for(key).restore(key, ttl, serialized_value, **options)
150
155
  end
151
156
 
152
157
  # Transfer a key from the connected instance to another instance.
153
- def migrate(key, options)
158
+ def migrate(_key, _options)
154
159
  raise CannotDistribute, :migrate
155
160
  end
156
161
 
@@ -171,8 +176,29 @@ class Redis
171
176
  end
172
177
 
173
178
  # Determine if a key exists.
174
- def exists(key)
175
- node_for(key).exists(key)
179
+ def exists(*args)
180
+ if !Redis.exists_returns_integer && args.size == 1
181
+ ::Redis.deprecate!(
182
+ "`Redis#exists(key)` will return an Integer in redis-rb 4.3, if you want to keep the old behavior, " \
183
+ "use `exists?` instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer = true. " \
184
+ "(#{::Kernel.caller(1, 1).first})\n"
185
+ )
186
+ exists?(*args)
187
+ else
188
+ keys_per_node = args.group_by { |key| node_for(key) }
189
+ keys_per_node.inject(0) do |sum, (node, keys)|
190
+ sum + node._exists(*keys)
191
+ end
192
+ end
193
+ end
194
+
195
+ # Determine if any of the keys exists.
196
+ def exists?(*args)
197
+ keys_per_node = args.group_by { |key| node_for(key) }
198
+ keys_per_node.each do |node, keys|
199
+ return true if node.exists?(*keys)
200
+ end
201
+ false
176
202
  end
177
203
 
178
204
  # Find all keys matching the given pattern.
@@ -185,6 +211,13 @@ class Redis
185
211
  node_for(key).move(key, db)
186
212
  end
187
213
 
214
+ # Copy a value from one key to another.
215
+ def copy(source, destination, **options)
216
+ ensure_same_node(:copy, [source, destination]) do |node|
217
+ node.copy(source, destination, **options)
218
+ end
219
+ end
220
+
188
221
  # Return a random key from the keyspace.
189
222
  def randomkey
190
223
  raise CannotDistribute, :randomkey
@@ -205,11 +238,11 @@ class Redis
205
238
  end
206
239
 
207
240
  # Sort the elements in a list, set or sorted set.
208
- def sort(key, options = {})
241
+ def sort(key, **options)
209
242
  keys = [key, options[:by], options[:store], *Array(options[:get])].compact
210
243
 
211
244
  ensure_same_node(:sort, keys) do |node|
212
- node.sort(key, options)
245
+ node.sort(key, **options)
213
246
  end
214
247
  end
215
248
 
@@ -244,8 +277,8 @@ class Redis
244
277
  end
245
278
 
246
279
  # Set the string value of a key.
247
- def set(key, value, options = {})
248
- node_for(key).set(key, value, options)
280
+ def set(key, value, **options)
281
+ node_for(key).set(key, value, **options)
249
282
  end
250
283
 
251
284
  # Set the time to live in seconds of a key.
@@ -264,20 +297,20 @@ class Redis
264
297
  end
265
298
 
266
299
  # Set multiple keys to multiple values.
267
- def mset(*args)
300
+ def mset(*_args)
268
301
  raise CannotDistribute, :mset
269
302
  end
270
303
 
271
- def mapped_mset(hash)
304
+ def mapped_mset(_hash)
272
305
  raise CannotDistribute, :mapped_mset
273
306
  end
274
307
 
275
308
  # Set multiple keys to multiple values, only if none of the keys exist.
276
- def msetnx(*args)
309
+ def msetnx(*_args)
277
310
  raise CannotDistribute, :msetnx
278
311
  end
279
312
 
280
- def mapped_msetnx(hash)
313
+ def mapped_msetnx(_hash)
281
314
  raise CannotDistribute, :mapped_msetnx
282
315
  end
283
316
 
@@ -286,6 +319,16 @@ class Redis
286
319
  node_for(key).get(key)
287
320
  end
288
321
 
322
+ # Get the value of a key and delete it.
323
+ def getdel(key)
324
+ node_for(key).getdel(key)
325
+ end
326
+
327
+ # Get the value of a key and sets its time to live based on options.
328
+ def getex(key, **options)
329
+ node_for(key).getex(key, **options)
330
+ end
331
+
289
332
  # Get the values of all the given keys as an Array.
290
333
  def mget(*keys)
291
334
  mapped_mget(*keys).values_at(*keys)
@@ -336,7 +379,7 @@ class Redis
336
379
  end
337
380
 
338
381
  # Return the position of the first bit set to 1 or 0 in a string.
339
- def bitpos(key, bit, start=nil, stop=nil)
382
+ def bitpos(key, bit, start = nil, stop = nil)
340
383
  node_for(key).bitpos(key, bit, start, stop)
341
384
  end
342
385
 
@@ -354,7 +397,7 @@ class Redis
354
397
  get(key)
355
398
  end
356
399
 
357
- def []=(key,value)
400
+ def []=(key, value)
358
401
  set(key, value)
359
402
  end
360
403
 
@@ -363,6 +406,21 @@ class Redis
363
406
  node_for(key).llen(key)
364
407
  end
365
408
 
409
+ # Remove the first/last element in a list, append/prepend it to another list and return it.
410
+ def lmove(source, destination, where_source, where_destination)
411
+ ensure_same_node(:lmove, [source, destination]) do |node|
412
+ node.lmove(source, destination, where_source, where_destination)
413
+ end
414
+ end
415
+
416
+ # Remove the first/last element in a list and append/prepend it
417
+ # to another list and return it, or block until one is available.
418
+ def blmove(source, destination, where_source, where_destination, timeout: 0)
419
+ ensure_same_node(:lmove, [source, destination]) do |node|
420
+ node.blmove(source, destination, where_source, where_destination, timeout: timeout)
421
+ end
422
+ end
423
+
366
424
  # Prepend one or more values to a list.
367
425
  def lpush(key, value)
368
426
  node_for(key).lpush(key, value)
@@ -383,14 +441,14 @@ class Redis
383
441
  node_for(key).rpushx(key, value)
384
442
  end
385
443
 
386
- # Remove and get the first element in a list.
387
- def lpop(key)
388
- node_for(key).lpop(key)
444
+ # Remove and get the first elements in a list.
445
+ def lpop(key, count = nil)
446
+ node_for(key).lpop(key, count)
389
447
  end
390
448
 
391
- # Remove and get the last element in a list.
392
- def rpop(key)
393
- node_for(key).rpop(key)
449
+ # Remove and get the last elements in a list.
450
+ def rpop(key, count = nil)
451
+ node_for(key).rpop(key, count)
394
452
  end
395
453
 
396
454
  # Remove the last element in a list, append it to another list and return
@@ -439,15 +497,9 @@ class Redis
439
497
 
440
498
  # Pop a value from a list, push it to another list and return it; or block
441
499
  # until one is available.
442
- def brpoplpush(source, destination, options = {})
443
- case options
444
- when Integer
445
- # Issue deprecation notice in obnoxious mode...
446
- options = { :timeout => options }
447
- end
448
-
500
+ def brpoplpush(source, destination, deprecated_timeout = 0, **options)
449
501
  ensure_same_node(:brpoplpush, [source, destination]) do |node|
450
- node.brpoplpush(source, destination, options)
502
+ node.brpoplpush(source, destination, deprecated_timeout, **options)
451
503
  end
452
504
  end
453
505
 
@@ -518,19 +570,24 @@ class Redis
518
570
  node_for(key).sismember(key, member)
519
571
  end
520
572
 
573
+ # Determine if multiple values are members of a set.
574
+ def smismember(key, *members)
575
+ node_for(key).smismember(key, *members)
576
+ end
577
+
521
578
  # Get all the members in a set.
522
579
  def smembers(key)
523
580
  node_for(key).smembers(key)
524
581
  end
525
582
 
526
583
  # Scan a set
527
- def sscan(key, cursor, options={})
528
- node_for(key).sscan(key, cursor, options)
584
+ def sscan(key, cursor, **options)
585
+ node_for(key).sscan(key, cursor, **options)
529
586
  end
530
587
 
531
588
  # Scan a set and return an enumerator
532
- def sscan_each(key, options={}, &block)
533
- node_for(key).sscan_each(key, options, &block)
589
+ def sscan_each(key, **options, &block)
590
+ node_for(key).sscan_each(key, **options, &block)
534
591
  end
535
592
 
536
593
  # Subtract multiple sets.
@@ -585,6 +642,7 @@ class Redis
585
642
  def zadd(key, *args)
586
643
  node_for(key).zadd(key, *args)
587
644
  end
645
+ ruby2_keywords(:zadd) if respond_to?(:ruby2_keywords, true)
588
646
 
589
647
  # Increment the score of a member in a sorted set.
590
648
  def zincrby(key, increment, member)
@@ -601,15 +659,33 @@ class Redis
601
659
  node_for(key).zscore(key, member)
602
660
  end
603
661
 
604
- # Return a range of members in a sorted set, by index.
605
- def zrange(key, start, stop, options = {})
606
- node_for(key).zrange(key, start, stop, options)
662
+ # Get one or more random members from a sorted set.
663
+ def zrandmember(key, count = nil, **options)
664
+ node_for(key).zrandmember(key, count, **options)
665
+ end
666
+
667
+ # Get the scores associated with the given members in a sorted set.
668
+ def zmscore(key, *members)
669
+ node_for(key).zmscore(key, *members)
670
+ end
671
+
672
+ # Return a range of members in a sorted set, by index, score or lexicographical ordering.
673
+ def zrange(key, start, stop, **options)
674
+ node_for(key).zrange(key, start, stop, **options)
675
+ end
676
+
677
+ # Select a range of members in a sorted set, by index, score or lexicographical ordering
678
+ # and store the resulting sorted set in a new key.
679
+ def zrangestore(dest_key, src_key, start, stop, **options)
680
+ ensure_same_node(:zrangestore, [dest_key, src_key]) do |node|
681
+ node.zrangestore(dest_key, src_key, start, stop, **options)
682
+ end
607
683
  end
608
684
 
609
685
  # Return a range of members in a sorted set, by index, with scores ordered
610
686
  # from high to low.
611
- def zrevrange(key, start, stop, options = {})
612
- node_for(key).zrevrange(key, start, stop, options)
687
+ def zrevrange(key, start, stop, **options)
688
+ node_for(key).zrevrange(key, start, stop, **options)
613
689
  end
614
690
 
615
691
  # Determine the index of a member in a sorted set.
@@ -629,14 +705,14 @@ class Redis
629
705
  end
630
706
 
631
707
  # Return a range of members in a sorted set, by score.
632
- def zrangebyscore(key, min, max, options = {})
633
- node_for(key).zrangebyscore(key, min, max, options)
708
+ def zrangebyscore(key, min, max, **options)
709
+ node_for(key).zrangebyscore(key, min, max, **options)
634
710
  end
635
711
 
636
712
  # Return a range of members in a sorted set, by score, with scores ordered
637
713
  # from high to low.
638
- def zrevrangebyscore(key, max, min, options = {})
639
- node_for(key).zrevrangebyscore(key, max, min, options)
714
+ def zrevrangebyscore(key, max, min, **options)
715
+ node_for(key).zrevrangebyscore(key, max, min, **options)
640
716
  end
641
717
 
642
718
  # Remove all members in a sorted set within the given scores.
@@ -649,18 +725,47 @@ class Redis
649
725
  node_for(key).zcount(key, min, max)
650
726
  end
651
727
 
728
+ # Get the intersection of multiple sorted sets
729
+ def zinter(*keys, **options)
730
+ ensure_same_node(:zinter, keys) do |node|
731
+ node.zinter(*keys, **options)
732
+ end
733
+ end
734
+
652
735
  # Intersect multiple sorted sets and store the resulting sorted set in a new
653
736
  # key.
654
- def zinterstore(destination, keys, options = {})
737
+ def zinterstore(destination, keys, **options)
655
738
  ensure_same_node(:zinterstore, [destination] + keys) do |node|
656
- node.zinterstore(destination, keys, options)
739
+ node.zinterstore(destination, keys, **options)
740
+ end
741
+ end
742
+
743
+ # Return the union of multiple sorted sets.
744
+ def zunion(*keys, **options)
745
+ ensure_same_node(:zunion, keys) do |node|
746
+ node.zunion(*keys, **options)
657
747
  end
658
748
  end
659
749
 
660
750
  # Add multiple sorted sets and store the resulting sorted set in a new key.
661
- def zunionstore(destination, keys, options = {})
751
+ def zunionstore(destination, keys, **options)
662
752
  ensure_same_node(:zunionstore, [destination] + keys) do |node|
663
- node.zunionstore(destination, keys, options)
753
+ node.zunionstore(destination, keys, **options)
754
+ end
755
+ end
756
+
757
+ # Return the difference between the first and all successive input sorted sets.
758
+ def zdiff(*keys, **options)
759
+ ensure_same_node(:zdiff, keys) do |node|
760
+ node.zdiff(*keys, **options)
761
+ end
762
+ end
763
+
764
+ # Compute the difference between the first and all successive input sorted sets
765
+ # and store the resulting sorted set in a new key.
766
+ def zdiffstore(destination, keys, **options)
767
+ ensure_same_node(:zdiffstore, [destination] + keys) do |node|
768
+ node.zdiffstore(destination, keys, **options)
664
769
  end
665
770
  end
666
771
 
@@ -669,9 +774,9 @@ class Redis
669
774
  node_for(key).hlen(key)
670
775
  end
671
776
 
672
- # Set the string value of a hash field.
673
- def hset(key, field, value)
674
- node_for(key).hset(key, field, value)
777
+ # Set multiple hash fields to multiple values.
778
+ def hset(key, *attrs)
779
+ node_for(key).hset(key, *attrs)
675
780
  end
676
781
 
677
782
  # Set the value of a hash field, only if the field does not exist.
@@ -702,6 +807,10 @@ class Redis
702
807
  Hash[*fields.zip(hmget(key, *fields)).flatten]
703
808
  end
704
809
 
810
+ def hrandfield(key, count = nil, **options)
811
+ node_for(key).hrandfield(key, count, **options)
812
+ end
813
+
705
814
  # Delete one or more hash fields.
706
815
  def hdel(key, *fields)
707
816
  node_for(key).hdel(key, *fields)
@@ -743,7 +852,7 @@ class Redis
743
852
  end
744
853
 
745
854
  def subscribed?
746
- !! @subscribed_node
855
+ !!@subscribed_node
747
856
  end
748
857
 
749
858
  # Listen for messages published to the given channels.
@@ -761,7 +870,8 @@ class Redis
761
870
 
762
871
  # Stop listening for messages posted to the given channels.
763
872
  def unsubscribe(*channels)
764
- raise RuntimeError, "Can't unsubscribe if not subscribed." unless subscribed?
873
+ raise "Can't unsubscribe if not subscribed." unless subscribed?
874
+
765
875
  @subscribed_node.unsubscribe(*channels)
766
876
  end
767
877
 
@@ -777,13 +887,26 @@ class Redis
777
887
  end
778
888
 
779
889
  # Watch the given keys to determine execution of the MULTI/EXEC block.
780
- def watch(*keys)
781
- raise CannotDistribute, :watch
890
+ def watch(*keys, &block)
891
+ ensure_same_node(:watch, keys) do |node|
892
+ @watch_key = key_tag(keys.first) || keys.first.to_s
893
+
894
+ begin
895
+ node.watch(*keys, &block)
896
+ rescue StandardError
897
+ @watch_key = nil
898
+ raise
899
+ end
900
+ end
782
901
  end
783
902
 
784
903
  # Forget about all watched keys.
785
904
  def unwatch
786
- raise CannotDistribute, :unwatch
905
+ raise CannotDistribute, :unwatch unless @watch_key
906
+
907
+ result = node_for(@watch_key).unwatch
908
+ @watch_key = nil
909
+ result
787
910
  end
788
911
 
789
912
  def pipelined
@@ -791,18 +914,30 @@ class Redis
791
914
  end
792
915
 
793
916
  # Mark the start of a transaction block.
794
- def multi
795
- raise CannotDistribute, :multi
917
+ def multi(&block)
918
+ raise CannotDistribute, :multi unless @watch_key
919
+
920
+ result = node_for(@watch_key).multi(&block)
921
+ @watch_key = nil if block_given?
922
+ result
796
923
  end
797
924
 
798
925
  # Execute all commands issued after MULTI.
799
926
  def exec
800
- raise CannotDistribute, :exec
927
+ raise CannotDistribute, :exec unless @watch_key
928
+
929
+ result = node_for(@watch_key).exec
930
+ @watch_key = nil
931
+ result
801
932
  end
802
933
 
803
934
  # Discard all commands issued after MULTI.
804
935
  def discard
805
- raise CannotDistribute, :discard
936
+ raise CannotDistribute, :discard unless @watch_key
937
+
938
+ result = node_for(@watch_key).discard
939
+ @watch_key = nil
940
+ result
806
941
  end
807
942
 
808
943
  # Control remote script registry.
@@ -861,7 +996,7 @@ class Redis
861
996
  self.class.new(@node_configs, @default_options)
862
997
  end
863
998
 
864
- protected
999
+ protected
865
1000
 
866
1001
  def on_each_node(command, *args)
867
1002
  nodes.map do |node|
data/lib/redis/errors.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Redis
3
4
  # Base error for all redis-rb errors.
4
5
  class BaseError < RuntimeError
@@ -44,6 +45,15 @@ class Redis
44
45
  end
45
46
 
46
47
  class Cluster
48
+ # Raised when client connected to redis as cluster mode
49
+ # and failed to fetch cluster state information by commands.
50
+ class InitialSetupError < BaseError
51
+ # @param errors [Array<Redis::BaseError>]
52
+ def initialize(errors)
53
+ super("Redis client could not fetch cluster information: #{errors.map(&:message).uniq.join(',')}")
54
+ end
55
+ end
56
+
47
57
  # Raised when client connected to redis as cluster mode
48
58
  # and some cluster subcommands were called.
49
59
  class OrchestrationCommandNotSupported < BaseError
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'zlib'
3
4
 
4
5
  class Redis
5
6
  class HashRing
6
-
7
7
  POINTS_PER_SERVER = 160 # this is the default in libmemcached
8
8
 
9
9
  attr_reader :ring, :sorted_keys, :replicas, :nodes
@@ -11,7 +11,7 @@ class Redis
11
11
  # nodes is a list of objects that have a proper to_s representation.
12
12
  # replicas indicates how many virtual points should be used pr. node,
13
13
  # replicas are required to improve the distribution.
14
- def initialize(nodes=[], replicas=POINTS_PER_SERVER)
14
+ def initialize(nodes = [], replicas = POINTS_PER_SERVER)
15
15
  @replicas = replicas
16
16
  @ring = {}
17
17
  @nodes = []
@@ -33,11 +33,11 @@ class Redis
33
33
  end
34
34
 
35
35
  def remove_node(node)
36
- @nodes.reject!{|n| n.id == node.id}
36
+ @nodes.reject! { |n| n.id == node.id }
37
37
  @replicas.times do |i|
38
38
  key = Zlib.crc32("#{node.id}:#{i}")
39
39
  @ring.delete(key)
40
- @sorted_keys.reject! {|k| k == key}
40
+ @sorted_keys.reject! { |k| k == key }
41
41
  end
42
42
  end
43
43
 
@@ -47,27 +47,29 @@ class Redis
47
47
  end
48
48
 
49
49
  def get_node_pos(key)
50
- return [nil,nil] if @ring.size == 0
50
+ return [nil, nil] if @ring.empty?
51
+
51
52
  crc = Zlib.crc32(key)
52
53
  idx = HashRing.binary_search(@sorted_keys, crc)
53
- return [@ring[@sorted_keys[idx]], idx]
54
+ [@ring[@sorted_keys[idx]], idx]
54
55
  end
55
56
 
56
57
  def iter_nodes(key)
57
- return [nil,nil] if @ring.size == 0
58
+ return [nil, nil] if @ring.empty?
59
+
58
60
  _, pos = get_node_pos(key)
59
61
  @ring.size.times do |n|
60
- yield @ring[@sorted_keys[(pos+n) % @ring.size]]
62
+ yield @ring[@sorted_keys[(pos + n) % @ring.size]]
61
63
  end
62
64
  end
63
65
 
64
66
  # Find the closest index in HashRing with value <= the given value
65
- def self.binary_search(ary, value, &block)
67
+ def self.binary_search(ary, value)
66
68
  upper = ary.size - 1
67
69
  lower = 0
68
70
  idx = 0
69
71
 
70
- while(lower <= upper) do
72
+ while lower <= upper
71
73
  idx = (lower + upper) / 2
72
74
  comp = ary[idx] <=> value
73
75
 
@@ -80,10 +82,8 @@ class Redis
80
82
  end
81
83
  end
82
84
 
83
- if upper < 0
84
- upper = ary.size - 1
85
- end
86
- return upper
85
+ upper = ary.size - 1 if upper < 0
86
+ upper
87
87
  end
88
88
  end
89
89
  end