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
50c55df5
Commit
50c55df5
authored
Oct 26, 2009
by
antirez
Browse files
ZRANGEBYSCORE implemented. Redis got range queries!
parent
9d60e6e4
Changes
2
Show whitespace changes
Inline
Side-by-side
redis-cli.c
View file @
50c55df5
...
@@ -92,6 +92,7 @@ static struct redisCommand cmdTable[] = {
...
@@ -92,6 +92,7 @@ static struct redisCommand cmdTable[] = {
{
"zadd"
,
4
,
REDIS_CMD_BULK
},
{
"zadd"
,
4
,
REDIS_CMD_BULK
},
{
"zrem"
,
3
,
REDIS_CMD_BULK
},
{
"zrem"
,
3
,
REDIS_CMD_BULK
},
{
"zrange"
,
4
,
REDIS_CMD_INLINE
},
{
"zrange"
,
4
,
REDIS_CMD_INLINE
},
{
"zrangebyscore"
,
4
,
REDIS_CMD_INLINE
},
{
"zrevrange"
,
4
,
REDIS_CMD_INLINE
},
{
"zrevrange"
,
4
,
REDIS_CMD_INLINE
},
{
"zlen"
,
2
,
REDIS_CMD_INLINE
},
{
"zlen"
,
2
,
REDIS_CMD_INLINE
},
{
"incrby"
,
3
,
REDIS_CMD_INLINE
},
{
"incrby"
,
3
,
REDIS_CMD_INLINE
},
...
...
redis.c
View file @
50c55df5
...
@@ -444,6 +444,7 @@ static void msetCommand(redisClient *c);
...
@@ -444,6 +444,7 @@ static void msetCommand(redisClient *c);
static void msetnxCommand(redisClient *c);
static void msetnxCommand(redisClient *c);
static void zaddCommand(redisClient *c);
static void zaddCommand(redisClient *c);
static void zrangeCommand(redisClient *c);
static void zrangeCommand(redisClient *c);
static void zrangebyscoreCommand(redisClient *c);
static void zrevrangeCommand(redisClient *c);
static void zrevrangeCommand(redisClient *c);
static void zlenCommand(redisClient *c);
static void zlenCommand(redisClient *c);
static void zremCommand(redisClient *c);
static void zremCommand(redisClient *c);
...
@@ -488,6 +489,7 @@ static struct redisCommand cmdTable[] = {
...
@@ -488,6 +489,7 @@ static struct redisCommand cmdTable[] = {
{"zadd",zaddCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
{"zadd",zaddCommand,4,REDIS_CMD_BULK|REDIS_CMD_DENYOOM},
{"zrem",zremCommand,3,REDIS_CMD_BULK},
{"zrem",zremCommand,3,REDIS_CMD_BULK},
{"zrange",zrangeCommand,4,REDIS_CMD_INLINE},
{"zrange",zrangeCommand,4,REDIS_CMD_INLINE},
{"zrangebyscore",zrangebyscoreCommand,4,REDIS_CMD_INLINE},
{"zrevrange",zrevrangeCommand,4,REDIS_CMD_INLINE},
{"zrevrange",zrevrangeCommand,4,REDIS_CMD_INLINE},
{"zlen",zlenCommand,2,REDIS_CMD_INLINE},
{"zlen",zlenCommand,2,REDIS_CMD_INLINE},
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
{"incrby",incrbyCommand,3,REDIS_CMD_INLINE|REDIS_CMD_DENYOOM},
...
@@ -3885,6 +3887,7 @@ static void zslInsert(zskiplist *zsl, double score, robj *obj) {
...
@@ -3885,6 +3887,7 @@ static void zslInsert(zskiplist *zsl, double score, robj *obj) {
zsl->length++;
zsl->length++;
}
}
/* Delete an element with matching score/object from the skiplist. */
static int zslDelete(zskiplist *zsl, double score, robj *obj) {
static int zslDelete(zskiplist *zsl, double score, robj *obj) {
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
int i;
int i;
...
@@ -3901,7 +3904,7 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) {
...
@@ -3901,7 +3904,7 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) {
/* We may have multiple elements with the same score, what we need
/* We may have multiple elements with the same score, what we need
* is to find the element with both the right score and object. */
* is to find the element with both the right score and object. */
x = x->forward[0];
x = x->forward[0];
if
(
compareStringObjects
(
x
->
obj
,
obj
)
==
0
)
{
if (
x && score == x->score &&
compareStringObjects(x->obj,obj) == 0) {
for (i = 0; i < zsl->level; i++) {
for (i = 0; i < zsl->level; i++) {
if (update[i]->forward[i] != x) break;
if (update[i]->forward[i] != x) break;
update[i]->forward[i] = x->forward[i];
update[i]->forward[i] = x->forward[i];
...
@@ -3923,6 +3926,22 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) {
...
@@ -3923,6 +3926,22 @@ static int zslDelete(zskiplist *zsl, double score, robj *obj) {
return 0; /* not found */
return 0; /* not found */
}
}
/* Find the first node having a score equal or greater than the specified one.
* Returns NULL if there is no match. */
static zskiplistNode *zslFirstWithScore(zskiplist *zsl, double score) {
zskiplistNode *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];
}
/* We may have multiple elements with the same score, what we need
* is to find the element with both the right score and object. */
return x->forward[0];
}
/* The actual Z-commands implementations */
/* The actual Z-commands implementations */
static void zaddCommand(redisClient *c) {
static void zaddCommand(redisClient *c) {
...
@@ -4076,6 +4095,52 @@ static void zrevrangeCommand(redisClient *c) {
...
@@ -4076,6 +4095,52 @@ static void zrevrangeCommand(redisClient *c) {
zrangeGenericCommand(c,1);
zrangeGenericCommand(c,1);
}
}
static void zrangebyscoreCommand(redisClient *c) {
robj *o;
double min = strtod(c->argv[2]->ptr,NULL);
double max = strtod(c->argv[3]->ptr,NULL);
o = lookupKeyRead(c->db,c->argv[1]);
if (o == NULL) {
addReply(c,shared.nullmultibulk);
} else {
if (o->type != REDIS_ZSET) {
addReply(c,shared.wrongtypeerr);
} else {
zset *zsetobj = o->ptr;
zskiplist *zsl = zsetobj->zsl;
zskiplistNode *ln;
robj *ele, *lenobj;
unsigned int rangelen = 0;
/* Get the first node with the score >= min */
ln = zslFirstWithScore(zsl,min);
if (ln == NULL) {
/* No element matching the speciifed interval */
addReply(c,shared.emptymultibulk);
return;
}
/* We don't know in advance how many matching elements there
* are in the list, so we push this object that will represent
* the multi-bulk length in the output buffer, and will "fix"
* it later */
lenobj = createObject(REDIS_STRING,NULL);
addReply(c,lenobj);
while(ln->score <= max) {
ele = ln->obj;
addReplyBulkLen(c,ele);
addReply(c,ele);
addReply(c,shared.crlf);
ln = ln->forward[0];
rangelen++;
}
lenobj->ptr = sdscatprintf(sdsempty(),"*%d\r\n",rangelen);
}
}
}
static void zlenCommand(redisClient *c) {
static void zlenCommand(redisClient *c) {
robj *o;
robj *o;
zset *zs;
zset *zs;
...
...
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