Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
9212eafd
Commit
9212eafd
authored
Mar 04, 2010
by
Pieter Noordhuis
Browse files
implemented ZREMBYRANK
parent
94e543b5
Changes
2
Show whitespace changes
Inline
Side-by-side
redis.c
View file @
9212eafd
...
@@ -661,6 +661,7 @@ static void brpopCommand(redisClient *c);
...
@@ -661,6 +661,7 @@ static void brpopCommand(redisClient *c);
static void appendCommand(redisClient *c);
static void appendCommand(redisClient *c);
static void substrCommand(redisClient *c);
static void substrCommand(redisClient *c);
static void zrankCommand(redisClient *c);
static void zrankCommand(redisClient *c);
static void zremrangebyrankCommand(redisClient *c);
/*================================= Globals ================================= */
/*================================= Globals ================================= */
...
@@ -708,6 +709,7 @@ static struct redisCommand cmdTable[] = {
...
@@ -708,6 +709,7 @@ static struct redisCommand cmdTable[] = {
{"zincrby",zincrbyCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1},
{"zincrby",zincrbyCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM,1,1,1},
{"zrem",zremCommand,3,REDIS_CMD_BULK,1,1,1},
{"zrem",zremCommand,3,REDIS_CMD_BULK,1,1,1},
{"zremrangebyscore",zremrangebyscoreCommand,4,REDIS_CMD_INLINE,1,1,1},
{"zremrangebyscore",zremrangebyscoreCommand,4,REDIS_CMD_INLINE,1,1,1},
{"zremrangebyrank",zremrangebyrankCommand,4,REDIS_CMD_INLINE,1,1,1},
{"zrange",zrangeCommand,-4,REDIS_CMD_INLINE,1,1,1},
{"zrange",zrangeCommand,-4,REDIS_CMD_INLINE,1,1,1},
{"zrangebyscore",zrangebyscoreCommand,-4,REDIS_CMD_INLINE,1,1,1},
{"zrangebyscore",zrangebyscoreCommand,-4,REDIS_CMD_INLINE,1,1,1},
{"zcount",zcountCommand,4,REDIS_CMD_INLINE,1,1,1},
{"zcount",zcountCommand,4,REDIS_CMD_INLINE,1,1,1},
...
@@ -5052,6 +5054,61 @@ static unsigned long zslDeleteRange(zskiplist *zsl, double min, double max, dict
...
@@ -5052,6 +5054,61 @@ static unsigned long zslDeleteRange(zskiplist *zsl, double min, double max, dict
return removed; /* not found */
return removed; /* not found */
}
}
/* Delete all the elements with rank between start and end from the skiplist.
* Start and end are inclusive. */
static unsigned long zslDeleteRangeByRank(zskiplist *zsl, unsigned int start, unsigned int end, dict *dict) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
unsigned long traversed = 0, removed = 0;
int i;
/* start and end are given 0-based, but zsl uses 1-based
* ranks internally */
start++; end++;
x = zsl->header;
for (i = zsl->level-1; i >= 0; i--) {
while (x->forward[i] && (traversed + (i > 0 ? x->span[i-1] : 1)) < start) {
traversed += i > 0 ? x->span[i-1] : 1;
x = x->forward[i];
}
update[i] = x;
}
traversed++;
x = x->forward[0];
while (x && traversed <= end) {
zskiplistNode *next;
for (i = 0; i < zsl->level; i++) {
if (update[i]->forward[i] == x) {
if (i > 0) {
update[i]->span[i-1] += x->span[i-1] - 1;
}
update[i]->forward[i] = x->forward[i];
} else {
/* invariant: i > 0, because update[0]->forward[0]
* is always equal to x */
update[i]->span[i-1] -= 1;
}
}
if (x->forward[0]) {
x->forward[0]->backward = x->backward;
} else {
zsl->tail = x->backward;
}
next = x->forward[0];
dictDelete(dict,x->obj);
zslFreeNode(x);
while(zsl->level > 1 && zsl->header->forward[zsl->level-1] == NULL)
zsl->level--;
zsl->length--;
removed++;
traversed++;
x = next;
}
return removed;
}
/* Find the first node having a score equal or greater than the specified one.
/* Find the first node having a score equal or greater than the specified one.
* Returns NULL if there is no match. */
* Returns NULL if there is no match. */
static zskiplistNode *zslFirstWithScore(zskiplist *zsl, double score) {
static zskiplistNode *zslFirstWithScore(zskiplist *zsl, double score) {
...
@@ -5271,6 +5328,45 @@ static void zremrangebyscoreCommand(redisClient *c) {
...
@@ -5271,6 +5328,45 @@ static void zremrangebyscoreCommand(redisClient *c) {
}
}
}
}
static void zremrangebyrankCommand(redisClient *c) {
int start = atoi(c->argv[2]->ptr);
int end = atoi(c->argv[3]->ptr);
robj *zsetobj;
zset *zs;
zsetobj = lookupKeyWrite(c->db,c->argv[1]);
if (zsetobj == NULL) {
addReply(c,shared.czero);
} else {
if (zsetobj->type != REDIS_ZSET) {
addReply(c,shared.wrongtypeerr);
return;
}
zs = zsetobj->ptr;
int llen = zs->zsl->length;
long deleted;
/* convert negative indexes */
if (start < 0) start = llen+start;
if (end < 0) end = llen+end;
if (start < 0) start = 0;
if (end < 0) end = 0;
/* indexes sanity checks */
if (start > end || start >= llen) {
addReply(c,shared.czero);
return;
}
if (end >= llen) end = llen-1;
deleted = zslDeleteRangeByRank(zs->zsl,start,end,zs->dict);
if (htNeedsResize(zs->dict)) dictResize(zs->dict);
server.dirty += deleted;
addReplyLong(c, deleted);
}
}
static void zrangeGenericCommand(redisClient *c, int reverse) {
static void zrangeGenericCommand(redisClient *c, int reverse) {
robj *o;
robj *o;
int start = atoi(c->argv[2]->ptr);
int start = atoi(c->argv[2]->ptr);
...
...
test-redis.tcl
View file @
9212eafd
...
@@ -1442,7 +1442,7 @@ proc main {server port} {
...
@@ -1442,7 +1442,7 @@ proc main {server port} {
$r zrangebyscore zset 20 50 LIMIT 2 3 withscores
$r zrangebyscore zset 20 50 LIMIT 2 3 withscores
}
{
d 40 e 50
}
}
{
d 40 e 50
}
test
{
ZREMRANGE basics
}
{
test
{
ZREMRANGE
BYSCORE
basics
}
{
$r del zset
$r del zset
$r zadd zset 1 a
$r zadd zset 1 a
$r zadd zset 2 b
$r zadd zset 2 b
...
@@ -1452,7 +1452,7 @@ proc main {server port} {
...
@@ -1452,7 +1452,7 @@ proc main {server port} {
list
[
$r
zremrangebyscore zset 2 4
]
[
$r
zrange zset 0 -1
]
list
[
$r
zremrangebyscore zset 2 4
]
[
$r
zrange zset 0 -1
]
}
{
3
{
a e
}}
}
{
3
{
a e
}}
test
{
ZREMRANGE from -inf to +inf
}
{
test
{
ZREMRANGE
BYSCORE
from -inf to +inf
}
{
$r del zset
$r del zset
$r zadd zset 1 a
$r zadd zset 1 a
$r zadd zset 2 b
$r zadd zset 2 b
...
@@ -1462,6 +1462,16 @@ proc main {server port} {
...
@@ -1462,6 +1462,16 @@ proc main {server port} {
list
[
$r
zremrangebyscore zset -inf +inf
]
[
$r
zrange zset 0 -1
]
list
[
$r
zremrangebyscore zset -inf +inf
]
[
$r
zrange zset 0 -1
]
}
{
5
{}}
}
{
5
{}}
test
{
ZREMRANGEBYRANK basics
}
{
$r del zset
$r zadd zset 1 a
$r zadd zset 2 b
$r zadd zset 3 c
$r zadd zset 4 d
$r zadd zset 5 e
list
[
$r
zremrangebyrank zset 1 3
]
[
$r
zrange zset 0 -1
]
}
{
3
{
a e
}}
test
{
SORT against sorted sets
}
{
test
{
SORT against sorted sets
}
{
$r del zset
$r del zset
$r zadd zset 1 a
$r zadd zset 1 a
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment