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