From 92d4306dc479b32fddb234cfa243be17b29edd0d Mon Sep 17 00:00:00 2001 From: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> Date: Tue, 31 Jan 2023 16:12:18 +0200 Subject: [PATCH] Added support for CF.INFO command (#1082) Co-authored-by: Vladyslav Vildanov --- src/ClientContextInterface.php | 1 + src/ClientInterface.php | 1 + src/Command/Redis/BloomFilter/BFINFO.php | 2 +- src/Command/Redis/CuckooFilter/CFINFO.php | 45 ++++++ .../Redis/CuckooFilter/CFINFO_Test.php | 137 ++++++++++++++++++ 5 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/Command/Redis/CuckooFilter/CFINFO.php create mode 100644 tests/Predis/Command/Redis/CuckooFilter/CFINFO_Test.php diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index 37171fce..53b4edad 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -64,6 +64,7 @@ use Predis\Command\CommandInterface; * @method $this cfcount(string $key, $item) * @method $this cfexists(string $key, $item) * @method $this cfmexists(string $key, ...$item) + * @method $this cfinfo(string $key) * @method $this decr($key) * @method $this decrby($key, $decrement) * @method $this failover(?To $to = null, bool $abort = false, int $timeout = -1) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index 93a7cb78..bd619c9b 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -73,6 +73,7 @@ use Predis\Response\Status; * @method int cfcount(string $key, $item) * @method int cfexists(string $key, $item) * @method int cfmexists(string $key, ...$item) + * @method array cfinfo(string $key) * @method int decr(string $key) * @method int decrby(string $key, int $decrement) * @method Status failover(?To $to = null, bool $abort = false, int $timeout = -1) diff --git a/src/Command/Redis/BloomFilter/BFINFO.php b/src/Command/Redis/BloomFilter/BFINFO.php index 4f27eaab..00acd4d5 100644 --- a/src/Command/Redis/BloomFilter/BFINFO.php +++ b/src/Command/Redis/BloomFilter/BFINFO.php @@ -66,7 +66,7 @@ class BFINFO extends RedisCommand $result = []; for ($i = 0, $iMax = count($data); $i < $iMax; ++$i) { - if ($data[$i + 1] ?? false) { + if (array_key_exists($i + 1, $data)) { $result[(string) $data[$i]] = $data[++$i]; } } diff --git a/src/Command/Redis/CuckooFilter/CFINFO.php b/src/Command/Redis/CuckooFilter/CFINFO.php new file mode 100644 index 00000000..9a34640e --- /dev/null +++ b/src/Command/Redis/CuckooFilter/CFINFO.php @@ -0,0 +1,45 @@ + 1) { + $result = []; + + for ($i = 0, $iMax = count($data); $i < $iMax; ++$i) { + if (array_key_exists($i + 1, $data)) { + $result[(string) $data[$i]] = $data[++$i]; + } + } + + return $result; + } + + return $data; + } +} diff --git a/tests/Predis/Command/Redis/CuckooFilter/CFINFO_Test.php b/tests/Predis/Command/Redis/CuckooFilter/CFINFO_Test.php new file mode 100644 index 00000000..9af01c2b --- /dev/null +++ b/tests/Predis/Command/Redis/CuckooFilter/CFINFO_Test.php @@ -0,0 +1,137 @@ +getCommand(); + $command->setArguments($actualArguments); + + $this->assertSameValues($expectedArguments, $command->getArguments()); + } + + /** + * @group disconnected + * @dataProvider responsesProvider + */ + public function testParseResponse(array $actualResponse, array $expectedResponse): void + { + $this->assertSame($expectedResponse, $this->getCommand()->parseResponse($actualResponse)); + } + + /** + * @group connected + * @return void + * @requiresRedisBfVersion >= 1.0.0 + */ + public function testInfoReturnsInformationAboutGivenCuckooFilter(): void + { + $redis = $this->getClient(); + $expectedResponse = [ + 'Size' => 1080, + 'Number of buckets' => 512, + 'Number of filters' => 1, + 'Number of items inserted' => 1, + 'Number of items deleted' => 0, + 'Bucket size' => 2, + 'Expansion rate' => 1, + 'Max iterations' => 20, + ]; + + $redis->cfadd('key', 'item'); + + $this->assertSame($expectedResponse, $redis->cfinfo('key')); + } + + /** + * @group connected + * @return void + * @requiresRedisBfVersion >= 1.0.0 + */ + public function testInfoThrowsExceptionOnNonExistingFilterKeyGiven(): void + { + $redis = $this->getClient(); + + $this->expectException(ServerException::class); + $this->expectExceptionMessage('ERR not found'); + + $redis->cfinfo('non_existing_key'); + } + + public function responsesProvider(): array + { + return [ + 'with one modifier' => [ + [100], + [100], + ], + 'with all modifiers' => [ + [ + 'Size', + 100, + 'Number of buckets', + 296, + 'Number of filter', + 1, + 'Number of items inserted', + 1, + 'Number of items deleted', + 1, + 'Bucket size', + 0, + 'Expansion rate', + 1, + 'Max iteration', + 20, + ], + [ + 'Size' => 100, + 'Number of buckets' => 296, + 'Number of filter' => 1, + 'Number of items inserted' => 1, + 'Number of items deleted' => 1, + 'Bucket size' => 0, + 'Expansion rate' => 1, + 'Max iteration' => 20, + ], + ], + ]; + } +}