This command implements ZRANGEBYSCORE, ZREVRANGEBYSCORE. */
| 3142 | |
| 3143 | /* This command implements ZRANGEBYSCORE, ZREVRANGEBYSCORE. */ |
| 3144 | void genericZrangebyscoreCommand(zrange_result_handler *handler, |
| 3145 | zrangespec *range, robj *zobj, long offset, long limit, |
| 3146 | int reverse) { |
| 3147 | |
| 3148 | client *c = handler->client; |
| 3149 | unsigned long rangelen = 0; |
| 3150 | |
| 3151 | handler->beginResultEmission(handler); |
| 3152 | |
| 3153 | /* For invalid offset, return directly. */ |
| 3154 | if (offset > 0 && offset >= (long)zsetLength(zobj)) { |
| 3155 | handler->finalizeResultEmission(handler, 0); |
| 3156 | return; |
| 3157 | } |
| 3158 | |
| 3159 | if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { |
| 3160 | unsigned char *zl = zobj->ptr; |
| 3161 | unsigned char *eptr, *sptr; |
| 3162 | unsigned char *vstr; |
| 3163 | unsigned int vlen; |
| 3164 | long long vlong; |
| 3165 | |
| 3166 | /* If reversed, get the last node in range as starting point. */ |
| 3167 | if (reverse) { |
| 3168 | eptr = zzlLastInRange(zl,range); |
| 3169 | } else { |
| 3170 | eptr = zzlFirstInRange(zl,range); |
| 3171 | } |
| 3172 | |
| 3173 | /* Get score pointer for the first element. */ |
| 3174 | if (eptr) |
| 3175 | sptr = ziplistNext(zl,eptr); |
| 3176 | |
| 3177 | /* If there is an offset, just traverse the number of elements without |
| 3178 | * checking the score because that is done in the next loop. */ |
| 3179 | while (eptr && offset--) { |
| 3180 | if (reverse) { |
| 3181 | zzlPrev(zl,&eptr,&sptr); |
| 3182 | } else { |
| 3183 | zzlNext(zl,&eptr,&sptr); |
| 3184 | } |
| 3185 | } |
| 3186 | |
| 3187 | while (eptr && limit--) { |
| 3188 | double score = zzlGetScore(sptr); |
| 3189 | |
| 3190 | /* Abort when the node is no longer in range. */ |
| 3191 | if (reverse) { |
| 3192 | if (!zslValueGteMin(score,range)) break; |
| 3193 | } else { |
| 3194 | if (!zslValueLteMax(score,range)) break; |
| 3195 | } |
| 3196 | |
| 3197 | /* We know the element exists, so ziplistGet should always |
| 3198 | * succeed */ |
| 3199 | serverAssertWithInfo(c,zobj,ziplistGet(eptr,&vstr,&vlen,&vlong)); |
| 3200 | |
| 3201 | rangelen++; |
no test coverage detected