This command implements ZRANGE, ZREVRANGE. */
| 3027 | |
| 3028 | /* This command implements ZRANGE, ZREVRANGE. */ |
| 3029 | void genericZrangebyrankCommand(zrange_result_handler *handler, |
| 3030 | robj_roptr zobj, long start, long end, int withscores, int reverse) { |
| 3031 | |
| 3032 | client *c = handler->client; |
| 3033 | long llen; |
| 3034 | long rangelen; |
| 3035 | size_t result_cardinality; |
| 3036 | |
| 3037 | /* Sanitize indexes. */ |
| 3038 | llen = zsetLength(zobj); |
| 3039 | if (start < 0) start = llen+start; |
| 3040 | if (end < 0) end = llen+end; |
| 3041 | if (start < 0) start = 0; |
| 3042 | |
| 3043 | handler->beginResultEmission(handler); |
| 3044 | |
| 3045 | /* Invariant: start >= 0, so this test will be true when end < 0. |
| 3046 | * The range is empty when start > end or start >= length. */ |
| 3047 | if (start > end || start >= llen) { |
| 3048 | handler->finalizeResultEmission(handler, 0); |
| 3049 | return; |
| 3050 | } |
| 3051 | if (end >= llen) end = llen-1; |
| 3052 | rangelen = (end-start)+1; |
| 3053 | result_cardinality = rangelen; |
| 3054 | |
| 3055 | if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { |
| 3056 | unsigned char *zl = (unsigned char*)zobj->m_ptr; |
| 3057 | unsigned char *eptr, *sptr; |
| 3058 | unsigned char *vstr; |
| 3059 | unsigned int vlen; |
| 3060 | long long vlong; |
| 3061 | double score = 0.0; |
| 3062 | |
| 3063 | if (reverse) |
| 3064 | eptr = ziplistIndex(zl,-2-(2*start)); |
| 3065 | else |
| 3066 | eptr = ziplistIndex(zl,2*start); |
| 3067 | |
| 3068 | serverAssertWithInfo(c,zobj,eptr != NULL); |
| 3069 | sptr = ziplistNext(zl,eptr); |
| 3070 | |
| 3071 | while (rangelen--) { |
| 3072 | serverAssertWithInfo(c,zobj,eptr != NULL && sptr != NULL); |
| 3073 | serverAssertWithInfo(c,zobj,ziplistGet(eptr,&vstr,&vlen,&vlong)); |
| 3074 | |
| 3075 | if (withscores) /* don't bother to extract the score if it's gonna be ignored. */ |
| 3076 | score = zzlGetScore(sptr); |
| 3077 | |
| 3078 | if (vstr == NULL) { |
| 3079 | handler->emitResultFromLongLong(handler, vlong, score); |
| 3080 | } else { |
| 3081 | handler->emitResultFromCBuffer(handler, vstr, vlen, score); |
| 3082 | } |
| 3083 | |
| 3084 | if (reverse) |
| 3085 | zzlPrev(zl,&eptr,&sptr); |
| 3086 | else |
no test coverage detected