Remove ZCOUNT branches from generic RANGEBYSCORE code

This commit is contained in:
Pieter Noordhuis 2011-10-03 14:23:31 +02:00
parent 62d774e5ba
commit 0cfc894066

View File

@ -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;
@ -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) {
@ -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;
}
@ -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);
@ -1856,24 +1856,26 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
if (!zslValueLteMax(score,&range)) break;
}
/* Do our magic */
rangelen++;
if (!justcount) {
redisAssert(ziplistGet(eptr,&vstr,&vlen,&vlong));
if (vstr == NULL)
addReplyBulkLongLong(c,vlong);
else
addReplyBulkCBuffer(c,vstr,vlen);
/* We know the element exists, so ziplistGet should always succeed */
redisAssert(ziplistGet(eptr,&vstr,&vlen,&vlong));
if (withscores)
addReplyDouble(c,score);
rangelen++;
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;
@ -1881,27 +1883,32 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse, int justcount) {
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. */
@ -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) {