Created
December 21, 2010 14:44
-
-
Save bohford/749997 to your computer and use it in GitHub Desktop.
ZPOP and ZREVPOP for Redis 2.2.0 series
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/help.h b/src/help.h | |
index 51613c9..196f90e 100644 | |
--- a/src/help.h | |
+++ b/src/help.h | |
@@ -632,7 +632,17 @@ struct commandHelp { | |
"destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]", | |
"Add multiple sorted sets and store the resulting sorted set in a new key", | |
4, | |
- "1.3.10" } | |
+ "1.3.10" }, | |
+ { "ZPOP", | |
+ "key [score]", | |
+ "Remove and get the highest ranked member of a sorted set", | |
+ 4, | |
+ "2.1.8" }, | |
+ { "ZREVPOP", | |
+ "key [score]", | |
+ "Remove and get the lowest ranked member of a sorted set", | |
+ 4, | |
+ "2.1.8" } | |
}; | |
#endif | |
diff --git a/src/redis.c b/src/redis.c | |
index 6e667f2..c0a77f1 100644 | |
--- a/src/redis.c | |
+++ b/src/redis.c | |
@@ -132,6 +132,8 @@ struct redisCommand readonlyCommandTable[] = { | |
{"zscore",zscoreCommand,3,0,NULL,1,1,1}, | |
{"zrank",zrankCommand,3,0,NULL,1,1,1}, | |
{"zrevrank",zrevrankCommand,3,0,NULL,1,1,1}, | |
+ {"zpop",zpopCommand,-2,0,NULL,1,1,1}, | |
+ {"zrevpop",zrevpopCommand,-2,0,NULL,1,1,1}, | |
{"hset",hsetCommand,4,REDIS_CMD_DENYOOM,NULL,1,1,1}, | |
{"hsetnx",hsetnxCommand,4,REDIS_CMD_DENYOOM,NULL,1,1,1}, | |
{"hget",hgetCommand,3,0,NULL,1,1,1}, | |
diff --git a/src/redis.h b/src/redis.h | |
index bc1a58c..9b6aae9 100644 | |
--- a/src/redis.h | |
+++ b/src/redis.h | |
@@ -998,6 +998,8 @@ void hlenCommand(redisClient *c); | |
void zremrangebyrankCommand(redisClient *c); | |
void zunionstoreCommand(redisClient *c); | |
void zinterstoreCommand(redisClient *c); | |
+void zpopCommand(redisClient *c); | |
+void zrevpopCommand(redisClient *c); | |
void hkeysCommand(redisClient *c); | |
void hvalsCommand(redisClient *c); | |
void hgetallCommand(redisClient *c); | |
diff --git a/src/t_zset.c b/src/t_zset.c | |
index 8139b53..7965320 100644 | |
--- a/src/t_zset.c | |
+++ b/src/t_zset.c | |
@@ -1058,3 +1058,59 @@ void zrankCommand(redisClient *c) { | |
void zrevrankCommand(redisClient *c) { | |
zrankGenericCommand(c, 1); | |
} | |
+ | |
+void zpopGenericCommand(redisClient *c, int reverse) { | |
+ robj *o; | |
+ zset *zs; | |
+ zskiplist *zsl; | |
+ zskiplistNode *ln; | |
+ int withminscore = 0; | |
+ double minscore; | |
+ | |
+ o = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk); | |
+ if (o == NULL || checkType(c,o,REDIS_ZSET)) return; | |
+ | |
+ if(c->argc == 3) { | |
+ withminscore = 1; | |
+ if (getDoubleFromObjectOrReply(c, c->argv[2], &minscore, NULL) != REDIS_OK) return; | |
+ } else if (c->argc > 3) { | |
+ addReply(c,shared.syntaxerr); | |
+ return; | |
+ } | |
+ | |
+ zs = o->ptr; | |
+ zsl = zs->zsl; | |
+ if (reverse) { | |
+ ln = zsl->header->level[0].forward; | |
+ } else { | |
+ ln = zsl->tail; | |
+ }; | |
+ | |
+ if (ln == NULL) { | |
+ addReply(c,shared.nullbulk); | |
+ } else if (withminscore && (reverse ? ln->score > minscore : ln->score < minscore)) { | |
+ addReply(c,shared.nullbulk); | |
+ } else { | |
+ addReplyBulk(c,ln->obj); | |
+ | |
+ long deleted; | |
+ deleted = zslDelete(zsl,ln->score,ln->obj); | |
+ redisAssert(deleted != 0); | |
+ | |
+ /* Delete from the hash table */ | |
+ dictDelete(zs->dict,ln->obj); | |
+ if (htNeedsResize(zs->dict)) dictResize(zs->dict); | |
+ if (dictSize(zs->dict) == 0) dbDelete(c->db,c->argv[1]); | |
+ | |
+ touchWatchedKey(c->db,c->argv[1]); | |
+ server.dirty++; | |
+ } | |
+} | |
+ | |
+void zpopCommand(redisClient *c) { | |
+ zpopGenericCommand(c, 0); | |
+} | |
+ | |
+void zrevpopCommand(redisClient *c) { | |
+ zpopGenericCommand(c, 1); | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment