From f24c63a292e045d4b14b82b25981f00a95c1767a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20S=C3=B6derqvist?= Date: Tue, 31 Aug 2021 08:25:36 +0200 Subject: Slot-to-keys using dict entry metadata (#9356) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enhance dict to support arbitrary metadata carried in dictEntry Co-authored-by: Viktor Söderqvist * Rewrite slot-to-keys mapping to linked lists using dict entry metadata This is a memory enhancement for Redis Cluster. The radix tree slots_to_keys (which duplicates all key names prefixed with their slot number) is replaced with a linked list for each slot. The dict entries of the same cluster slot form a linked list and the pointers are stored as metadata in each dict entry of the main DB dict. This commit also moves the slot-to-key API from db.c to cluster.c. Co-authored-by: Jim Brunner --- src/defrag.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/defrag.c') diff --git a/src/defrag.c b/src/defrag.c index c804af370..f5d56078d 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -34,6 +34,7 @@ */ #include "server.h" +#include "cluster.h" #include #include #include @@ -45,7 +46,7 @@ int je_get_defrag_hint(void* ptr); /* forward declarations*/ -void defragDictBucketCallback(void *privdata, dictEntry **bucketref); +void defragDictBucketCallback(dict *d, dictEntry **bucketref); dictEntry* replaceSatelliteDictKeyPtrAndOrDefragDictEntry(dict *d, sds oldkey, sds newkey, uint64_t hash, long *defragged); /* Defrag helper for generic allocations. @@ -895,12 +896,15 @@ void defragScanCallback(void *privdata, const dictEntry *de) { /* Defrag scan callback for each hash table bucket, * used in order to defrag the dictEntry allocations. */ -void defragDictBucketCallback(void *privdata, dictEntry **bucketref) { - UNUSED(privdata); /* NOTE: this function is also used by both activeDefragCycle and scanLaterHash, etc. don't use privdata */ +void defragDictBucketCallback(dict *d, dictEntry **bucketref) { while(*bucketref) { dictEntry *de = *bucketref, *newde; if ((newde = activeDefragAlloc(de))) { *bucketref = newde; + if (server.cluster_enabled && d == server.db[0].dict) { + /* Cluster keyspace dict. Update slot-to-entries mapping. */ + slotToKeyReplaceEntry(newde); + } } bucketref = &(*bucketref)->next; } -- cgit v1.2.1