Commit 4f8cf6a2 authored by antirez's avatar antirez
Browse files

use the new rewriteClientCommandVector() function for SPOP -> SREM replication translation as well.

parent 0d119ad3
...@@ -947,3 +947,28 @@ void clientCommand(redisClient *c) { ...@@ -947,3 +947,28 @@ void clientCommand(redisClient *c) {
addReplyError(c, "Syntax error, try CLIENT (LIST | KILL ip:port)"); addReplyError(c, "Syntax error, try CLIENT (LIST | KILL ip:port)");
} }
} }
void rewriteClientCommandVector(redisClient *c, int argc, ...) {
va_list ap;
int j;
robj **argv; /* The new argument vector */
argv = zmalloc(sizeof(robj*)*argc);
va_start(ap,argc);
for (j = 0; j < argc; j++) {
robj *a;
a = va_arg(ap, robj*);
argv[j] = a;
incrRefCount(a);
}
/* We free the objects in the original vector at the end, so we are
* sure that if the same objects are reused in the new vector the
* refcount gets incremented before it gets decremented. */
for (j = 0; j < c->argc; j++) decrRefCount(c->argv[j]);
zfree(c->argv);
/* Replace argv and argc with our new versions. */
c->argv = argv;
c->argc = argc;
va_end(ap);
}
...@@ -677,6 +677,7 @@ void addReplyMultiBulkLen(redisClient *c, long length); ...@@ -677,6 +677,7 @@ void addReplyMultiBulkLen(redisClient *c, long length);
void *dupClientReplyValue(void *o); void *dupClientReplyValue(void *o);
void getClientsMaxBuffers(unsigned long *longest_output_list, void getClientsMaxBuffers(unsigned long *longest_output_list,
unsigned long *biggest_input_buffer); unsigned long *biggest_input_buffer);
void rewriteClientCommandVector(redisClient *c, int argc, ...);
#ifdef __GNUC__ #ifdef __GNUC__
void addReplyErrorFormat(redisClient *c, const char *fmt, ...) void addReplyErrorFormat(redisClient *c, const char *fmt, ...)
......
...@@ -624,31 +624,6 @@ void lremCommand(redisClient *c) { ...@@ -624,31 +624,6 @@ void lremCommand(redisClient *c) {
if (removed) touchWatchedKey(c->db,c->argv[1]); if (removed) touchWatchedKey(c->db,c->argv[1]);
} }
void rewriteClientCommandVector(redisClient *c, int argc, ...) {
va_list ap;
int j;
robj **argv; /* The new argument vector */
argv = zmalloc(sizeof(robj*)*argc);
va_start(ap,argc);
for (j = 0; j < argc; j++) {
robj *a;
a = va_arg(ap, robj*);
argv[j] = a;
incrRefCount(a);
}
/* We free the objects in the original vector at the end, so we are
* sure that if the same objects are reused in the new vector the
* refcount gets incremented before it gets decremented. */
for (j = 0; j < c->argc; j++) decrRefCount(c->argv[j]);
zfree(c->argv);
/* Replace argv and argc with our new versions. */
c->argv = argv;
c->argc = argc;
va_end(ap);
}
/* This is the semantic of this command: /* This is the semantic of this command:
* RPOPLPUSH srclist dstlist: * RPOPLPUSH srclist dstlist:
* IF LLEN(srclist) > 0 * IF LLEN(srclist) > 0
......
...@@ -329,7 +329,7 @@ void scardCommand(redisClient *c) { ...@@ -329,7 +329,7 @@ void scardCommand(redisClient *c) {
} }
void spopCommand(redisClient *c) { void spopCommand(redisClient *c) {
robj *set, *ele; robj *set, *ele, *aux;
int64_t llele; int64_t llele;
int encoding; int encoding;
...@@ -345,16 +345,11 @@ void spopCommand(redisClient *c) { ...@@ -345,16 +345,11 @@ void spopCommand(redisClient *c) {
setTypeRemove(set,ele); setTypeRemove(set,ele);
} }
/* Change argv to replicate as SREM */ /* Replicate/AOF this command as an SREM operation */
c->argc = 3; aux = createStringObject("SREM",4);
c->argv = zrealloc(c->argv,sizeof(robj*)*(c->argc)); rewriteClientCommandVector(c,3,aux,c->argv[1],ele);
decrRefCount(ele);
/* Overwrite SREM with SPOP (same length) */ decrRefCount(aux);
redisAssert(sdslen(c->argv[0]->ptr) == 4);
memcpy(c->argv[0]->ptr, "SREM", 4);
/* Popped element already has incremented refcount */
c->argv[2] = ele;
addReplyBulk(c,ele); addReplyBulk(c,ele);
if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]); if (setTypeSize(set) == 0) dbDelete(c->db,c->argv[1]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment