Sfoglia il codice sorgente

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 anni fa
parent
commit
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();