Merge branch 'command_hashing'

This commit is contained in:
Daniele Alessandri
2011-03-27 18:50:55 +02:00
47 changed files with 111 additions and 57 deletions
+1 -1
View File
@@ -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'; }
}
@@ -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';
+1 -1
View File
@@ -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') {
+29 -14
View File
@@ -8,7 +8,33 @@ abstract class Command implements ICommand {
private $_hash;
private $_arguments = array();
public function canBeHashed() {
protected function canBeHashed() {
return isset($this->_arguments[0]);
}
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;
}
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;
}
@@ -16,19 +42,8 @@ abstract class Command implements ICommand {
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);
}
}
if ($this->canBeHashed()) {
$key = $this->getHashablePart($this->_arguments[0]);
$this->_hash = $distributor->generateKey($key);
return $this->_hash;
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+7
View File
@@ -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);
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+3 -1
View File
@@ -5,7 +5,9 @@ namespace Predis\Commands;
use Predis\Utils;
class GetMultiple extends Command {
public 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);
-1
View File
@@ -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();
+1 -1
View File
@@ -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();
-1
View File
@@ -3,7 +3,6 @@
namespace Predis\Commands;
class InfoV24x extends Info {
public function canBeHashed() { return false; }
public function parseResponse($data) {
$info = array();
$current = null;
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
@@ -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
View File
@@ -2,6 +2,6 @@
namespace Predis\Commands;
class ListPopLastBlocking extends Command {
class ListPopLastBlocking extends ListPopFirstBlocking {
public function getId() { return 'BRPOP'; }
}
@@ -3,5 +3,8 @@
namespace Predis\Commands;
class ListPopLastPushHead extends Command {
protected function canBeHashed() {
return $this->checkSameHashForKeys($this->getArguments());
}
public function getId() { return 'RPOPLPUSH'; }
}
@@ -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'; }
}
+1 -1
View File
@@ -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; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+3
View File
@@ -5,6 +5,9 @@ namespace Predis\Commands;
use Predis\Utils;
class SetIntersection extends Command {
protected function canBeHashed() {
return $this->checkSameHashForKeys($this->getArguments());
}
public function getId() { return 'SINTER'; }
public function filterArguments(Array $arguments) {
return Utils::filterArrayArguments($arguments);
@@ -5,6 +5,9 @@ namespace Predis\Commands;
use Predis\Utils;
class SetIntersectionStore extends Command {
protected function canBeHashed() {
return $this->checkSameHashForKeys($this->getArguments());
}
public function getId() { return 'SINTERSTORE'; }
public function filterArguments(Array $arguments) {
if (count($arguments) === 2 && is_array($arguments[1])) {
+1 -1
View File
@@ -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; }
}
+8 -1
View File
@@ -3,7 +3,14 @@
namespace Predis\Commands;
class SetMultiple extends Command {
public 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])) {
@@ -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; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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') {
+1 -1
View File
@@ -5,7 +5,7 @@ namespace Predis\Commands;
use Predis\Utils;
class Subscribe extends Command {
public function canBeHashed() { return false; }
protected function canBeHashed() { return false; }
public function getId() { return 'SUBSCRIBE'; }
public function filterArguments(Array $arguments) {
return Utils::filterArrayArguments($arguments);
+1 -1
View File
@@ -3,7 +3,7 @@
namespace Predis\Commands;
class SubscribeByPattern extends Command {
public function canBeHashed() { return false; }
protected function canBeHashed() { return false; }
public function getId() { return 'PSUBSCRIBE'; }
public function filterArguments(Array $arguments) {
return Utils::filterArrayArguments($arguments);
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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'; }
}
+1 -1
View File
@@ -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; }
}
+1 -1
View File
@@ -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])) {
+6
View File
@@ -3,6 +3,12 @@
namespace Predis\Commands;
class ZSetUnionStore extends Command {
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();
+6 -5
View File
@@ -47,12 +47,13 @@ class ConnectionCluster implements IConnectionCluster, \IteratorAggregate {
}
public function getConnection(ICommand $command) {
if ($command->canBeHashed() === false) {
throw new ClientException(
sprintf("Cannot send '%s' commands to a cluster of connections", $command->getId())
);
$cmdHash = $command->getHash($this->_distributor);
if (isset($cmdHash)) {
return $this->_distributor->get($cmdHash);
}
return $this->_distributor->get($command->getHash($this->_distributor));
throw new ClientException(
sprintf("Cannot send '%s' commands to a cluster of connections", $command->getId())
);
}
public function getConnectionById($id = null) {