From 6c83ecbb485dae2468a635469bbec7dba20e2c07 Mon Sep 17 00:00:00 2001 From: John Sully Date: Fri, 14 Aug 2020 16:05:39 +0000 Subject: [PATCH] Prehash the tombstone for cleanup Former-commit-id: c9d97a7c7448fc769486175bea1648589487c87c --- src/db.cpp | 12 ++++++++---- src/dict.cpp | 10 +++++----- src/dict.h | 2 +- src/lazyfree.cpp | 5 ++++- src/snapshot.cpp | 3 ++- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index b7b36b518..b91041f66 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -422,7 +422,8 @@ bool redisDbPersistentData::syncDelete(robj *key) if (itr != nullptr) { sds keyTombstone = sdsdup(szFromObj(key)); - if (dictAdd(m_pdictTombstone, keyTombstone, nullptr) != DICT_OK) + uint64_t hash = dictGetHash(m_pdict, keyTombstone); + if (dictAdd(m_pdictTombstone, keyTombstone, (void*)hash) != DICT_OK) sdsfree(keyTombstone); } } @@ -2290,7 +2291,7 @@ void redisDbPersistentData::initialize() { m_pdbSnapshot = nullptr; m_pdict = dictCreate(&dbDictType,this); - m_pdictTombstone = dictCreate(&dbDictType,this); + m_pdictTombstone = dictCreate(&dbDictTypeTombstone,this); m_setexpire = new(MALLOC_LOCAL) expireset(); m_fAllChanged = 0; m_fTrackingChanges = 0; @@ -2477,8 +2478,11 @@ void redisDbPersistentData::ensure(const char *sdsKey, dictEntry **pde) { dictAdd(m_pdict, keyNew, nullptr); } - *pde = dictFind(m_pdict, sdsKey); - dictAdd(m_pdictTombstone, sdsdupshared(itr.key()), nullptr); + uint64_t hash = dictGetHash(m_pdict, sdsKey); + dictEntry **deT; + dictht *ht; + *pde = dictFindWithPrev(m_pdict, sdsKey, hash, &deT, &ht); + dictAdd(m_pdictTombstone, sdsdupshared(itr.key()), (void*)hash); } } diff --git a/src/dict.cpp b/src/dict.cpp index ef7365fdb..c69c663a4 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -326,7 +326,7 @@ int dictRehashMilliseconds(dict *d, int ms) { static void _dictRehashStep(dict *d) { unsigned long iterators; __atomic_load(&d->iterators, &iterators, __ATOMIC_RELAXED); - if (iterators == 0) dictRehash(d,1); + if (iterators == 0) dictRehash(d,10); } /* Add an element to the target hash table */ @@ -541,14 +541,13 @@ void dictRelease(dict *d) zfree(d); } -dictEntry *dictFindWithPrev(dict *d, const void *key, dictEntry ***dePrevPtr, dictht **pht) +dictEntry *dictFindWithPrev(dict *d, const void *key, uint64_t h, dictEntry ***dePrevPtr, dictht **pht) { dictEntry *he; - uint64_t h, idx, table; + uint64_t idx, table; if (dictSize(d) == 0) return NULL; /* dict is empty */ if (dictIsRehashing(d)) _dictRehashStep(d); - h = dictHashKey(d, key); for (table = 0; table <= 1; table++) { *pht = d->ht + table; idx = h & d->ht[table].sizemask; @@ -570,7 +569,8 @@ dictEntry *dictFind(dict *d, const void *key) { dictEntry **deT; dictht *ht; - return dictFindWithPrev(d, key, &deT, &ht); + uint64_t h = dictHashKey(d, key); + return dictFindWithPrev(d, key, h, &deT, &ht); } void *dictFetchValue(dict *d, const void *key) { diff --git a/src/dict.h b/src/dict.h index c9118d35f..77ab832db 100644 --- a/src/dict.h +++ b/src/dict.h @@ -167,7 +167,7 @@ dictEntry *dictUnlink(dict *ht, const void *key); void dictFreeUnlinkedEntry(dict *d, dictEntry *he); void dictRelease(dict *d); dictEntry * dictFind(dict *d, const void *key); -dictEntry * dictFindWithPrev(dict *d, const void *key, dictEntry ***dePrevPtr, dictht **ht); +dictEntry * dictFindWithPrev(dict *d, const void *key, uint64_t h, dictEntry ***dePrevPtr, dictht **ht); void *dictFetchValue(dict *d, const void *key); int dictResize(dict *d); dictIterator *dictGetIterator(dict *d); diff --git a/src/lazyfree.cpp b/src/lazyfree.cpp index 1ee49103a..b5f341ed3 100644 --- a/src/lazyfree.cpp +++ b/src/lazyfree.cpp @@ -62,7 +62,10 @@ bool redisDbPersistentData::asyncDelete(robj *key) { dictEntry *de = dictUnlink(m_pdict,ptrFromObj(key)); if (de) { if (m_pdbSnapshot != nullptr && m_pdbSnapshot->find_cached_threadsafe(szFromObj(key)) != nullptr) - dictAdd(m_pdictTombstone, sdsdup((sds)dictGetKey(de)), nullptr); + { + uint64_t hash = dictGetHash(m_pdict, szFromObj(key)); + dictAdd(m_pdictTombstone, sdsdup((sds)dictGetKey(de)), (void*)hash); + } robj *val = (robj*)dictGetVal(de); if (val->FExpires()) diff --git a/src/snapshot.cpp b/src/snapshot.cpp index 0ad1b5282..8dd4db367 100644 --- a/src/snapshot.cpp +++ b/src/snapshot.cpp @@ -70,6 +70,7 @@ const redisDbPersistentDataSnapshot *redisDbPersistentData::createSnapshot(uint6 auto spdb = std::unique_ptr(new (MALLOC_LOCAL) redisDbPersistentDataSnapshot()); + dictRehashMilliseconds(m_pdict, 50); // Give us the best chance at a fast cleanup spdb->m_fAllChanged = false; spdb->m_fTrackingChanges = 0; spdb->m_pdict = m_pdict; @@ -303,7 +304,7 @@ void redisDbPersistentData::endSnapshot(const redisDbPersistentDataSnapshot *psn { dictEntry **dePrev; dictht *ht; - dictEntry *deSnapshot = dictFindWithPrev(m_spdbSnapshotHOLDER->m_pdict, dictGetKey(de), &dePrev, &ht); + dictEntry *deSnapshot = dictFindWithPrev(m_spdbSnapshotHOLDER->m_pdict, dictGetKey(de), (uint64_t)dictGetVal(de), &dePrev, &ht); if (deSnapshot == nullptr && m_spdbSnapshotHOLDER->m_pdbSnapshot) { // The tombstone is for a grand child, propogate it (or possibly in the storage provider - but an extra tombstone won't hurt)