Cluster: use O(log(N)) algo for countKeysInSlot().

This commit is contained in:
antirez 2013-02-25 12:37:50 +01:00
parent d4fa40655d
commit 996a643752
2 changed files with 23 additions and 8 deletions

View File

@ -780,17 +780,30 @@ unsigned int getKeysInSlot(unsigned int hashslot, robj **keys, unsigned int coun
} }
unsigned int countKeysInSlot(unsigned int hashslot) { unsigned int countKeysInSlot(unsigned int hashslot) {
zskiplistNode *n; zskiplist *zsl = server.cluster->slots_to_keys;
zskiplistNode *zn;
zrangespec range; zrangespec range;
int j = 0; int rank, count = 0;
range.min = range.max = hashslot; range.min = range.max = hashslot;
range.minex = range.maxex = 0; range.minex = range.maxex = 0;
n = zslFirstInRange(server.cluster->slots_to_keys, range); /* Find first element in range */
while(n && n->score == hashslot) { zn = zslFirstInRange(zsl, range);
j++;
n = n->level[0].forward; /* 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 j; return count;
} }

View File

@ -1129,11 +1129,13 @@ zskiplistNode *zslInsert(zskiplist *zsl, double score, robj *obj);
unsigned char *zzlInsert(unsigned char *zl, robj *ele, double score); unsigned char *zzlInsert(unsigned char *zl, robj *ele, double score);
int zslDelete(zskiplist *zsl, double score, robj *obj); int zslDelete(zskiplist *zsl, double score, robj *obj);
zskiplistNode *zslFirstInRange(zskiplist *zsl, zrangespec range); zskiplistNode *zslFirstInRange(zskiplist *zsl, zrangespec range);
zskiplistNode *zslLastInRange(zskiplist *zsl, zrangespec range);
double zzlGetScore(unsigned char *sptr); double zzlGetScore(unsigned char *sptr);
void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr); void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr); void zzlPrev(unsigned char *zl, unsigned char **eptr, unsigned char **sptr);
unsigned int zsetLength(robj *zobj); unsigned int zsetLength(robj *zobj);
void zsetConvert(robj *zobj, int encoding); void zsetConvert(robj *zobj, int encoding);
unsigned long zslGetRank(zskiplist *zsl, double score, robj *o);
/* Core functions */ /* Core functions */
int freeMemoryIfNeeded(void); int freeMemoryIfNeeded(void);