summaryrefslogtreecommitdiff
path: root/src/t_list.c
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2012-02-29 14:41:57 +0100
committerantirez <antirez@gmail.com>2012-02-29 14:41:57 +0100
commitc1db214eeb2b7385c32889e17748429fcbe5cbae (patch)
tree2ded05b066530e5e47d9dcf61bf6b85f3d854fe5 /src/t_list.c
parentcd8bdea31bdd682c811276a56515b65268f42958 (diff)
downloadredis-c1db214eeb2b7385c32889e17748429fcbe5cbae.tar.gz
Better implementation for BRPOP/BLPOP in the non blocking case.
Diffstat (limited to 'src/t_list.c')
-rw-r--r--src/t_list.c44
1 files changed, 15 insertions, 29 deletions
diff --git a/src/t_list.c b/src/t_list.c
index d6e28b7e5..2be8074a7 100644
--- a/src/t_list.c
+++ b/src/t_list.c
@@ -933,36 +933,22 @@ void blockingPopGenericCommand(redisClient *c, int where) {
return;
} else {
if (listTypeLength(o) != 0) {
- /* If the list contains elements fall back to the usual
- * non-blocking POP operation */
- struct redisCommand *orig_cmd;
- robj *argv[2], **orig_argv;
- int orig_argc;
-
- /* We need to alter the command arguments before to call
- * popGenericCommand() as the command takes a single key. */
- orig_argv = c->argv;
- orig_argc = c->argc;
- orig_cmd = c->cmd;
- argv[1] = c->argv[j];
- c->argv = argv;
- c->argc = 2;
-
- /* Also the return value is different, we need to output
- * the multi bulk reply header and the key name. The
- * "real" command will add the last element (the value)
- * for us. If this souds like an hack to you it's just
- * because it is... */
- addReplyMultiBulkLen(c,2);
- addReplyBulk(c,argv[1]);
-
- popGenericCommand(c,where);
-
- /* Fix the client structure with the original stuff */
- c->argv = orig_argv;
- c->argc = orig_argc;
- c->cmd = orig_cmd;
+ /* Non empty list, this is like a non normal [LR]POP. */
+ robj *value = listTypePop(o,where);
+ redisAssert(value != NULL);
+ addReplyMultiBulkLen(c,2);
+ addReplyBulk(c,c->argv[j]);
+ addReplyBulk(c,value);
+ decrRefCount(value);
+ if (listTypeLength(o) == 0) dbDelete(c->db,c->argv[j]);
+ signalModifiedKey(c->db,c->argv[j]);
+ server.dirty++;
+
+ /* Replicate it as an [LR]POP instead of B[LR]POP. */
+ rewriteClientCommandVector(c,2,
+ (where == REDIS_HEAD) ? shared.lpop : shared.rpop,
+ c->argv[j]);
return;
}
}