mirror of
http://github.com/valkey-io/valkey
synced 2024-11-22 18:54:58 +00:00
some work on ZADD against existing element (score update), still broken...
This commit is contained in:
parent
0aad7a1938
commit
e197b441a2
@ -20,7 +20,7 @@ array set ::redis::multibulkarg {}
|
||||
|
||||
# Flag commands requiring last argument as a bulk write operation
|
||||
foreach redis_bulk_cmd {
|
||||
set setnx rpush lpush lset lrem sadd srem sismember echo getset smove
|
||||
set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd
|
||||
} {
|
||||
set ::redis::bulkarg($redis_bulk_cmd) {}
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ static struct redisCommand cmdTable[] = {
|
||||
{"smembers",2,REDIS_CMD_INLINE},
|
||||
{"zadd",4,REDIS_CMD_BULK},
|
||||
{"zrange",4,REDIS_CMD_INLINE},
|
||||
{"zlen",2,REDIS_CMD_INLINE},
|
||||
{"incrby",3,REDIS_CMD_INLINE},
|
||||
{"decrby",3,REDIS_CMD_INLINE},
|
||||
{"getset",3,REDIS_CMD_BULK},
|
||||
|
53
redis.c
53
redis.c
@ -435,6 +435,7 @@ static void msetCommand(redisClient *c);
|
||||
static void msetnxCommand(redisClient *c);
|
||||
static void zaddCommand(redisClient *c);
|
||||
static void zrangeCommand(redisClient *c);
|
||||
static void zlenCommand(redisClient *c);
|
||||
|
||||
/*================================= Globals ================================= */
|
||||
|
||||
@ -475,6 +476,7 @@ static struct redisCommand cmdTable[] = {
|
||||
{"smembers",sinterCommand,2,REDIS_CMD_INLINE},
|
||||
{"zadd",zaddCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
|
||||
{"zrange",zrangeCommand,4,REDIS_CMD_INLINE},
|
||||
{"zlen",zlenCommand,2,REDIS_CMD_INLINE},
|
||||
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
||||
{"decrby",decrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
|
||||
{"getset",getsetCommand,3,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
|
||||
@ -2052,6 +2054,7 @@ static robj *getDecodedObject(const robj *o) {
|
||||
static int compareStringObjects(robj *a, robj *b) {
|
||||
assert(a->type == REDIS_STRING && b->type == REDIS_STRING);
|
||||
|
||||
if (a == b) return 0;
|
||||
if (a->encoding == REDIS_ENCODING_INT && b->encoding == REDIS_ENCODING_INT){
|
||||
return (long)a->ptr - (long)b->ptr;
|
||||
} else {
|
||||
@ -3751,7 +3754,6 @@ static void zslInsert(zskiplist *zsl, double score, robj *obj) {
|
||||
x = x->forward[i];
|
||||
update[i] = x;
|
||||
}
|
||||
x = x->forward[1];
|
||||
/* we assume the key is not already inside, since we allow duplicated
|
||||
* scores, and the re-insertion of score and redis object should never
|
||||
* happpen since the caller of zslInsert() should test in the hash table
|
||||
@ -3771,7 +3773,34 @@ static void zslInsert(zskiplist *zsl, double score, robj *obj) {
|
||||
}
|
||||
|
||||
static int zslDelete(zskiplist *zsl, double score, robj *obj) {
|
||||
return 1;
|
||||
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
|
||||
int i;
|
||||
|
||||
x = zsl->header;
|
||||
for (i = zsl->level-1; i >= 0; i--) {
|
||||
while (x->forward[i] && x->forward[i]->score < score)
|
||||
x = x->forward[i];
|
||||
update[i] = x;
|
||||
}
|
||||
/* We may have multiple elements with the same score, what we need
|
||||
* is to find the element with both the right score and object. */
|
||||
x = x->forward[0];
|
||||
while(x->score == score) {
|
||||
if (compareStringObjects(x->obj,obj) == 0) {
|
||||
for (i = 0; i < zsl->level; i++) {
|
||||
if (update[i]->forward[i] != x) break;
|
||||
update[i]->forward[i] = x->forward[i];
|
||||
}
|
||||
zslFreeNode(x);
|
||||
while(zsl->level > 1 && zsl->header->forward[zsl->level-1] == NULL)
|
||||
zsl->level--;
|
||||
return 1;
|
||||
} else {
|
||||
x = x->forward[0];
|
||||
if (!x) return 0; /* end of the list reached, not found */
|
||||
}
|
||||
}
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
/* The actual Z-commands implementations */
|
||||
@ -3813,7 +3842,7 @@ static void zaddCommand(redisClient *c) {
|
||||
if (*score != *oldscore) {
|
||||
int deleted;
|
||||
|
||||
deleted = zslDelete(zs->zsl,*score,c->argv[3]);
|
||||
deleted = zslDelete(zs->zsl,*oldscore,c->argv[3]);
|
||||
assert(deleted != 0);
|
||||
zslInsert(zs->zsl,*score,c->argv[3]);
|
||||
incrRefCount(c->argv[3]);
|
||||
@ -3875,6 +3904,24 @@ static void zrangeCommand(redisClient *c) {
|
||||
}
|
||||
}
|
||||
|
||||
static void zlenCommand(redisClient *c) {
|
||||
robj *o;
|
||||
zset *zs;
|
||||
|
||||
o = lookupKeyRead(c->db,c->argv[1]);
|
||||
if (o == NULL) {
|
||||
addReply(c,shared.czero);
|
||||
return;
|
||||
} else {
|
||||
if (o->type != REDIS_ZSET) {
|
||||
addReply(c,shared.wrongtypeerr);
|
||||
} else {
|
||||
zs = o->ptr;
|
||||
addReplySds(c,sdscatprintf(sdsempty(),":%d\r\n",zs->zsl->length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================= Non type-specific commands ==================== */
|
||||
|
||||
static void flushdbCommand(redisClient *c) {
|
||||
|
Loading…
Reference in New Issue
Block a user