diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | php_redis.h | 2 | ||||
-rw-r--r-- | redis.c | 26 | ||||
-rw-r--r-- | redis_cluster.c | 24 | ||||
-rw-r--r-- | redis_cluster.h | 2 | ||||
-rw-r--r-- | redis_commands.c | 17 | ||||
-rw-r--r-- | redis_commands.h | 9 | ||||
-rw-r--r-- | tests/RedisTest.php | 30 |
8 files changed, 81 insertions, 30 deletions
@@ -16,3 +16,4 @@ mkinstalldirs run-tests.php idea/* .cquery +tags diff --git a/php_redis.h b/php_redis.h index 1f1eb1ac..d6240ec1 100644 --- a/php_redis.h +++ b/php_redis.h @@ -133,6 +133,8 @@ PHP_METHOD(Redis, zInter); PHP_METHOD(Redis, zUnion); PHP_METHOD(Redis, zPopMax); PHP_METHOD(Redis, zPopMin); +PHP_METHOD(Redis, bzPopMax); +PHP_METHOD(Redis, bzPopMin); PHP_METHOD(Redis, expireAt); PHP_METHOD(Redis, pexpireAt); PHP_METHOD(Redis, bgrewriteaof); @@ -259,6 +259,8 @@ static zend_function_entry redis_functions[] = { PHP_ME(Redis, blPop, arginfo_blrpop, ZEND_ACC_PUBLIC) PHP_ME(Redis, brPop, arginfo_blrpop, ZEND_ACC_PUBLIC) PHP_ME(Redis, brpoplpush, arginfo_brpoplpush, ZEND_ACC_PUBLIC) + PHP_ME(Redis, bzPopMax, arginfo_blrpop, ZEND_ACC_PUBLIC) + PHP_ME(Redis, bzPopMin, arginfo_blrpop, ZEND_ACC_PUBLIC) PHP_ME(Redis, clearLastError, arginfo_void, ZEND_ACC_PUBLIC) PHP_ME(Redis, client, arginfo_client, ZEND_ACC_PUBLIC) PHP_ME(Redis, close, arginfo_void, ZEND_ACC_PUBLIC) @@ -1376,14 +1378,14 @@ PHP_METHOD(Redis, rPop) /* {{{ proto string Redis::blPop(string key1, string key2, ..., int timeout) */ PHP_METHOD(Redis, blPop) { - REDIS_PROCESS_CMD(blpop, redis_sock_read_multibulk_reply); + REDIS_PROCESS_KW_CMD("BLPOP", redis_varkey_timeout_cmd, redis_sock_read_multibulk_reply); } /* }}} */ /* {{{ proto string Redis::brPop(string key1, string key2, ..., int timeout) */ PHP_METHOD(Redis, brPop) { - REDIS_PROCESS_CMD(brpop, redis_sock_read_multibulk_reply); + REDIS_PROCESS_KW_CMD("BRPOP", redis_varkey_timeout_cmd, redis_sock_read_multibulk_reply); } /* }}} */ @@ -2144,9 +2146,9 @@ PHP_METHOD(Redis, zUnion) { PHP_METHOD(Redis, zPopMax) { if (ZEND_NUM_ARGS() == 1) { - REDIS_PROCESS_KW_CMD("ZPOPMAX", redis_key_cmd, redis_sock_read_multibulk_reply); + REDIS_PROCESS_KW_CMD("ZPOPMAX", redis_key_cmd, redis_mbulk_reply_zipped_keys_dbl); } else if (ZEND_NUM_ARGS() == 2) { - REDIS_PROCESS_KW_CMD("ZPOPMAX", redis_key_long_cmd, redis_sock_read_multibulk_reply); + REDIS_PROCESS_KW_CMD("ZPOPMAX", redis_key_long_cmd, redis_mbulk_reply_zipped_keys_dbl); } else { ZEND_WRONG_PARAM_COUNT(); } @@ -2157,15 +2159,27 @@ PHP_METHOD(Redis, zPopMax) PHP_METHOD(Redis, zPopMin) { if (ZEND_NUM_ARGS() == 1) { - REDIS_PROCESS_KW_CMD("ZPOPMIN", redis_key_cmd, redis_sock_read_multibulk_reply); + REDIS_PROCESS_KW_CMD("ZPOPMIN", redis_key_cmd, redis_mbulk_reply_zipped_keys_dbl); } else if (ZEND_NUM_ARGS() == 2) { - REDIS_PROCESS_KW_CMD("ZPOPMIN", redis_key_long_cmd, redis_sock_read_multibulk_reply); + REDIS_PROCESS_KW_CMD("ZPOPMIN", redis_key_long_cmd, redis_mbulk_reply_zipped_keys_dbl); } else { ZEND_WRONG_PARAM_COUNT(); } } /* }}} */ +/* {{{ proto Redis::bzPopMax(Array(keys) [, timeout]): Array */ +PHP_METHOD(Redis, bzPopMax) { + REDIS_PROCESS_KW_CMD("BZPOPMAX", redis_varkey_timeout_cmd, redis_sock_read_multibulk_reply); +} +/* }}} */ + +/* {{{ proto Redis::bzPopMin(Array(keys) [, timeout]): Array */ +PHP_METHOD(Redis, bzPopMin) { + REDIS_PROCESS_KW_CMD("BZPOPMIN", redis_varkey_timeout_cmd, redis_sock_read_multibulk_reply); +} +/* }}} */ + /* hashes */ /* {{{ proto long Redis::hset(string key, string mem, string val) */ diff --git a/redis_cluster.c b/redis_cluster.c index 7087e478..f9da1cc0 100644 --- a/redis_cluster.c +++ b/redis_cluster.c @@ -124,6 +124,8 @@ zend_function_entry redis_cluster_functions[] = { PHP_ME(RedisCluster, brpop, arginfo_blrpop, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, brpoplpush, arginfo_brpoplpush, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, clearlasterror, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, bzpopmax, arginfo_blrpop, ZEND_ACC_PUBLIC) + PHP_ME(RedisCluster, bzpopmin, arginfo_blrpop, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, client, arginfo_key_or_address_variadic, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, close, arginfo_void, ZEND_ACC_PUBLIC) PHP_ME(RedisCluster, cluster, arginfo_key_or_address_variadic, ZEND_ACC_PUBLIC) @@ -1257,13 +1259,13 @@ PHP_METHOD(RedisCluster, rpush) { /* {{{ proto array RedisCluster::blpop(string key1, ... keyN, long timeout) */ PHP_METHOD(RedisCluster, blpop) { - CLUSTER_PROCESS_CMD(blpop, cluster_mbulk_resp, 0); + CLUSTER_PROCESS_KW_CMD("BLPOP", redis_varkey_timeout_cmd, cluster_mbulk_resp, 0); } /* }}} */ /* {{{ proto array RedisCluster::brpop(string key1, ... keyN, long timeout */ PHP_METHOD(RedisCluster, brpop) { - CLUSTER_PROCESS_CMD(brpop, cluster_mbulk_resp, 0); + CLUSTER_PROCESS_KW_CMD("BRPOP", redis_varkey_timeout_cmd, cluster_mbulk_resp, 0); } /* }}} */ @@ -1849,9 +1851,9 @@ PHP_METHOD(RedisCluster, zremrangebylex) { /* {{{ proto array RedisCluster::zpopmax(string key) */ PHP_METHOD(RedisCluster, zpopmax) { if (ZEND_NUM_ARGS() == 1) { - CLUSTER_PROCESS_KW_CMD("ZPOPMAX", redis_key_cmd, cluster_mbulk_resp, 0); + CLUSTER_PROCESS_KW_CMD("ZPOPMAX", redis_key_cmd, cluster_mbulk_zipdbl_resp, 0); } else if (ZEND_NUM_ARGS() == 2) { - CLUSTER_PROCESS_KW_CMD("ZPOPMAX", redis_key_long_cmd, cluster_mbulk_resp, 0); + CLUSTER_PROCESS_KW_CMD("ZPOPMAX", redis_key_long_cmd, cluster_mbulk_zipdbl_resp, 0); } else { ZEND_WRONG_PARAM_COUNT(); } @@ -1861,15 +1863,25 @@ PHP_METHOD(RedisCluster, zpopmax) { /* {{{ proto array RedisCluster::zpopmin(string key) */ PHP_METHOD(RedisCluster, zpopmin) { if (ZEND_NUM_ARGS() == 1) { - CLUSTER_PROCESS_KW_CMD("ZPOPMIN", redis_key_cmd, cluster_mbulk_resp, 0); + CLUSTER_PROCESS_KW_CMD("ZPOPMIN", redis_key_cmd, cluster_mbulk_zipdbl_resp, 0); } else if (ZEND_NUM_ARGS() == 2) { - CLUSTER_PROCESS_KW_CMD("ZPOPMIN", redis_key_long_cmd, cluster_mbulk_resp, 0); + CLUSTER_PROCESS_KW_CMD("ZPOPMIN", redis_key_long_cmd, cluster_mbulk_zipdbl_resp, 0); } else { ZEND_WRONG_PARAM_COUNT(); } } /* }}} */ +/* {{{ proto array RedisCluster::bzPopMin(Array keys [, timeout]) }}} */ +PHP_METHOD(RedisCluster, bzpopmax) { + CLUSTER_PROCESS_KW_CMD("BZPOPMAX", redis_varkey_timeout_cmd, cluster_mbulk_resp, 0); +} + +/* {{{ proto array RedisCluster::bzPopMax(Array keys [, timeout]) }}} */ +PHP_METHOD(RedisCluster, bzpopmin) { + CLUSTER_PROCESS_KW_CMD("BZPOPMIN", redis_varkey_timeout_cmd, cluster_mbulk_resp, 0); +} + /* {{{ proto RedisCluster::sort(string key, array options) */ PHP_METHOD(RedisCluster, sort) { redisCluster *c = GET_CONTEXT(); diff --git a/redis_cluster.h b/redis_cluster.h index 5e928174..69354506 100644 --- a/redis_cluster.h +++ b/redis_cluster.h @@ -226,6 +226,8 @@ PHP_METHOD(RedisCluster, smove); PHP_METHOD(RedisCluster, srandmember); PHP_METHOD(RedisCluster, zpopmin); PHP_METHOD(RedisCluster, zpopmax); +PHP_METHOD(RedisCluster, bzpopmax); +PHP_METHOD(RedisCluster, bzpopmin); PHP_METHOD(RedisCluster, zrange); PHP_METHOD(RedisCluster, zrevrange); PHP_METHOD(RedisCluster, zrangebyscore); diff --git a/redis_commands.c b/redis_commands.c index db854738..c77ff31e 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -1251,6 +1251,15 @@ static int gen_varkey_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, return SUCCESS; } +/* Generic handling of every blocking pop command (BLPOP, BZPOP[MIN/MAX], etc */ +int redis_varkey_timeout_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char *kw, char **cmd, int *cmd_len, short *slot, + void **ctx) +{ + return gen_varkey_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, kw, + strlen(kw), 2, 1, cmd, cmd_len, slot); +} + /* * Commands with specific signatures or that need unique functions because they * have specific processing (argument validation, etc) that make them unique @@ -3052,14 +3061,6 @@ int redis_blpop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, "BLPOP", sizeof("BLPOP")-1, 2, 1, cmd, cmd_len, slot); } -/* BRPOP */ -int redis_brpop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, - char **cmd, int *cmd_len, short *slot, void **ctx) -{ - return gen_varkey_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, - "BRPOP", sizeof("BRPOP")-1, 1, 1, cmd, cmd_len, slot); -} - /* SINTER */ int redis_sinter_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx) diff --git a/redis_commands.h b/redis_commands.h index 1ef1712c..11fbd695 100644 --- a/redis_commands.h +++ b/redis_commands.h @@ -78,6 +78,9 @@ int redis_key_val_arr_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, int redis_key_str_arr_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char *kw, char **cmd, int *cmd_len, short *slot, void **ctx); +int redis_varkey_timeout_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, + char *kw, char **cmd, int *cmd_len, short *slot, void **ctx); + /* Construct SCAN and similar commands, as well as check iterator */ int redis_scan_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, REDIS_SCAN_TYPE type, char **cmd, int *cmd_len); @@ -226,12 +229,6 @@ int redis_unlink_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, int redis_watch_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx); -int redis_blpop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, - char **cmd, int *cmd_len, short *slot, void **ctx); - -int redis_brpop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, - char **cmd, int *cmd_len, short *slot, void **ctx); - int redis_sinter_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, char **cmd, int *cmd_len, short *slot, void **ctx); diff --git a/tests/RedisTest.php b/tests/RedisTest.php index e666b1fc..7dcd17fe 100644 --- a/tests/RedisTest.php +++ b/tests/RedisTest.php @@ -2409,6 +2409,28 @@ class Redis_Test extends TestSuite $this->assertEquals($this->redis->zRemRangeByLex('key', '[a', '[c'), 2); } + public function testBZPop() { + if (version_compare($this->version, "5.0.0", "lt")) { + $this->MarkTestSkipped(); + return; + } + + $this->redis->del('{zs}1', '{zs}2'); + $this->redis->zAdd('{zs}1', 0, 'a', 1, 'b', 2, 'c'); + $this->redis->zAdd('{zs}2', 3, 'A', 4, 'B', 5, 'D'); + + $this->assertEquals(Array('{zs}1', 'a', '0'), $this->redis->bzPopMin('{zs}1', '{zs}2', 0)); + $this->assertEquals(Array('{zs}1', 'c', '2'), $this->redis->bzPopMax(Array('{zs}1', '{zs}2'), 0)); + $this->assertEquals(Array('{zs}2', 'A', '3'), $this->redis->bzPopMin('{zs}2', '{zs}1', 0)); + + /* Verify timeout is being sent */ + $this->redis->del('{zs}1', '{zs}2'); + $st = microtime(true) * 1000; + $this->redis->bzPopMin('{zs}1', '{zs}2', 1); + $et = microtime(true) * 1000; + $this->assertTrue($et - $st > 100); + } + public function testZPop() { if (version_compare($this->version, "5.0.0", "lt")) { $this->MarkTestSkipped(); @@ -2418,18 +2440,18 @@ class Redis_Test extends TestSuite // zPopMax and zPopMin without a COUNT argument $this->redis->del('key'); $this->redis->zAdd('key', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e'); - $this->assertTrue(array('e', '4') === $this->redis->zPopMax('key')); - $this->assertTrue(array('a', '0') === $this->redis->zPopMin('key')); + $this->assertTrue(array('e' => 4.0) === $this->redis->zPopMax('key')); + $this->assertTrue(array('a' => 0.0) === $this->redis->zPopMin('key')); // zPopMax with a COUNT argument $this->redis->del('key'); $this->redis->zAdd('key', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e'); - $this->assertTrue(array('e', '4', 'd', '3', 'c', '2') === $this->redis->zPopMax('key', 3)); + $this->assertTrue(array('e' => 4.0, 'd' => 3.0, 'c' => 2.0) === $this->redis->zPopMax('key', 3)); // zPopMin with a COUNT argument $this->redis->del('key'); $this->redis->zAdd('key', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e'); - $this->assertTrue(array('a', '0', 'b', '1', 'c', '2') === $this->redis->zPopMin('key', 3)); + $this->assertTrue(array('a' => 0.0, 'b' => 1.0, 'c' => 2.0) === $this->redis->zPopMin('key', 3)); } public function testHashes() { |