From 0cd7b446c659b91769c9a7a0f68fc461defc90f4 Mon Sep 17 00:00:00 2001 From: Daniele Alessandri Date: Thu, 25 Feb 2010 12:46:10 +0100 Subject: [PATCH] Users can now choose at runtime how to handle multibulk responses. The new (and optional) iterator-based approach is slightly slower than the usual fetch-all behaviour, but in certain scenarios (e.g. when dealing with massive multibulk responses) it can save a lot of memory on the client. --- lib/Predis.php | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/Predis.php b/lib/Predis.php index d7a60255..73233b93 100644 --- a/lib/Predis.php +++ b/lib/Predis.php @@ -85,6 +85,10 @@ class Client { return $this->_serverProfile; } + public function useMultiBulkIterator($value = true) { + Response::useMultiBulkIterator($value); + } + public function connect() { $this->_connection->connect(); } @@ -336,6 +340,15 @@ class ResponseMultiBulkHandler implements IResponseHandler { } } +class ResponseMultiBulkStreamHandler implements IResponseHandler { + public function handle($socket, $prefix, $rawLength) { + if (!is_numeric($rawLength)) { + throw new ClientException("Cannot parse '$rawLength' as data length"); + } + return new Utilities\MultiBulkResponseIterator($socket, (int)$rawLength); + } +} + class ResponseIntegerHandler implements IResponseHandler { public function handle($socket, $prefix, $number) { if (is_numeric($number)) { @@ -357,7 +370,7 @@ class Response { const QUEUED = 'QUEUED'; const NULL = 'nil'; - private static $_prefixHandlers; + private static $_prefixHandlers, $_useMultiBulkIterator; private static function initializePrefixHandlers() { return array( @@ -365,10 +378,22 @@ class Response { '-' => new ResponseErrorHandler(), ':' => new ResponseIntegerHandler(), '$' => new ResponseBulkHandler(), - '*' => new ResponseMultiBulkHandler() + '*' => self::$_useMultiBulkIterator + ? new ResponseMultiBulkStreamHandler() + : new ResponseMultiBulkHandler() ); } + public static function useMultiBulkIterator($value = null) { + if (is_bool($value)) { + self::$_useMultiBulkIterator = $value; + self::$_prefixHandlers = self::initializePrefixHandlers(); + } + else { + return self::$_useMultiBulkIterator; + } + } + public static function read($socket) { $header = fgets($socket); if ($header === false) {