| 3274 | } |
| 3275 | |
| 3276 | void zcountCommand(client *c) { |
| 3277 | robj *key = c->argv[1]; |
| 3278 | robj *zobj; |
| 3279 | zrangespec range; |
| 3280 | unsigned long count = 0; |
| 3281 | |
| 3282 | /* Parse the range arguments */ |
| 3283 | if (zslParseRange(c->argv[2],c->argv[3],&range) != C_OK) { |
| 3284 | addReplyError(c,"min or max is not a float"); |
| 3285 | return; |
| 3286 | } |
| 3287 | |
| 3288 | /* Lookup the sorted set */ |
| 3289 | if ((zobj = lookupKeyReadOrReply(c, key, shared.czero)) == NULL || |
| 3290 | checkType(c, zobj, OBJ_ZSET)) return; |
| 3291 | |
| 3292 | if (zobj->encoding == OBJ_ENCODING_ZIPLIST) { |
| 3293 | unsigned char *zl = zobj->ptr; |
| 3294 | unsigned char *eptr, *sptr; |
| 3295 | double score; |
| 3296 | |
| 3297 | /* Use the first element in range as the starting point */ |
| 3298 | eptr = zzlFirstInRange(zl,&range); |
| 3299 | |
| 3300 | /* No "first" element */ |
| 3301 | if (eptr == NULL) { |
| 3302 | addReply(c, shared.czero); |
| 3303 | return; |
| 3304 | } |
| 3305 | |
| 3306 | /* First element is in range */ |
| 3307 | sptr = ziplistNext(zl,eptr); |
| 3308 | score = zzlGetScore(sptr); |
| 3309 | serverAssertWithInfo(c,zobj,zslValueLteMax(score,&range)); |
| 3310 | |
| 3311 | /* Iterate over elements in range */ |
| 3312 | while (eptr) { |
| 3313 | score = zzlGetScore(sptr); |
| 3314 | |
| 3315 | /* Abort when the node is no longer in range. */ |
| 3316 | if (!zslValueLteMax(score,&range)) { |
| 3317 | break; |
| 3318 | } else { |
| 3319 | count++; |
| 3320 | zzlNext(zl,&eptr,&sptr); |
| 3321 | } |
| 3322 | } |
| 3323 | } else if (zobj->encoding == OBJ_ENCODING_SKIPLIST) { |
| 3324 | zset *zs = zobj->ptr; |
| 3325 | zskiplist *zsl = zs->zsl; |
| 3326 | zskiplistNode *zn; |
| 3327 | unsigned long rank; |
| 3328 | |
| 3329 | /* Find first element in range */ |
| 3330 | zn = zslFirstInRange(zsl, &range); |
| 3331 | |
| 3332 | /* Use rank of first element, if any, to determine preliminary count */ |
| 3333 | if (zn != NULL) { |
nothing calls this directly
no test coverage detected