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