From 1b7106e7dbf5317299da74cd79a1d488daa1bdaf Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 26 Oct 2009 12:04:42 +0100 Subject: [PATCH] ZREM implemented --- TODO | 2 +- client-libraries/tcl/redis.tcl | 2 +- redis-cli.c | 1 + redis.c | 38 ++++++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index bb2c7f91..62a28a83 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,7 @@ Pre 1.1 todo * For now only the last argument gets integer encoded, so make sure that: 1) every multi bulk commands implemented will have the last arg that is indeed a value, and not used otherwise. 2) to explicitly call the function to encode the object in MSET and other commands where there are multiple "values". * Man pages for MSET MSETNX and SRANDMEMBER. * Hashes (HSET, HGET, HEXISTS, HLEN, ...). -* ZSETs +* ZSETs: ZADD, ZRANGE, ZDEL, ZINCRBY, ZSCORE. * An utility able to export an .rdb file into a text-only JSON dump, we can't live anymore without such a tool. Probably an extension to redis-cli. After 1.1 todo diff --git a/client-libraries/tcl/redis.tcl b/client-libraries/tcl/redis.tcl index 86b7eb48..8bca7886 100644 --- a/client-libraries/tcl/redis.tcl +++ b/client-libraries/tcl/redis.tcl @@ -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 zadd + set setnx rpush lpush lset lrem sadd srem sismember echo getset smove zadd zrem } { set ::redis::bulkarg($redis_bulk_cmd) {} } diff --git a/redis-cli.c b/redis-cli.c index dc16617f..a5608cad 100644 --- a/redis-cli.c +++ b/redis-cli.c @@ -90,6 +90,7 @@ static struct redisCommand cmdTable[] = { {"sdiffstore",-3,REDIS_CMD_INLINE}, {"smembers",2,REDIS_CMD_INLINE}, {"zadd",4,REDIS_CMD_BULK}, + {"zrem",3,REDIS_CMD_BULK}, {"zrange",4,REDIS_CMD_INLINE}, {"zlen",2,REDIS_CMD_INLINE}, {"incrby",3,REDIS_CMD_INLINE}, diff --git a/redis.c b/redis.c index ee99792b..83318443 100644 --- a/redis.c +++ b/redis.c @@ -436,6 +436,7 @@ static void msetnxCommand(redisClient *c); static void zaddCommand(redisClient *c); static void zrangeCommand(redisClient *c); static void zlenCommand(redisClient *c); +static void zremCommand(redisClient *c); /*================================= Globals ================================= */ @@ -475,6 +476,7 @@ static struct redisCommand cmdTable[] = { {"sdiffstore",sdiffstoreCommand,-3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM}, {"smembers",sinterCommand,2,REDIS_CMD_INLINE}, {"zadd",zaddCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM}, + {"zrem",zremCommand,3,REDIS_CMD_BULK}, {"zrange",zrangeCommand,4,REDIS_CMD_INLINE}, {"zlen",zlenCommand,2,REDIS_CMD_INLINE}, {"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM}, @@ -3853,6 +3855,41 @@ static void zaddCommand(redisClient *c) { } } +static void zremCommand(redisClient *c) { + robj *zsetobj; + zset *zs; + + zsetobj = lookupKeyWrite(c->db,c->argv[1]); + if (zsetobj == NULL) { + addReply(c,shared.czero); + } else { + dictEntry *de; + double *oldscore; + int deleted; + + if (zsetobj->type != REDIS_ZSET) { + addReply(c,shared.wrongtypeerr); + return; + } + zs = zsetobj->ptr; + de = dictFind(zs->dict,c->argv[2]); + if (de == NULL) { + addReply(c,shared.czero); + return; + } + /* Delete from the skiplist */ + oldscore = dictGetEntryVal(de); + deleted = zslDelete(zs->zsl,*oldscore,c->argv[2]); + assert(deleted != 0); + + /* Delete from the hash table */ + dictDelete(zs->dict,c->argv[2]); + if (htNeedsResize(zs->dict)) dictResize(zs->dict); + server.dirty++; + addReply(c,shared.cone); + } +} + static void zrangeCommand(redisClient *c) { robj *o; int start = atoi(c->argv[2]->ptr); @@ -4980,6 +5017,7 @@ static struct redisFunctionSym symsTable[] = { {"createZsetObject",(unsigned long)createZsetObject}, {"zaddCommand",(unsigned long)zaddCommand}, {"zrangeCommand",(unsigned long)zrangeCommand}, +{"zremCommand",(unsigned long)zremCommand}, {NULL,0} };