Skip to content

Commit

Permalink
Remove ZCOUNT branches from generic RANGEBYSCORE code
Browse files Browse the repository at this point in the history
  • Loading branch information
pietern committed Oct 3, 2011
1 parent 62d774e commit 0cfc894
Showing 1 changed file with 55 additions and 46 deletions.
101 changes: 55 additions & 46 deletions src/t_zset.c
Original file line number Diff line number Diff line change
Expand Up @@ -1756,12 +1756,11 @@ void zrevrangeCommand(redisClient *c) {
zrangeGenericCommand(c,1);
}

/* This command implements ZRANGEBYSCORE, ZREVRANGEBYSCORE and ZCOUNT.
* If "justcount", only the number of elements in the range is returned. */
void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
/* This command implements ZRANGEBYSCORE, ZREVRANGEBYSCORE. */
void genericZrangebyscoreCommand(redisClient *c, int reverse) {
zrangespec range;
robj *key = c->argv[1];
robj *emptyreply, *zobj;
robj *zobj;
int offset = 0, limit = -1;
int withscores = 0;
unsigned long rangelen = 0;
Expand Down Expand Up @@ -1804,8 +1803,7 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
}

/* Ok, lookup the key and get the range */
emptyreply = justcount ? shared.czero : shared.emptymultibulk;
if ((zobj = lookupKeyReadOrReply(c,key,emptyreply)) == NULL ||
if ((zobj = lookupKeyReadOrReply(c,key,shared.emptymultibulk)) == NULL ||
checkType(c,zobj,REDIS_ZSET)) return;

if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
Expand All @@ -1817,14 +1815,15 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
double score;

/* If reversed, get the last node in range as starting point. */
if (reverse)
if (reverse) {
eptr = zzlLastInRange(zl,range);
else
} else {
eptr = zzlFirstInRange(zl,range);
}

/* No "first" element in the specified interval. */
if (eptr == NULL) {
addReply(c,emptyreply);
addReply(c, shared.emptymultibulk);
return;
}

Expand All @@ -1835,16 +1834,17 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
/* 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 */
if (!justcount)
replylen = addDeferredMultiBulkLength(c);
replylen = addDeferredMultiBulkLength(c);

/* If there is an offset, just traverse the number of elements without
* checking the score because that is done in the next loop. */
while (eptr && offset--)
if (reverse)
while (eptr && offset--) {
if (reverse) {
zzlPrev(zl,&eptr,&sptr);
else
} else {
zzlNext(zl,&eptr,&sptr);
}
}

while (eptr && limit--) {
score = zzlGetScore(sptr);
Expand All @@ -1856,52 +1856,59 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
if (!zslValueLteMax(score,&range)) break;
}

/* Do our magic */
/* We know the element exists, so ziplistGet should always succeed */
redisAssert(ziplistGet(eptr,&vstr,&vlen,&vlong));

rangelen++;
if (!justcount) {
redisAssert(ziplistGet(eptr,&vstr,&vlen,&vlong));
if (vstr == NULL)
addReplyBulkLongLong(c,vlong);
else
addReplyBulkCBuffer(c,vstr,vlen);

if (withscores)
addReplyDouble(c,score);
if (vstr == NULL) {
addReplyBulkLongLong(c,vlong);
} else {
addReplyBulkCBuffer(c,vstr,vlen);
}

if (withscores) {
addReplyDouble(c,score);
}

/* Move to next node */
if (reverse)
if (reverse) {
zzlPrev(zl,&eptr,&sptr);
else
} else {
zzlNext(zl,&eptr,&sptr);
}
}
} else if (zobj->encoding == REDIS_ENCODING_SKIPLIST) {
zset *zs = zobj->ptr;
zskiplist *zsl = zs->zsl;
zskiplistNode *ln;

/* If reversed, get the last node in range as starting point. */
if (reverse)
if (reverse) {
ln = zslLastInRange(zsl,range);
else
} else {
ln = zslFirstInRange(zsl,range);
}

/* No "first" element in the specified interval. */
if (ln == NULL) {
addReply(c,emptyreply);
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 */
if (!justcount)
replylen = addDeferredMultiBulkLength(c);
replylen = addDeferredMultiBulkLength(c);

/* If there is an offset, just traverse the number of elements without
* checking the score because that is done in the next loop. */
while (ln && offset--)
ln = reverse ? ln->backward : ln->level[0].forward;
while (ln && offset--) {
if (reverse) {
ln = ln->backward;
} else {
ln = ln->level[0].forward;
}
}

while (ln && limit--) {
/* Abort when the node is no longer in range. */
Expand All @@ -1911,35 +1918,37 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
if (!zslValueLteMax(ln->score,&range)) break;
}

/* Do our magic */
rangelen++;
if (!justcount) {
addReplyBulk(c,ln->obj);
if (withscores)
addReplyDouble(c,ln->score);
addReplyBulk(c,ln->obj);

if (withscores) {
addReplyDouble(c,ln->score);
}

/* Move to next node */
ln = reverse ? ln->backward : ln->level[0].forward;
if (reverse) {
ln = ln->backward;
} else {
ln = ln->level[0].forward;
}
}
} else {
redisPanic("Unknown sorted set encoding");
}

if (justcount) {
addReplyLongLong(c,(long)rangelen);
} else {
if (withscores) rangelen *= 2;
setDeferredMultiBulkLength(c,replylen,rangelen);
if (withscores) {
rangelen *= 2;
}

setDeferredMultiBulkLength(c, replylen, rangelen);
}

void zrangebyscoreCommand(redisClient *c) {
genericZrangebyscoreCommand(c,0,0);
genericZrangebyscoreCommand(c,0);
}

void zrevrangebyscoreCommand(redisClient *c) {
genericZrangebyscoreCommand(c,1,0);
genericZrangebyscoreCommand(c,1);
}

void zcountCommand(redisClient *c) {
Expand Down

0 comments on commit 0cfc894

Please sign in to comment.