From 930a1096e1750c4346d7015edda49cbcfb91b71b Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Wed, 23 Mar 2011 22:58:49 +0100 Subject: [PATCH 1/4] Refactor the key hashing logic for Redis commands. --- lib/Predis/Commands/Command.php | 35 +++++++++++++----------- lib/Predis/Network/ConnectionCluster.php | 5 ++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/Predis/Commands/Command.php b/lib/Predis/Commands/Command.php index 31fa1045..c73a12cc 100644 --- a/lib/Predis/Commands/Command.php +++ b/lib/Predis/Commands/Command.php @@ -12,27 +12,30 @@ abstract class Command implements ICommand { return true; } + protected function getHashablePart($key) { + $start = strpos($key, '{'); + if ($start !== false) { + $end = strpos($key, '}', $start); + if ($end !== false) { + $key = substr($key, ++$start, $end - $start); + } + } + return $key; + } + public function getHash(IDistributionStrategy $distributor) { if (isset($this->_hash)) { return $this->_hash; } - if (isset($this->_arguments[0])) { - // TODO: should we throw an exception if the command does not - // support sharding? - $key = $this->_arguments[0]; - - $start = strpos($key, '{'); - if ($start !== false) { - $end = strpos($key, '}', $start); - if ($end !== false) { - $key = substr($key, ++$start, $end - $start); - } - } - - $this->_hash = $distributor->generateKey($key); - return $this->_hash; + if ($this->canBeHashed() === false) { + return null; } - return null; + if (!isset($this->_arguments[0])) { + return null; + } + $key = $this->getHashablePart($this->_arguments[0]); + $this->_hash = $distributor->generateKey($key); + return $this->_hash; } protected function filterArguments(Array $arguments) { diff --git a/lib/Predis/Network/ConnectionCluster.php b/lib/Predis/Network/ConnectionCluster.php index 3126847f..4cb25722 100644 --- a/lib/Predis/Network/ConnectionCluster.php +++ b/lib/Predis/Network/ConnectionCluster.php @@ -47,12 +47,13 @@ class ConnectionCluster implements IConnectionCluster, \IteratorAggregate { } public function getConnection(ICommand $command) { - if ($command->canBeHashed() === false) { + $cmdHash = $command->getHash($this->_distributor); + if (isset($cmdHash) === false) { throw new ClientException( sprintf("Cannot send '%s' commands to a cluster of connections", $command->getId()) ); } - return $this->_distributor->get($command->getHash($this->_distributor)); + return $this->_distributor->get($cmdHash); } public function getConnectionById($id = null) { From 4e0e1908cdd771e15dccedabfe293063a6485fa9 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Wed, 23 Mar 2011 23:27:05 +0100 Subject: [PATCH 2/4] Minor speed optimizations. --- lib/Predis/Commands/Command.php | 2 +- lib/Predis/Network/ConnectionCluster.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Predis/Commands/Command.php b/lib/Predis/Commands/Command.php index c73a12cc..b5407370 100644 --- a/lib/Predis/Commands/Command.php +++ b/lib/Predis/Commands/Command.php @@ -27,7 +27,7 @@ abstract class Command implements ICommand { if (isset($this->_hash)) { return $this->_hash; } - if ($this->canBeHashed() === false) { + if (!$this->canBeHashed()) { return null; } if (!isset($this->_arguments[0])) { diff --git a/lib/Predis/Network/ConnectionCluster.php b/lib/Predis/Network/ConnectionCluster.php index 4cb25722..91167632 100644 --- a/lib/Predis/Network/ConnectionCluster.php +++ b/lib/Predis/Network/ConnectionCluster.php @@ -48,12 +48,12 @@ class ConnectionCluster implements IConnectionCluster, \IteratorAggregate { public function getConnection(ICommand $command) { $cmdHash = $command->getHash($this->_distributor); - if (isset($cmdHash) === false) { - throw new ClientException( - sprintf("Cannot send '%s' commands to a cluster of connections", $command->getId()) - ); + if (isset($cmdHash)) { + return $this->_distributor->get($cmdHash); } - return $this->_distributor->get($cmdHash); + throw new ClientException( + sprintf("Cannot send '%s' commands to a cluster of connections", $command->getId()) + ); } public function getConnectionById($id = null) { From b84c84007fd0136ca458acb4d1346f3820a1bc20 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Thu, 24 Mar 2011 00:43:02 +0100 Subject: [PATCH 3/4] Remove Predis\ICommand::canBeHashed() as a public method required for command classes and reuse it internally to Predis\Command. --- lib/Predis/Commands/Auth.php | 2 +- .../BackgroundRewriteAppendOnlyFile.php | 2 +- lib/Predis/Commands/BackgroundSave.php | 2 +- lib/Predis/Commands/Command.php | 17 +++++++---------- lib/Predis/Commands/Config.php | 2 +- lib/Predis/Commands/DatabaseSize.php | 2 +- lib/Predis/Commands/Discard.php | 2 +- lib/Predis/Commands/DoEcho.php | 2 +- lib/Predis/Commands/Exec.php | 2 +- lib/Predis/Commands/FlushAll.php | 2 +- lib/Predis/Commands/FlushDatabase.php | 2 +- lib/Predis/Commands/GetMultiple.php | 2 +- lib/Predis/Commands/ICommand.php | 1 - lib/Predis/Commands/Info.php | 2 +- lib/Predis/Commands/InfoV24x.php | 1 - lib/Predis/Commands/Keys.php | 2 +- lib/Predis/Commands/LastSave.php | 2 +- lib/Predis/Commands/MoveKey.php | 2 +- lib/Predis/Commands/Multi.php | 2 +- lib/Predis/Commands/Ping.php | 2 +- lib/Predis/Commands/Publish.php | 2 +- lib/Predis/Commands/Quit.php | 2 +- lib/Predis/Commands/RandomKey.php | 2 +- lib/Predis/Commands/Rename.php | 2 +- lib/Predis/Commands/RenamePreserve.php | 2 +- lib/Predis/Commands/Save.php | 2 +- lib/Predis/Commands/SelectDatabase.php | 2 +- lib/Predis/Commands/SetIntersection.php | 1 + lib/Predis/Commands/SetIntersectionStore.php | 1 + lib/Predis/Commands/SetMove.php | 2 +- lib/Predis/Commands/SetMultiple.php | 2 +- lib/Predis/Commands/SetMultiplePreserve.php | 1 - lib/Predis/Commands/Shutdown.php | 2 +- lib/Predis/Commands/SlaveOf.php | 2 +- lib/Predis/Commands/Subscribe.php | 2 +- lib/Predis/Commands/SubscribeByPattern.php | 2 +- lib/Predis/Commands/Unsubscribe.php | 2 +- lib/Predis/Commands/UnsubscribeByPattern.php | 2 +- lib/Predis/Commands/Unwatch.php | 2 +- lib/Predis/Commands/Watch.php | 2 +- lib/Predis/Commands/ZSetIntersectionStore.php | 1 + lib/Predis/Commands/ZSetUnionStore.php | 1 + 42 files changed, 45 insertions(+), 47 deletions(-) diff --git a/lib/Predis/Commands/Auth.php b/lib/Predis/Commands/Auth.php index 9c09580b..966382d2 100644 --- a/lib/Predis/Commands/Auth.php +++ b/lib/Predis/Commands/Auth.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Auth extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'AUTH'; } } diff --git a/lib/Predis/Commands/BackgroundRewriteAppendOnlyFile.php b/lib/Predis/Commands/BackgroundRewriteAppendOnlyFile.php index 55ca89e2..61c10ad0 100644 --- a/lib/Predis/Commands/BackgroundRewriteAppendOnlyFile.php +++ b/lib/Predis/Commands/BackgroundRewriteAppendOnlyFile.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class BackgroundRewriteAppendOnlyFile extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'BGREWRITEAOF'; } public function parseResponse($data) { return $data == 'Background append only file rewriting started'; diff --git a/lib/Predis/Commands/BackgroundSave.php b/lib/Predis/Commands/BackgroundSave.php index c166d4fc..c65eb9f5 100644 --- a/lib/Predis/Commands/BackgroundSave.php +++ b/lib/Predis/Commands/BackgroundSave.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class BackgroundSave extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'BGSAVE'; } public function parseResponse($data) { if ($data == 'Background saving started') { diff --git a/lib/Predis/Commands/Command.php b/lib/Predis/Commands/Command.php index b5407370..ce904b70 100644 --- a/lib/Predis/Commands/Command.php +++ b/lib/Predis/Commands/Command.php @@ -8,8 +8,8 @@ abstract class Command implements ICommand { private $_hash; private $_arguments = array(); - public function canBeHashed() { - return true; + protected function canBeHashed() { + return isset($this->_arguments[0]); } protected function getHashablePart($key) { @@ -27,15 +27,12 @@ abstract class Command implements ICommand { if (isset($this->_hash)) { return $this->_hash; } - if (!$this->canBeHashed()) { - return null; + if ($this->canBeHashed()) { + $key = $this->getHashablePart($this->_arguments[0]); + $this->_hash = $distributor->generateKey($key); + return $this->_hash; } - if (!isset($this->_arguments[0])) { - return null; - } - $key = $this->getHashablePart($this->_arguments[0]); - $this->_hash = $distributor->generateKey($key); - return $this->_hash; + return null; } protected function filterArguments(Array $arguments) { diff --git a/lib/Predis/Commands/Config.php b/lib/Predis/Commands/Config.php index 122d4fdf..2dde0c25 100644 --- a/lib/Predis/Commands/Config.php +++ b/lib/Predis/Commands/Config.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Config extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'CONFIG'; } } diff --git a/lib/Predis/Commands/DatabaseSize.php b/lib/Predis/Commands/DatabaseSize.php index 7a1e3aaf..b2c404c6 100644 --- a/lib/Predis/Commands/DatabaseSize.php +++ b/lib/Predis/Commands/DatabaseSize.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class DatabaseSize extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'DBSIZE'; } } diff --git a/lib/Predis/Commands/Discard.php b/lib/Predis/Commands/Discard.php index f73312ab..d0177cfd 100644 --- a/lib/Predis/Commands/Discard.php +++ b/lib/Predis/Commands/Discard.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Discard extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'DISCARD'; } } diff --git a/lib/Predis/Commands/DoEcho.php b/lib/Predis/Commands/DoEcho.php index a929d9c7..5caa4ec8 100644 --- a/lib/Predis/Commands/DoEcho.php +++ b/lib/Predis/Commands/DoEcho.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class DoEcho extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'ECHO'; } } diff --git a/lib/Predis/Commands/Exec.php b/lib/Predis/Commands/Exec.php index 7bef7edd..99e6a851 100644 --- a/lib/Predis/Commands/Exec.php +++ b/lib/Predis/Commands/Exec.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Exec extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'EXEC'; } } diff --git a/lib/Predis/Commands/FlushAll.php b/lib/Predis/Commands/FlushAll.php index c9a97317..1eb6bd61 100644 --- a/lib/Predis/Commands/FlushAll.php +++ b/lib/Predis/Commands/FlushAll.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class FlushAll extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'FLUSHALL'; } } diff --git a/lib/Predis/Commands/FlushDatabase.php b/lib/Predis/Commands/FlushDatabase.php index 084d0647..448efb08 100644 --- a/lib/Predis/Commands/FlushDatabase.php +++ b/lib/Predis/Commands/FlushDatabase.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class FlushDatabase extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'FLUSHDB'; } } diff --git a/lib/Predis/Commands/GetMultiple.php b/lib/Predis/Commands/GetMultiple.php index 212b5ab3..8a557ffc 100644 --- a/lib/Predis/Commands/GetMultiple.php +++ b/lib/Predis/Commands/GetMultiple.php @@ -5,7 +5,7 @@ namespace Predis\Commands; use Predis\Utils; class GetMultiple extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'MGET'; } public function filterArguments(Array $arguments) { return Utils::filterArrayArguments($arguments); diff --git a/lib/Predis/Commands/ICommand.php b/lib/Predis/Commands/ICommand.php index 37440a1f..bdd6b835 100644 --- a/lib/Predis/Commands/ICommand.php +++ b/lib/Predis/Commands/ICommand.php @@ -6,7 +6,6 @@ use Predis\Distribution\IDistributionStrategy; interface ICommand { public function getId(); - public function canBeHashed(); public function getHash(IDistributionStrategy $distributor); public function setArgumentsArray(Array $arguments); public function getArguments(); diff --git a/lib/Predis/Commands/Info.php b/lib/Predis/Commands/Info.php index a495d8cc..a300e5a3 100644 --- a/lib/Predis/Commands/Info.php +++ b/lib/Predis/Commands/Info.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class Info extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'INFO'; } public function parseResponse($data) { $info = array(); diff --git a/lib/Predis/Commands/InfoV24x.php b/lib/Predis/Commands/InfoV24x.php index a9eb2342..f27645e1 100644 --- a/lib/Predis/Commands/InfoV24x.php +++ b/lib/Predis/Commands/InfoV24x.php @@ -3,7 +3,6 @@ namespace Predis\Commands; class InfoV24x extends Info { - public function canBeHashed() { return false; } public function parseResponse($data) { $info = array(); $current = null; diff --git a/lib/Predis/Commands/Keys.php b/lib/Predis/Commands/Keys.php index d7c8e5f3..339ba662 100644 --- a/lib/Predis/Commands/Keys.php +++ b/lib/Predis/Commands/Keys.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Keys extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'KEYS'; } } diff --git a/lib/Predis/Commands/LastSave.php b/lib/Predis/Commands/LastSave.php index 46e7fe32..4f8a6638 100644 --- a/lib/Predis/Commands/LastSave.php +++ b/lib/Predis/Commands/LastSave.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class LastSave extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'LASTSAVE'; } } diff --git a/lib/Predis/Commands/MoveKey.php b/lib/Predis/Commands/MoveKey.php index 833dd3de..b343dbc5 100644 --- a/lib/Predis/Commands/MoveKey.php +++ b/lib/Predis/Commands/MoveKey.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class MoveKey extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'MOVE'; } public function parseResponse($data) { return (bool) $data; } } diff --git a/lib/Predis/Commands/Multi.php b/lib/Predis/Commands/Multi.php index 9e8d1fb5..4a4383e5 100644 --- a/lib/Predis/Commands/Multi.php +++ b/lib/Predis/Commands/Multi.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Multi extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'MULTI'; } } diff --git a/lib/Predis/Commands/Ping.php b/lib/Predis/Commands/Ping.php index 0810a012..e6efd65e 100644 --- a/lib/Predis/Commands/Ping.php +++ b/lib/Predis/Commands/Ping.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class Ping extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'PING'; } public function parseResponse($data) { return $data === 'PONG' ? true : false; diff --git a/lib/Predis/Commands/Publish.php b/lib/Predis/Commands/Publish.php index 5e1a437b..74f35639 100644 --- a/lib/Predis/Commands/Publish.php +++ b/lib/Predis/Commands/Publish.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Publish extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'PUBLISH'; } } diff --git a/lib/Predis/Commands/Quit.php b/lib/Predis/Commands/Quit.php index cd86fa57..a53faa9f 100644 --- a/lib/Predis/Commands/Quit.php +++ b/lib/Predis/Commands/Quit.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Quit extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'QUIT'; } } diff --git a/lib/Predis/Commands/RandomKey.php b/lib/Predis/Commands/RandomKey.php index 23ef952f..a8ec603c 100644 --- a/lib/Predis/Commands/RandomKey.php +++ b/lib/Predis/Commands/RandomKey.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class RandomKey extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'RANDOMKEY'; } public function parseResponse($data) { return $data !== '' ? $data : null; } } diff --git a/lib/Predis/Commands/Rename.php b/lib/Predis/Commands/Rename.php index 1cd8ea03..f6a973cd 100644 --- a/lib/Predis/Commands/Rename.php +++ b/lib/Predis/Commands/Rename.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Rename extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'RENAME'; } } diff --git a/lib/Predis/Commands/RenamePreserve.php b/lib/Predis/Commands/RenamePreserve.php index e6684bd8..f88e4190 100644 --- a/lib/Predis/Commands/RenamePreserve.php +++ b/lib/Predis/Commands/RenamePreserve.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class RenamePreserve extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'RENAMENX'; } public function parseResponse($data) { return (bool) $data; } } diff --git a/lib/Predis/Commands/Save.php b/lib/Predis/Commands/Save.php index b10c1ebe..6d8f675f 100644 --- a/lib/Predis/Commands/Save.php +++ b/lib/Predis/Commands/Save.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Save extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'SAVE'; } } diff --git a/lib/Predis/Commands/SelectDatabase.php b/lib/Predis/Commands/SelectDatabase.php index 851c4433..fa3b6785 100644 --- a/lib/Predis/Commands/SelectDatabase.php +++ b/lib/Predis/Commands/SelectDatabase.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class SelectDatabase extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'SELECT'; } } diff --git a/lib/Predis/Commands/SetIntersection.php b/lib/Predis/Commands/SetIntersection.php index 6cd7740a..e2484665 100644 --- a/lib/Predis/Commands/SetIntersection.php +++ b/lib/Predis/Commands/SetIntersection.php @@ -5,6 +5,7 @@ namespace Predis\Commands; use Predis\Utils; class SetIntersection extends Command { + protected function canBeHashed() { return false; } public function getId() { return 'SINTER'; } public function filterArguments(Array $arguments) { return Utils::filterArrayArguments($arguments); diff --git a/lib/Predis/Commands/SetIntersectionStore.php b/lib/Predis/Commands/SetIntersectionStore.php index dc0087a6..78ea568c 100644 --- a/lib/Predis/Commands/SetIntersectionStore.php +++ b/lib/Predis/Commands/SetIntersectionStore.php @@ -5,6 +5,7 @@ namespace Predis\Commands; use Predis\Utils; class SetIntersectionStore extends Command { + protected function canBeHashed() { return false; } public function getId() { return 'SINTERSTORE'; } public function filterArguments(Array $arguments) { return Utils::filterArrayArguments($arguments); diff --git a/lib/Predis/Commands/SetMove.php b/lib/Predis/Commands/SetMove.php index f5d52d81..e5ed7748 100644 --- a/lib/Predis/Commands/SetMove.php +++ b/lib/Predis/Commands/SetMove.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class SetMove extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'SMOVE'; } public function parseResponse($data) { return (bool) $data; } } diff --git a/lib/Predis/Commands/SetMultiple.php b/lib/Predis/Commands/SetMultiple.php index 8a102d81..f26977ff 100644 --- a/lib/Predis/Commands/SetMultiple.php +++ b/lib/Predis/Commands/SetMultiple.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class SetMultiple extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'MSET'; } public function filterArguments(Array $arguments) { if (count($arguments) === 1 && is_array($arguments[0])) { diff --git a/lib/Predis/Commands/SetMultiplePreserve.php b/lib/Predis/Commands/SetMultiplePreserve.php index 5f5850df..d2d93677 100644 --- a/lib/Predis/Commands/SetMultiplePreserve.php +++ b/lib/Predis/Commands/SetMultiplePreserve.php @@ -3,7 +3,6 @@ namespace Predis\Commands; class SetMultiplePreserve extends SetMultiple { - public function canBeHashed() { return false; } public function getId() { return 'MSETNX'; } public function parseResponse($data) { return (bool) $data; } } diff --git a/lib/Predis/Commands/Shutdown.php b/lib/Predis/Commands/Shutdown.php index e300357b..33e48807 100644 --- a/lib/Predis/Commands/Shutdown.php +++ b/lib/Predis/Commands/Shutdown.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Shutdown extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'SHUTDOWN'; } } diff --git a/lib/Predis/Commands/SlaveOf.php b/lib/Predis/Commands/SlaveOf.php index 92697d77..2067baac 100644 --- a/lib/Predis/Commands/SlaveOf.php +++ b/lib/Predis/Commands/SlaveOf.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class SlaveOf extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'SLAVEOF'; } public function filterArguments(Array $arguments) { if (count($arguments) === 0 || $arguments[0] === 'NO ONE') { diff --git a/lib/Predis/Commands/Subscribe.php b/lib/Predis/Commands/Subscribe.php index 8122422a..0919cd4a 100644 --- a/lib/Predis/Commands/Subscribe.php +++ b/lib/Predis/Commands/Subscribe.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Subscribe extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'SUBSCRIBE'; } } diff --git a/lib/Predis/Commands/SubscribeByPattern.php b/lib/Predis/Commands/SubscribeByPattern.php index c1f17185..ac2fdf07 100644 --- a/lib/Predis/Commands/SubscribeByPattern.php +++ b/lib/Predis/Commands/SubscribeByPattern.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class SubscribeByPattern extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'PSUBSCRIBE'; } } diff --git a/lib/Predis/Commands/Unsubscribe.php b/lib/Predis/Commands/Unsubscribe.php index 7ee9ef40..ac854212 100644 --- a/lib/Predis/Commands/Unsubscribe.php +++ b/lib/Predis/Commands/Unsubscribe.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class Unsubscribe extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'UNSUBSCRIBE'; } } diff --git a/lib/Predis/Commands/UnsubscribeByPattern.php b/lib/Predis/Commands/UnsubscribeByPattern.php index a3211b79..bc02da47 100644 --- a/lib/Predis/Commands/UnsubscribeByPattern.php +++ b/lib/Predis/Commands/UnsubscribeByPattern.php @@ -3,6 +3,6 @@ namespace Predis\Commands; class UnsubscribeByPattern extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'PUNSUBSCRIBE'; } } diff --git a/lib/Predis/Commands/Unwatch.php b/lib/Predis/Commands/Unwatch.php index 1cdeb164..a476a169 100644 --- a/lib/Predis/Commands/Unwatch.php +++ b/lib/Predis/Commands/Unwatch.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class Unwatch extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'UNWATCH'; } public function parseResponse($data) { return (bool) $data; } } diff --git a/lib/Predis/Commands/Watch.php b/lib/Predis/Commands/Watch.php index cc629ea0..a8c57c4c 100644 --- a/lib/Predis/Commands/Watch.php +++ b/lib/Predis/Commands/Watch.php @@ -3,7 +3,7 @@ namespace Predis\Commands; class Watch extends Command { - public function canBeHashed() { return false; } + protected function canBeHashed() { return false; } public function getId() { return 'WATCH'; } public function filterArguments(Array $arguments) { if (isset($arguments[0]) && is_array($arguments[0])) { diff --git a/lib/Predis/Commands/ZSetIntersectionStore.php b/lib/Predis/Commands/ZSetIntersectionStore.php index 11bc9e91..8e8b6a09 100644 --- a/lib/Predis/Commands/ZSetIntersectionStore.php +++ b/lib/Predis/Commands/ZSetIntersectionStore.php @@ -3,5 +3,6 @@ namespace Predis\Commands; class ZSetIntersectionStore extends ZSetUnionStore { + protected function canBeHashed() { return false; } public function getId() { return 'ZINTERSTORE'; } } diff --git a/lib/Predis/Commands/ZSetUnionStore.php b/lib/Predis/Commands/ZSetUnionStore.php index 790b79e1..aed60729 100644 --- a/lib/Predis/Commands/ZSetUnionStore.php +++ b/lib/Predis/Commands/ZSetUnionStore.php @@ -3,6 +3,7 @@ namespace Predis\Commands; class ZSetUnionStore extends Command { + protected function canBeHashed() { return false; } public function getId() { return 'ZUNIONSTORE'; } public function filterArguments(Array $arguments) { $options = array(); From c4064e5801026ab6ad5b10e1cb93a281f268f4ed Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Sun, 27 Mar 2011 12:12:51 +0200 Subject: [PATCH 4/4] 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. --- lib/Predis/Commands/Command.php | 15 +++++++++++++++ lib/Predis/Commands/Delete.php | 7 +++++++ lib/Predis/Commands/GetMultiple.php | 4 +++- lib/Predis/Commands/ListPopFirstBlocking.php | 5 +++++ lib/Predis/Commands/ListPopLastBlocking.php | 2 +- lib/Predis/Commands/ListPopLastPushHead.php | 3 +++ .../Commands/ListPopLastPushHeadBlocking.php | 5 +++++ lib/Predis/Commands/SetIntersection.php | 4 +++- lib/Predis/Commands/SetIntersectionStore.php | 4 +++- lib/Predis/Commands/SetMultiple.php | 9 ++++++++- lib/Predis/Commands/ZSetIntersectionStore.php | 1 - lib/Predis/Commands/ZSetUnionStore.php | 7 ++++++- 12 files changed, 59 insertions(+), 7 deletions(-) diff --git a/lib/Predis/Commands/Command.php b/lib/Predis/Commands/Command.php index ce904b70..5c607280 100644 --- a/lib/Predis/Commands/Command.php +++ b/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; diff --git a/lib/Predis/Commands/Delete.php b/lib/Predis/Commands/Delete.php index ba5cd5eb..a844acdf 100644 --- a/lib/Predis/Commands/Delete.php +++ b/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); diff --git a/lib/Predis/Commands/GetMultiple.php b/lib/Predis/Commands/GetMultiple.php index 8a557ffc..1c652c13 100644 --- a/lib/Predis/Commands/GetMultiple.php +++ b/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); diff --git a/lib/Predis/Commands/ListPopFirstBlocking.php b/lib/Predis/Commands/ListPopFirstBlocking.php index 097026ed..ee48a269 100644 --- a/lib/Predis/Commands/ListPopFirstBlocking.php +++ b/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'; } } diff --git a/lib/Predis/Commands/ListPopLastBlocking.php b/lib/Predis/Commands/ListPopLastBlocking.php index 11687c15..3e0372d5 100644 --- a/lib/Predis/Commands/ListPopLastBlocking.php +++ b/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'; } } diff --git a/lib/Predis/Commands/ListPopLastPushHead.php b/lib/Predis/Commands/ListPopLastPushHead.php index 9e32ffd1..a5b934f6 100644 --- a/lib/Predis/Commands/ListPopLastPushHead.php +++ b/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'; } } diff --git a/lib/Predis/Commands/ListPopLastPushHeadBlocking.php b/lib/Predis/Commands/ListPopLastPushHeadBlocking.php index 6e43fc1a..02152170 100644 --- a/lib/Predis/Commands/ListPopLastPushHeadBlocking.php +++ b/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'; } } diff --git a/lib/Predis/Commands/SetIntersection.php b/lib/Predis/Commands/SetIntersection.php index e2484665..0fd86d6c 100644 --- a/lib/Predis/Commands/SetIntersection.php +++ b/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); diff --git a/lib/Predis/Commands/SetIntersectionStore.php b/lib/Predis/Commands/SetIntersectionStore.php index 78ea568c..0ba71d71 100644 --- a/lib/Predis/Commands/SetIntersectionStore.php +++ b/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); diff --git a/lib/Predis/Commands/SetMultiple.php b/lib/Predis/Commands/SetMultiple.php index f26977ff..a0e14e5d 100644 --- a/lib/Predis/Commands/SetMultiple.php +++ b/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])) { diff --git a/lib/Predis/Commands/ZSetIntersectionStore.php b/lib/Predis/Commands/ZSetIntersectionStore.php index 8e8b6a09..11bc9e91 100644 --- a/lib/Predis/Commands/ZSetIntersectionStore.php +++ b/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'; } } diff --git a/lib/Predis/Commands/ZSetUnionStore.php b/lib/Predis/Commands/ZSetUnionStore.php index aed60729..658c50cf 100644 --- a/lib/Predis/Commands/ZSetUnionStore.php +++ b/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();