SRANDMEMBER

Implemented SRANDMEMBER command for Redis and RedisCluster
This commit is contained in:
michael-grunder
2014-06-07 20:37:23 -07:00
parent 6534d933e1
commit 711950df9d
5 changed files with 84 additions and 36 deletions
+11 -36
View File
@@ -1339,49 +1339,24 @@ PHP_METHOD(Redis, sPop)
*/
PHP_METHOD(Redis, sRandMember)
{
zval *object;
char *cmd;
int cmd_len;
short have_count;
RedisSock *redis_sock;
char *key = NULL, *cmd;
int key_len, cmd_len, key_free = 0;
long count;
/* Parse our params */
if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l",
&object, redis_ce, &key, &key_len, &count) == FAILURE) {
// Grab our socket, validate call
if(redis_sock_get(getThis(), &redis_sock TSRMLS_CC, 0)<0 ||
redis_srandmember_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
&cmd, &cmd_len, NULL, NULL, &have_count)==FAILURE)
{
RETURN_FALSE;
}
/* Get our redis socket */
if(redis_sock_get(object, &redis_sock TSRMLS_CC, 0) < 0) {
RETURN_FALSE;
}
/* Prefix our key if necissary */
key_free = redis_key_prefix(redis_sock, &key, &key_len);
/* If we have two arguments, we're running with an optional COUNT, which will return */
/* a multibulk reply. Without the argument we'll return a string response */
if(ZEND_NUM_ARGS() == 2) {
// Construct our command with count
cmd_len = redis_cmd_format_static(&cmd, "SRANDMEMBER", "sl",
key, key_len, count);
} else {
// Construct our command
cmd_len = redis_cmd_format_static(&cmd, "SRANDMEMBER", "s",
key, key_len);
}
/* Free our key if we prefixed it */
if(key_free) efree(key);
/* Process our command */
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
/* Either bulk or multi-bulk depending on argument count */
if(ZEND_NUM_ARGS() == 2) {
if(have_count) {
IF_ATOMIC() {
if(redis_sock_read_multibulk_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
redis_sock, NULL, NULL) < 0)
redis_sock, NULL, NULL)<0)
{
RETURN_FALSE;
}
@@ -1390,7 +1365,7 @@ PHP_METHOD(Redis, sRandMember)
} else {
IF_ATOMIC() {
redis_string_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock,
NULL, NULL);
NULL, NULL);
}
REDIS_PROCESS_RESPONSE(redis_string_response);
}
+30
View File
@@ -62,6 +62,7 @@ zend_function_entry redis_cluster_functions[] = {
PHP_ME(RedisCluster, scard, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RedisCluster, smembers, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RedisCluster, sismember, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RedisCluster, srandmember, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RedisCluster, strlen, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RedisCluster, persist, NULL, ZEND_ACC_PUBLIC)
PHP_ME(RedisCluster, ttl, NULL, ZEND_ACC_PUBLIC)
@@ -361,6 +362,35 @@ PHP_METHOD(RedisCluster, spop) {
}
/* }}} */
/* {{{ proto string|array RedisCluster::srandmember(string key, [long count]) */
PHP_METHOD(RedisCluster, srandmember) {
redisCluster *c = GET_CONTEXT();
char *cmd; int cmd_len; short slot;
short have_count;
if(redis_srandmember_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU, c->flags,
&cmd, &cmd_len, &slot, NULL, &have_count)
==FAILURE)
{
RETURN_FALSE;
}
if(cluster_send_command(c,slot,cmd,cmd_len TSRMLS_CC)<0 || c->err!=NULL) {
efree(cmd);
RETURN_FALSE;
}
// Clean up command
efree(cmd);
// Response type differs if we use WITHSCORES or not
if(have_count) {
cluster_mbulk_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
} else {
cluster_bulk_resp(INTERNAL_FUNCTION_PARAM_PASSTHRU, c, NULL);
}
}
/* {{{ proto string RedisCluster::strlen(string key) */
PHP_METHOD(RedisCluster, strlen) {
CLUSTER_PROCESS_KW_CMD("STRLEN", redis_key_cmd, cluster_bulk_resp);
+1
View File
@@ -138,6 +138,7 @@ PHP_METHOD(RedisCluster, pfmerge);
PHP_METHOD(RedisCluster, restore);
PHP_METHOD(RedisCluster, setrange);
PHP_METHOD(RedisCluster, smove);
PHP_METHOD(RedisCluster, srandmember);
PHP_METHOD(RedisCluster, zrange);
PHP_METHOD(RedisCluster, zrevrange);
#endif
+39
View File
@@ -1259,4 +1259,43 @@ int redis_hsetnx_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
cmd, cmd_len, slot);
}
/* SRANDMEMBER */
int redis_srandmember_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx,
short *have_count)
{
char *key;
int key_len, key_free;
long count;
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &key, &key_len,
&count)==FAILURE)
{
return FAILURE;
}
// Prefix key if requested
key_free = redis_key_prefix(redis_sock, &key, &key_len);
// Set our have count flag
*have_count = ZEND_NUM_ARGS() == 2;
// Two args means we have the optional COUNT
if(*have_count) {
*cmd_len = redis_cmd_format_static(cmd, "SRANDMEMBER", "sl", key,
key_len, count);
} else {
*cmd_len = redis_cmd_format_static(cmd, "SRANDMEMBER", "s", key,
key_len);
}
// Set slot
CMD_SET_SLOT(slot,key,key_len);
// Cleanup
if(key_free) efree(key);
return SUCCESS;
}
/* vim: set tabstop=4 softtabstops=4 noexpandtab shiftwidth=4: */
+3
View File
@@ -113,6 +113,9 @@ int redis_hset_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
int redis_hsetnx_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx);
int redis_srandmember_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock,
char **cmd, int *cmd_len, short *slot, void **ctx,
short *have_count);
#endif
/* vim: set tabstop=4 softtabstops=4 noexpandtab shiftwidth=4: */