MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / genericZrangebylexCommand

Function genericZrangebylexCommand

src/t_zset.cpp:3432–3544  ·  view source on GitHub ↗

This command implements ZRANGEBYLEX, ZREVRANGEBYLEX. */

Source from the content-addressed store, hash-verified

3430
3431/* This command implements ZRANGEBYLEX, ZREVRANGEBYLEX. */
3432void genericZrangebylexCommand(zrange_result_handler *handler,
3433 zlexrangespec *range, robj_roptr zobj, int withscores, long offset, long limit,
3434 int reverse)
3435{
3436 client *c = handler->client;
3437 unsigned long rangelen = 0;
3438
3439 handler->beginResultEmission(handler);
3440
3441 if (zobj->encoding == OBJ_ENCODING_ZIPLIST) {
3442 unsigned char *zl = (unsigned char*)zobj->m_ptr;
3443 unsigned char *eptr, *sptr;
3444 unsigned char *vstr;
3445 unsigned int vlen;
3446 long long vlong;
3447
3448 /* If reversed, get the last node in range as starting point. */
3449 if (reverse) {
3450 eptr = zzlLastInLexRange(zl,range);
3451 } else {
3452 eptr = zzlFirstInLexRange(zl,range);
3453 }
3454
3455 /* Get score pointer for the first element. */
3456 if (eptr)
3457 sptr = ziplistNext(zl,eptr);
3458
3459 /* If there is an offset, just traverse the number of elements without
3460 * checking the score because that is done in the next loop. */
3461 while (eptr && offset--) {
3462 if (reverse) {
3463 zzlPrev(zl,&eptr,&sptr);
3464 } else {
3465 zzlNext(zl,&eptr,&sptr);
3466 }
3467 }
3468
3469 while (eptr && limit--) {
3470 double score = 0;
3471 if (withscores) /* don't bother to extract the score if it's gonna be ignored. */
3472 score = zzlGetScore(sptr);
3473
3474 /* Abort when the node is no longer in range. */
3475 if (reverse) {
3476 if (!zzlLexValueGteMin(eptr,range)) break;
3477 } else {
3478 if (!zzlLexValueLteMax(eptr,range)) break;
3479 }
3480
3481 /* We know the element exists, so ziplistGet should always
3482 * succeed. */
3483 serverAssertWithInfo(c,zobj,ziplistGet(eptr,&vstr,&vlen,&vlong));
3484
3485 rangelen++;
3486 if (vstr == NULL) {
3487 handler->emitResultFromLongLong(handler, vlong, score);
3488 } else {
3489 handler->emitResultFromCBuffer(handler, vstr, vlen, score);

Callers 1

zrangeGenericCommandFunction · 0.85

Calls 15

zzlLastInLexRangeFunction · 0.85
zzlFirstInLexRangeFunction · 0.85
ziplistNextFunction · 0.85
zzlPrevFunction · 0.85
zzlNextFunction · 0.85
zzlGetScoreFunction · 0.85
zzlLexValueGteMinFunction · 0.85
zzlLexValueLteMaxFunction · 0.85
ziplistGetFunction · 0.85
zslLastInLexRangeFunction · 0.85
zslFirstInLexRangeFunction · 0.85
zslLexValueGteMinFunction · 0.85

Tested by

no test coverage detected