From 484354ff95e6e1b93552ef9576422709a1c739c2 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 29 Apr 2011 16:17:58 +0200 Subject: [PATCH] CLUSTER GETKEYSINSLOT implemented --- src/cluster.c | 21 +++++++++++++++++++++ src/db.c | 10 +++++++--- src/redis.h | 1 + 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/cluster.c b/src/cluster.c index 6c43bbf8..5b747264 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -1209,6 +1209,27 @@ void clusterCommand(redisClient *c) { sds key = c->argv[2]->ptr; addReplyLongLong(c,keyHashSlot(key,sdslen(key))); + } else if (!strcasecmp(c->argv[1]->ptr,"getkeysinslot") && c->argc == 4) { + long long maxkeys, slot; + unsigned int numkeys; + int j; + robj **keys; + + if (getLongLongFromObjectOrReply(c,c->argv[2],&slot,NULL) != REDIS_OK) + return; + if (getLongLongFromObjectOrReply(c,c->argv[3],&maxkeys,NULL) != REDIS_OK) + return; + if (slot < 0 || slot >= REDIS_CLUSTER_SLOTS || maxkeys < 0 || + maxkeys > 1024*1024) { + addReplyError(c,"Invalid slot or number of keys"); + return; + } + + keys = zmalloc(sizeof(robj*)*maxkeys); + numkeys = GetKeysInSlot(slot, keys, maxkeys); + addReplyMultiBulkLen(c,numkeys); + for (j = 0; j < numkeys; j++) addReplyBulk(c,keys[j]); + zfree(keys); } else { addReplyError(c,"Wrong CLUSTER subcommand or number of arguments"); } diff --git a/src/db.c b/src/db.c index 7d323924..670e2bce 100644 --- a/src/db.c +++ b/src/db.c @@ -725,14 +725,18 @@ void SlotToKeyDel(robj *key) { zslDelete(server.cluster.slots_to_keys,hashslot,key); } -robj *GetKeyInSlot(unsigned int hashslot) { +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); - if (!n) return NULL; - return n->obj; + while(n && n->score == hashslot && count--) { + keys[j++] = n->obj; + n = n->level[0].forward; + } + return j; } diff --git a/src/redis.h b/src/redis.h index 0baa7d81..b6955805 100644 --- a/src/redis.h +++ b/src/redis.h @@ -1065,6 +1065,7 @@ long long emptyDb(); int selectDb(redisClient *c, int id); void signalModifiedKey(redisDb *db, robj *key); void signalFlushedDb(int dbid); +unsigned int GetKeysInSlot(unsigned int hashslot, robj **keys, unsigned int count); /* API to get key arguments from commands */ #define REDIS_GETKEYS_ALL 0 -- 2.45.2