diff --git a/src/module.c b/src/module.c index 0e7fedc1d..95995f1bf 100644 --- a/src/module.c +++ b/src/module.c @@ -1075,6 +1075,17 @@ RedisModuleString *RM_ZsetRangeCurrentElement(RedisModuleKey *key, double *score * does not include any item at all. */ int RM_ZsetRangeNext(RedisModuleKey *key) { if (!key->zr || !key->zcurrent) return 0; /* No active iterator. */ + zrangespec zrs; + + /* Convert to core range structure. */ + RedisModuleZsetRange *zr = key->zr; + if (zr->type == REDISMODULE_ZSET_RANGE_SCORE) { + zrs.min = zr->score_start; + zrs.max = zr->score_end; + zrs.minex = (zr->flags & REDISMODULE_ZSET_RANGE_START_EX) != 0; + zrs.maxex = (zr->flags & REDISMODULE_ZSET_RANGE_END_EX) != 0; + } + if (key->value->encoding == OBJ_ENCODING_ZIPLIST) { unsigned char *zl = key->value->ptr; unsigned char *eptr = key->zcurrent; @@ -1085,8 +1096,19 @@ int RM_ZsetRangeNext(RedisModuleKey *key) { key->zer = 1; return 0; } else { - /* TODO: check if we are in range. */ - key->zcurrent = next; + /* Fetch the next element score for the + * range check. */ + unsigned char *saved_next = next; + next = ziplistNext(zl,next); /* Skip next element. */ + double score = zzlGetScore(next); /* Obtain the next score. */ + /* Are we still within the range? */ + if (zr->type == REDISMODULE_ZSET_RANGE_SCORE && + !zslValueLteMax(score,&zrs)) + { + key->zer = 1; + return 0; + } + key->zcurrent = saved_next; return 1; } } else if (key->value->encoding == OBJ_ENCODING_SKIPLIST) { @@ -1095,7 +1117,13 @@ int RM_ZsetRangeNext(RedisModuleKey *key) { key->zer = 1; return 0; } else { - /* TODO: check if we are in range. */ + /* Are we still within the range? */ + if (zr->type == REDISMODULE_ZSET_RANGE_SCORE && + !zslValueLteMax(ln->score,&zrs)) + { + key->zer = 1; + return 0; + } key->zcurrent = next; return 1; } diff --git a/src/server.h b/src/server.h index 9cd8661fe..d6d1fd18e 100644 --- a/src/server.h +++ b/src/server.h @@ -1344,6 +1344,8 @@ int zsetAdd(robj *zobj, double score, sds ele, int *flags, double *newscore); long zsetRank(robj *zobj, sds ele, int reverse); int zsetDel(robj *zobj, sds ele); sds ziplistGetObject(unsigned char *sptr); +int zslValueGteMin(double value, zrangespec *spec); +int zslValueLteMax(double value, zrangespec *spec); /* Core functions */ int freeMemoryIfNeeded(void); diff --git a/src/t_zset.c b/src/t_zset.c index c65ec6d43..04c0b9fdd 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -244,7 +244,7 @@ int zslDelete(zskiplist *zsl, double score, sds ele, zskiplistNode **node) { return 0; /* not found */ } -static int zslValueGteMin(double value, zrangespec *spec) { +int zslValueGteMin(double value, zrangespec *spec) { return spec->minex ? (value > spec->min) : (value >= spec->min); }