diff --git a/lib/redis/distributed.rb b/lib/redis/distributed.rb index 4bda232a4..e37c27440 100644 --- a/lib/redis/distributed.rb +++ b/lib/redis/distributed.rb @@ -255,12 +255,16 @@ def setnx(key, value) end # Set multiple keys to multiple values. - def mset(*args) - raise CannotDistribute, :mset + def mset(*keys) + mapped_mset(Hash[keys.each_slice(2).to_a]) end def mapped_mset(hash) - raise CannotDistribute, :mapped_mset + keys_per_node = hash.group_by { |key, value| node_for(key) } + + keys_per_node.map do |node, mset| + node.mapped_mset(Hash[mset]) + end end # Set multiple keys to multiple values, only if none of the keys exist. @@ -279,11 +283,18 @@ def get(key) # Get the values of all the given keys. def mget(*keys) - raise CannotDistribute, :mget + result = mapped_mget(*keys) + keys.map { |key| result[key] } end - def mapped_mget(*keys) - raise CannotDistribute, :mapped_mget + def mapped_mget(*mget_keys) + keys_per_node = mget_keys.group_by { |key| node_for(key) } + + result = keys_per_node.inject({}) do |accum, (node, keys)| + values = node.mget(*keys) + accum.merge!(Hash[keys.zip(values)]) + end + result 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..f25364159 100644 --- a/test/distributed_commands_on_strings_test.rb +++ b/test/distributed_commands_on_strings_test.rb @@ -9,27 +9,41 @@ 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 - assert_raise Redis::Distributed::CannotDistribute do - r.mset(:foo, "s1", :bar, "s2") - end + r.mset(:foo, "s1", :bar, "s2") + + assert_equal "s1", r.get("foo") + assert_equal "s2", r.get("bar") end def test_mset_mapped - assert_raise Redis::Distributed::CannotDistribute do - r.mapped_mset(:foo => "s1", :bar => "s2") - end + r.mapped_mset(:foo => "s1", :bar => "s2") + + assert_equal "s1", r.get("foo") + assert_equal "s2", r.get("bar") end def test_msetnx