#include <signal.h>
+void SlotToKeyAdd(robj *key);
+void SlotToKeyDel(robj *key);
+
/*-----------------------------------------------------------------------------
* C-level DB API
*----------------------------------------------------------------------------*/
sds copy = sdsdup(key->ptr);
dictAdd(db->dict, copy, val);
if (server.ds_enabled) cacheSetKeyMayExist(db,key);
+ if (server.cluster_enabled) SlotToKeyAdd(key);
return REDIS_OK;
}
}
if ((oldval = dictFetchValue(db->dict,key->ptr)) == NULL) {
sds copy = sdsdup(key->ptr);
dictAdd(db->dict, copy, val);
+ if (server.cluster_enabled) SlotToKeyAdd(key);
retval = 1;
} else {
dictReplace(db->dict, key->ptr, val);
/* Deleting an entry from the expires dict will not free the sds of
* the key, because it is shared with the main dictionary. */
if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);
- return dictDelete(db->dict,key->ptr) == DICT_OK;
+ if (dictDelete(db->dict,key->ptr) == DICT_OK) {
+ if (server.cluster_enabled) SlotToKeyDel(key);
+ return 1;
+ } else {
+ return 0;
+ }
}
/* Empty the whole database.
void selectCommand(redisClient *c) {
int id = atoi(c->argv[1]->ptr);
+ if (server.cluster_enabled && id != 0) {
+ addReplyError(c,"SELECT is not allowed in cluster mode");
+ return;
+ }
if (selectDb(c,id) == REDIS_ERR) {
addReplyError(c,"invalid DB index");
} else {
redisDb *src, *dst;
int srcid;
+ if (server.cluster_enabled) {
+ addReplyError(c,"MOVE is not allowed in cluster mode");
+ return;
+ }
+
/* Obtain source and target DB pointers */
src = c->db;
srcid = c->db->id;
*numkeys = num;
return keys;
}
+
+/* Slot to Key API. This is used by Redis Cluster in order to obtain in
+ * a fast way a key that belongs to a specified hash slot. This is useful
+ * while rehashing the cluster. */
+void SlotToKeyAdd(robj *key) {
+ unsigned int hashslot = keyHashSlot(key->ptr,sdslen(key->ptr));
+
+ zslInsert(server.cluster.slots_to_keys,hashslot,key);
+ incrRefCount(key);
+}
+
+void SlotToKeyDel(robj *key) {
+ unsigned int hashslot = keyHashSlot(key->ptr,sdslen(key->ptr));
+
+ zslDelete(server.cluster.slots_to_keys,hashslot,key);
+}
+
+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;
+}