mirror of
https://github.com/php-win-ext/phpredis.git
synced 2026-03-24 00:52:16 +01:00
Change ZPOP* return type and implement blocking variants
This commit updates ZPOPMIN/ZPOPMAX to return the same format that zRange WITHSCORES and zRangeByScore WITHSCORES does. In addition the blocking variants BZPOPMIN and BZPOPMAX are implemented.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@ mkinstalldirs
|
||||
run-tests.php
|
||||
idea/*
|
||||
.cquery
|
||||
tags
|
||||
|
||||
@@ -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);
|
||||
|
||||
26
redis.c
26
redis.c
@@ -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) */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user