From 81c353e56931aecad9457b9b6cfa5d24d699a8e7 Mon Sep 17 00:00:00 2001 From: Pawel Karpinski Date: Tue, 11 Feb 2020 10:23:07 -0500 Subject: [PATCH] Move dictEntry to PM dictEntry instances will be allocated to PM. Involves dictionary entries created using DB API (db.c) --- src/db.c | 10 +++++++--- src/dict.c | 24 ++++++++++++++++++------ src/dict.h | 7 +++++-- src/expire.c | 2 +- src/sentinel.c | 2 +- src/t_set.c | 2 +- src/t_zset.c | 2 +- 7 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/db.c b/src/db.c index ee8ead52fc8..c62486d0631 100644 --- a/src/db.c +++ b/src/db.c @@ -177,12 +177,16 @@ robj *lookupKeyWriteOrReply(client *c, robj *key, robj *reply) { * * The program is aborted if the key already exists. */ void dbAdd(redisDb *db, robj *key, robj *val) { - sds copy; + sds copy = NULL; if (server.keys_on_pmem) copy = sdsdupPM(key->ptr); else copy = sdsdup(key->ptr); - int retval = dictAdd(db->dict, copy, val); + int retval = 0; + if (server.dictionary_entries_on_pmem) + retval = dictAddPM(db->dict, copy, val); + else + retval = dictAdd(db->dict, copy, val); serverAssertWithInfo(NULL,key,retval == DICT_OK); if (val->type == OBJ_LIST || @@ -1167,7 +1171,7 @@ void setExpire(client *c, redisDb *db, robj *key, long long when) { /* Reuse the sds from the main dict in the expire dict */ kde = dictFind(db->dict,key->ptr); serverAssertWithInfo(NULL,key,kde != NULL); - de = dictAddOrFind(db->expires,dictGetKey(kde)); + de = dictAddOrFind(db->expires,dictGetKey(kde),server.dictionary_entries_on_pmem); dictSetSignedIntegerVal(de,when); int writable_slave = server.masterhost && server.repl_slave_ro == 0; diff --git a/src/dict.c b/src/dict.c index 106467ef712..08d9bc76416 100644 --- a/src/dict.c +++ b/src/dict.c @@ -264,7 +264,16 @@ static void _dictRehashStep(dict *d) { /* Add an element to the target hash table */ int dictAdd(dict *d, void *key, void *val) { - dictEntry *entry = dictAddRaw(d,key,NULL); + dictEntry *entry = dictAddRaw(d,key,NULL,DICT_ENTRIES_ON_DRAM); + + if (!entry) return DICT_ERR; + dictSetVal(d, entry, val); + return DICT_OK; +} + +int dictAddPM(dict *d, void *key, void *val) +{ + dictEntry *entry = dictAddRaw(d,key,NULL,DICT_ENTRIES_ON_PMEM); if (!entry) return DICT_ERR; dictSetVal(d, entry, val); @@ -289,7 +298,7 @@ int dictAdd(dict *d, void *key, void *val) * * If key was added, the hash entry is returned to be manipulated by the caller. */ -dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing) +dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing, int dictionaryEntriesOnPmem) { long index; dictEntry *entry; @@ -307,7 +316,10 @@ dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing) * system it is more likely that recently added entries are accessed * more frequently. */ ht = dictIsRehashing(d) ? &d->ht[1] : &d->ht[0]; - entry = zmalloc(sizeof(*entry)); + if (dictionaryEntriesOnPmem) + entry = zmalloc_pmem(sizeof(*entry)); + else + entry = zmalloc(sizeof(*entry)); entry->next = ht->table[index]; ht->table[index] = entry; ht->used++; @@ -328,7 +340,7 @@ int dictReplace(dict *d, void *key, void *val) /* Try to add the element. If the key * does not exists dictAdd will succeed. */ - entry = dictAddRaw(d,key,&existing); + entry = dictAddRaw(d,key,&existing,DICT_ENTRIES_ON_DRAM); if (entry) { dictSetVal(d, entry, val); return 1; @@ -352,9 +364,9 @@ int dictReplace(dict *d, void *key, void *val) * existing key is returned.) * * See dictAddRaw() for more information. */ -dictEntry *dictAddOrFind(dict *d, void *key) { +dictEntry *dictAddOrFind(dict *d, void *key, int dictionaryEntriesOnPmem) { dictEntry *entry, *existing; - entry = dictAddRaw(d,key,&existing); + entry = dictAddRaw(d,key,&existing,dictionaryEntriesOnPmem); return entry ? entry : existing; } diff --git a/src/dict.h b/src/dict.h index dec60f6373c..34dd0a51097 100644 --- a/src/dict.h +++ b/src/dict.h @@ -40,6 +40,8 @@ #define DICT_OK 0 #define DICT_ERR 1 +#define DICT_ENTRIES_ON_DRAM 0 +#define DICT_ENTRIES_ON_PMEM 1 /* Unused arguments generate annoying warnings... */ #define DICT_NOTUSED(V) ((void) V) @@ -151,8 +153,9 @@ typedef void (dictScanBucketFunction)(void *privdata, dictEntry **bucketref); dict *dictCreate(dictType *type, void *privDataPtr); int dictExpand(dict *d, unsigned long size); int dictAdd(dict *d, void *key, void *val); -dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing); -dictEntry *dictAddOrFind(dict *d, void *key); +int dictAddPM(dict *d, void *key, void *val); +dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing, int dictionaryEntriesOnPmem); +dictEntry *dictAddOrFind(dict *d, void *key, int dictionaryEntriesOnPmem); int dictReplace(dict *d, void *key, void *val); int dictDelete(dict *d, const void *key); dictEntry *dictUnlink(dict *ht, const void *key); diff --git a/src/expire.c b/src/expire.c index 5aff72ee09d..3755d2012fc 100644 --- a/src/expire.c +++ b/src/expire.c @@ -439,7 +439,7 @@ void rememberSlaveKeyWithExpire(redisDb *db, robj *key) { } if (db->id > 63) return; - dictEntry *de = dictAddOrFind(slaveKeysWithExpire,key->ptr); + dictEntry *de = dictAddOrFind(slaveKeysWithExpire,key->ptr,DICT_ENTRIES_ON_DRAM); /* If the entry was just created, set it to a copy of the SDS string * representing the key: we don't want to need to take those keys * in sync with the main DB. The keys will be removed by expireSlaveKeys() diff --git a/src/sentinel.c b/src/sentinel.c index 10c003d03f2..10e171d1164 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -3853,7 +3853,7 @@ int sentinelLeaderIncr(dict *counters, char *runid) { dictEntry *existing, *de; uint64_t oldval; - de = dictAddRaw(counters,runid,&existing); + de = dictAddRaw(counters,runid,&existing,DICT_ENTRIES_ON_DRAM); if (existing) { oldval = dictGetUnsignedIntegerVal(existing); dictSetUnsignedIntegerVal(existing,oldval+1); diff --git a/src/t_set.c b/src/t_set.c index abbf82fde2d..f70f72bf1a9 100644 --- a/src/t_set.c +++ b/src/t_set.c @@ -53,7 +53,7 @@ int setTypeAdd(robj *subject, sds value) { long long llval; if (subject->encoding == OBJ_ENCODING_HT) { dict *ht = subject->ptr; - dictEntry *de = dictAddRaw(ht,value,NULL); + dictEntry *de = dictAddRaw(ht,value,NULL,DICT_ENTRIES_ON_DRAM); if (de) { dictSetKey(ht,de,sdsdup(value)); dictSetVal(ht,de,NULL); diff --git a/src/t_zset.c b/src/t_zset.c index ea6f4b848cf..aa6b3f59854 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -2332,7 +2332,7 @@ void zunionInterGenericCommand(client *c, robj *dstkey, int op) { if (isnan(score)) score = 0; /* Search for this element in the accumulating dictionary. */ - de = dictAddRaw(accumulator,zuiSdsFromValue(&zval),&existing); + de = dictAddRaw(accumulator,zuiSdsFromValue(&zval),&existing,DICT_ENTRIES_ON_DRAM); /* If we don't have it, we need to create a new entry. */ if (!existing) { tmp = zuiNewSdsFromValue(&zval);