소스 검색

Some commands accepting multiple keys can be hashed if all the keys return the same hash (key tags).

List of the commands affected by this change (based on Redis 2.2):
    MSET, MGET, DEL, BLPOP, BRPOP, RPOPLPUSH, BRPOPLPUSH, SINTER, SINTERSTORE,
    SUNION, SUNIONSTORE, SDIFF, SDIFFSTORE, ZINTERSTORE, ZUNIONSTORE.
Daniele Alessandri 14 년 전
부모
커밋
c4064e5801

+ 15 - 0
lib/Predis/Commands/Command.php

@@ -23,6 +23,21 @@ abstract class Command implements ICommand {
         return $key;
     }
 
+    protected function checkSameHashForKeys(Array $keys) {
+        if (($count = count($keys)) === 0) {
+            return false;
+        }
+        $currentKey = $this->getHashablePart($keys[0]);
+        for ($i = 1; $i < $count; $i++) {
+            $nextKey = $this->getHashablePart($keys[$i]);
+            if ($currentKey !== $nextKey) {
+                return false;
+            }
+            $currentKey = $nextKey;
+        }
+        return true;
+    }
+
     public function getHash(IDistributionStrategy $distributor) {
         if (isset($this->_hash)) {
             return $this->_hash;

+ 7 - 0
lib/Predis/Commands/Delete.php

@@ -5,6 +5,13 @@ namespace Predis\Commands;
 use Predis\Utils;
 
 class Delete extends Command {
+    protected function canBeHashed() {
+        $args = $this->getArguments();
+        if (count($args) === 1) {
+            return true;
+        }
+        return $this->checkSameHashForKeys($args);
+    }
     public function getId() { return 'DEL'; }
     public function filterArguments(Array $arguments) {
         return Utils::filterArrayArguments($arguments);

+ 3 - 1
lib/Predis/Commands/GetMultiple.php

@@ -5,7 +5,9 @@ namespace Predis\Commands;
 use Predis\Utils;
 
 class GetMultiple extends Command {
-    protected function canBeHashed() { return false; }
+    protected function canBeHashed() {
+        return $this->checkSameHashForKeys($this->getArguments());
+    }
     public function getId() { return 'MGET'; }
     public function filterArguments(Array $arguments) {
         return Utils::filterArrayArguments($arguments);

+ 5 - 0
lib/Predis/Commands/ListPopFirstBlocking.php

@@ -3,5 +3,10 @@
 namespace Predis\Commands;
 
 class ListPopFirstBlocking extends Command {
+    protected function canBeHashed() {
+        return $this->checkSameHashForKeys(
+            array_slice(($args = $this->getArguments()), 0, count($args) - 1)
+        );
+    }
     public function getId() { return 'BLPOP'; }
 }

+ 1 - 1
lib/Predis/Commands/ListPopLastBlocking.php

@@ -2,6 +2,6 @@
 
 namespace Predis\Commands;
 
-class ListPopLastBlocking extends Command {
+class ListPopLastBlocking extends ListPopFirstBlocking {
     public function getId() { return 'BRPOP'; }
 }

+ 3 - 0
lib/Predis/Commands/ListPopLastPushHead.php

@@ -3,5 +3,8 @@
 namespace Predis\Commands;
 
 class ListPopLastPushHead extends Command {
+    protected function canBeHashed() {
+        return $this->checkSameHashForKeys($this->getArguments());
+    }
     public function getId() { return 'RPOPLPUSH'; }
 }

+ 5 - 0
lib/Predis/Commands/ListPopLastPushHeadBlocking.php

@@ -3,5 +3,10 @@
 namespace Predis\Commands;
 
 class ListPopLastPushHeadBlocking extends Command {
+    protected function canBeHashed() {
+        return $this->checkSameHashForKeys(
+            array_slice($args = $this->getArguments(), 0, count($args) - 1)
+        );
+    }
     public function getId() { return 'BRPOPLPUSH'; }
 }

+ 3 - 1
lib/Predis/Commands/SetIntersection.php

@@ -5,7 +5,9 @@ namespace Predis\Commands;
 use Predis\Utils;
 
 class SetIntersection extends Command {
-    protected function canBeHashed() { return false; }
+    protected function canBeHashed() {
+        return $this->checkSameHashForKeys($this->getArguments());
+    }
     public function getId() { return 'SINTER'; }
     public function filterArguments(Array $arguments) {
         return Utils::filterArrayArguments($arguments);

+ 3 - 1
lib/Predis/Commands/SetIntersectionStore.php

@@ -5,7 +5,9 @@ namespace Predis\Commands;
 use Predis\Utils;
 
 class SetIntersectionStore extends Command {
-    protected function canBeHashed() { return false; }
+    protected function canBeHashed() {
+        return $this->checkSameHashForKeys($this->getArguments());
+    }
     public function getId() { return 'SINTERSTORE'; }
     public function filterArguments(Array $arguments) {
         return Utils::filterArrayArguments($arguments);

+ 8 - 1
lib/Predis/Commands/SetMultiple.php

@@ -3,7 +3,14 @@
 namespace Predis\Commands;
 
 class SetMultiple extends Command {
-    protected function canBeHashed() { return false; }
+    protected function canBeHashed() {
+        $args = $this->getArguments();
+        $keys = array();
+        for ($i = 0; $i < count($args); $i += 2) {
+            $keys[] = $args[$i];
+        }
+        return $this->checkSameHashForKeys($keys);
+    }
     public function getId() { return 'MSET'; }
     public function filterArguments(Array $arguments) {
         if (count($arguments) === 1 && is_array($arguments[0])) {

+ 0 - 1
lib/Predis/Commands/ZSetIntersectionStore.php

@@ -3,6 +3,5 @@
 namespace Predis\Commands;
 
 class ZSetIntersectionStore extends ZSetUnionStore {
-    protected function canBeHashed() { return false; }
     public function getId() { return 'ZINTERSTORE'; }
 }

+ 6 - 1
lib/Predis/Commands/ZSetUnionStore.php

@@ -3,7 +3,12 @@
 namespace Predis\Commands;
 
 class ZSetUnionStore extends Command {
-    protected function canBeHashed() { return false; }
+    protected function canBeHashed() {
+        $args = $this->getArguments();
+        return $this->checkSameHashForKeys(
+            array_merge(array($args[0]), array_slice($args, 2, $args[1]))
+        );
+    }
     public function getId() { return 'ZUNIONSTORE'; }
     public function filterArguments(Array $arguments) {
         $options = array();