From 2e4603998c22e64565c0d48d8c6a76b7c0510179 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Wed, 12 Apr 2017 18:40:10 -0700 Subject: [PATCH] Distributed: support mget and mapped_mget Map the keys to their nodes, mget them on each node, and stitch the results together. --- lib/redis/distributed.rb | 9 +++++--- test/distributed_commands_on_strings_test.rb | 24 +++++++++++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/redis/distributed.rb b/lib/redis/distributed.rb index df4914831..648aa769b 100644 --- a/lib/redis/distributed.rb +++ b/lib/redis/distributed.rb @@ -277,13 +277,16 @@ def get(key) node_for(key).get(key) end - # Get the values of all the given keys. + # Get the values of all the given keys as an Array. def mget(*keys) - raise CannotDistribute, :mget + mapped_mget(*keys).values_at(*keys) end + # Get the values of all the given keys as a Hash. def mapped_mget(*keys) - raise CannotDistribute, :mapped_mget + keys.group_by { |k| node_for k }.inject({}) do |results, (node, subkeys)| + results.merge! node.mapped_mget(*subkeys) + end end # Overwrite part of a string at key starting at the specified offset. diff --git a/test/distributed_commands_on_strings_test.rb b/test/distributed_commands_on_strings_test.rb index ad83c12e5..e8a7f5456 100644 --- a/test/distributed_commands_on_strings_test.rb +++ b/test/distributed_commands_on_strings_test.rb @@ -9,15 +9,27 @@ class TestDistributedCommandsOnStrings < Test::Unit::TestCase include Lint::Strings def test_mget - assert_raise Redis::Distributed::CannotDistribute do - r.mget("foo", "bar") - end + r.set("foo", "s1") + r.set("bar", "s2") + + assert_equal ["s1", "s2"] , r.mget("foo", "bar") + assert_equal ["s1", "s2", nil], r.mget("foo", "bar", "baz") end def test_mget_mapped - assert_raise Redis::Distributed::CannotDistribute do - r.mapped_mget("foo", "bar") - end + r.set("foo", "s1") + r.set("bar", "s2") + + response = r.mapped_mget("foo", "bar") + + assert_equal "s1", response["foo"] + assert_equal "s2", response["bar"] + + response = r.mapped_mget("foo", "bar", "baz") + + assert_equal "s1", response["foo"] + assert_equal "s2", response["bar"] + assert_equal nil , response["baz"] end def test_mset