unsigned int countKeysInSlot(unsigned int hashslot) { zskiplist *zsl = server.cluster->slots_to_keys; zskiplistNode *zn; zrangespec range; int rank, count = 0; range.min = range.max = hashslot; range.minex = range.maxex = 0; /* Find first element in range */ zn = zslFirstInRange(zsl, &range); /* Use rank of first element, if any, to determine preliminary count */ if (zn != NULL) { rank = zslGetRank(zsl, zn->score, zn->obj); count = (zsl->length - (rank - 1)); /* Find last element in range */ zn = zslLastInRange(zsl, &range); /* Use rank of last element, if any, to determine the actual count */ if (zn != NULL) { rank = zslGetRank(zsl, zn->score, zn->obj); count -= (zsl->length - rank); } } return count; }
void zrankGenericCommand(redisClient *c, int reverse) { robj *o; zset *zs; zskiplist *zsl; dictEntry *de; unsigned long rank; double *score; if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || checkType(c,o,REDIS_ZSET)) return; zs = o->ptr; zsl = zs->zsl; c->argv[2] = tryObjectEncoding(c->argv[2]); de = dictFind(zs->dict,c->argv[2]); if (!de) { addReply(c,shared.nullbulk); return; } score = dictGetEntryVal(de); rank = zslGetRank(zsl, *score, c->argv[2]); if (rank) { if (reverse) { addReplyLongLong(c, zsl->length - rank); } else { addReplyLongLong(c, rank-1); } } else { addReply(c,shared.nullbulk); } }
int main(void) { int i; struct timeval start, end; int *key = malloc(N * sizeof(int)); if (key == NULL) { exit(-1); } zskiplist *zsl = zslCreate(); if (zsl == NULL) { exit(-1); } printf("Test start!\n"); printf("Add %d nodes...\n", N); /* Insert test */ srandom(time(NULL)); gettimeofday(&start, NULL); for (i = 0; i < N; i++) { key[i] = (int)random(); zslInsert(zsl, key[i]); } gettimeofday(&end, NULL); printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000); /* Search test 1 */ printf("Now search each node by key...\n"); gettimeofday(&start, NULL); for (i = 0; i < N; i++) { zrangespec range; range.min = range.max = key[i]; range.minex = range.maxex = 0; zskiplistNode *zn = zslFirstInRange(zsl, &range); if (zn != NULL) { #ifdef SKIPLIST_DEBUG printf("key:0x%08x\n", zn->score); #endif } else { printf("Not found:0x%08x\n", key[i]); } #ifdef SKIPLIST_DEBUG printf("key rank:%ld\n", zslGetRank(zsl, key[i])); #else zslGetRank(zsl, key[i]); #endif } gettimeofday(&end, NULL); printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000); /* Search test 2 */ printf("Now search each node by rank...\n"); gettimeofday(&start, NULL); for (i = 0; i < N; i++) { zskiplistNode* zn = zslGetElementByRank(zsl, i + 1); if (zn != NULL) { #ifdef SKIPLIST_DEBUG printf("key:0x%08x\n", zn->score); #endif } else { printf("Not found:%d\n", i + 1); } } gettimeofday(&end, NULL); printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000); /* Delete test */ printf("Now remove all nodes...\n"); gettimeofday(&start, NULL); for (i = 0; i < N; i++) { zslDelete(zsl, key[i]); } gettimeofday(&end, NULL); printf("time span: %ldms\n", (end.tv_sec - start.tv_sec)*1000 + (end.tv_usec - start.tv_usec)/1000); printf("End of Test.\n"); zslFree(zsl); return 0; }