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; }
unsigned int GetKeysInSlot(unsigned int hashslot, robj **keys, unsigned int count) { zskiplistNode *n; zrangespec range; int j = 0; range.min = range.max = hashslot; range.minex = range.maxex = 0; n = zslFirstInRange(server.cluster.slots_to_keys, range); while(n && n->score == hashslot && count--) { keys[j++] = n->obj; n = n->level[0].forward; } return j; }
/* Pupulate the specified array of objects with keys in the specified slot. * New objects are returned to represent keys, it's up to the caller to * decrement the reference count to release the keys names. */ unsigned int getKeysInSlot(unsigned int hashslot, robj **keys, unsigned int count) { zskiplistNode *n; zrangespec range; int j = 0; range.min = range.max = hashslot; range.minex = range.maxex = 0; n = zslFirstInRange(server.cluster->slots_to_keys, &range); while(n && n->score == hashslot && count--) { keys[j++] = createStringObject(n->ele,sdslen(n->ele)); n = n->level[0].forward; } return j; }
/* Remove all the keys in the specified hash slot. * The number of removed items is returned. */ unsigned int delKeysInSlot(unsigned int hashslot) { zskiplistNode *n; zrangespec range; int j = 0; range.min = range.max = hashslot; range.minex = range.maxex = 0; n = zslFirstInRange(server.cluster->slots_to_keys, &range); while(n && n->score == hashslot) { robj *key = n->obj; n = n->level[0].forward; /* Go to the next item before freeing it. */ incrRefCount(key); /* Protect the object while freeing it. */ dbDelete(&server.db[0],key); decrRefCount(key); j++; } return j; }
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; }