Prehash the tombstone for cleanup

Former-commit-id: c9d97a7c7448fc769486175bea1648589487c87c
This commit is contained in:
John Sully 2020-08-14 16:05:39 +00:00
parent 85d7a4c1e2
commit 6c83ecbb48
5 changed files with 20 additions and 12 deletions

View File

@ -422,7 +422,8 @@ bool redisDbPersistentData::syncDelete(robj *key)
if (itr != nullptr) if (itr != nullptr)
{ {
sds keyTombstone = sdsdup(szFromObj(key)); 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); sdsfree(keyTombstone);
} }
} }
@ -2290,7 +2291,7 @@ void redisDbPersistentData::initialize()
{ {
m_pdbSnapshot = nullptr; m_pdbSnapshot = nullptr;
m_pdict = dictCreate(&dbDictType,this); m_pdict = dictCreate(&dbDictType,this);
m_pdictTombstone = dictCreate(&dbDictType,this); m_pdictTombstone = dictCreate(&dbDictTypeTombstone,this);
m_setexpire = new(MALLOC_LOCAL) expireset(); m_setexpire = new(MALLOC_LOCAL) expireset();
m_fAllChanged = 0; m_fAllChanged = 0;
m_fTrackingChanges = 0; m_fTrackingChanges = 0;
@ -2477,8 +2478,11 @@ void redisDbPersistentData::ensure(const char *sdsKey, dictEntry **pde)
{ {
dictAdd(m_pdict, keyNew, nullptr); dictAdd(m_pdict, keyNew, nullptr);
} }
*pde = dictFind(m_pdict, sdsKey); uint64_t hash = dictGetHash(m_pdict, sdsKey);
dictAdd(m_pdictTombstone, sdsdupshared(itr.key()), nullptr); dictEntry **deT;
dictht *ht;
*pde = dictFindWithPrev(m_pdict, sdsKey, hash, &deT, &ht);
dictAdd(m_pdictTombstone, sdsdupshared(itr.key()), (void*)hash);
} }
} }

View File

@ -326,7 +326,7 @@ int dictRehashMilliseconds(dict *d, int ms) {
static void _dictRehashStep(dict *d) { static void _dictRehashStep(dict *d) {
unsigned long iterators; unsigned long iterators;
__atomic_load(&d->iterators, &iterators, __ATOMIC_RELAXED); __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 */ /* Add an element to the target hash table */
@ -541,14 +541,13 @@ void dictRelease(dict *d)
zfree(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; dictEntry *he;
uint64_t h, idx, table; uint64_t idx, table;
if (dictSize(d) == 0) return NULL; /* dict is empty */ if (dictSize(d) == 0) return NULL; /* dict is empty */
if (dictIsRehashing(d)) _dictRehashStep(d); if (dictIsRehashing(d)) _dictRehashStep(d);
h = dictHashKey(d, key);
for (table = 0; table <= 1; table++) { for (table = 0; table <= 1; table++) {
*pht = d->ht + table; *pht = d->ht + table;
idx = h & d->ht[table].sizemask; idx = h & d->ht[table].sizemask;
@ -570,7 +569,8 @@ dictEntry *dictFind(dict *d, const void *key)
{ {
dictEntry **deT; dictEntry **deT;
dictht *ht; 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) { void *dictFetchValue(dict *d, const void *key) {

View File

@ -167,7 +167,7 @@ dictEntry *dictUnlink(dict *ht, const void *key);
void dictFreeUnlinkedEntry(dict *d, dictEntry *he); void dictFreeUnlinkedEntry(dict *d, dictEntry *he);
void dictRelease(dict *d); void dictRelease(dict *d);
dictEntry * dictFind(dict *d, const void *key); 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); void *dictFetchValue(dict *d, const void *key);
int dictResize(dict *d); int dictResize(dict *d);
dictIterator *dictGetIterator(dict *d); dictIterator *dictGetIterator(dict *d);

View File

@ -62,7 +62,10 @@ bool redisDbPersistentData::asyncDelete(robj *key) {
dictEntry *de = dictUnlink(m_pdict,ptrFromObj(key)); dictEntry *de = dictUnlink(m_pdict,ptrFromObj(key));
if (de) { if (de) {
if (m_pdbSnapshot != nullptr && m_pdbSnapshot->find_cached_threadsafe(szFromObj(key)) != nullptr) 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); robj *val = (robj*)dictGetVal(de);
if (val->FExpires()) if (val->FExpires())

View File

@ -70,6 +70,7 @@ const redisDbPersistentDataSnapshot *redisDbPersistentData::createSnapshot(uint6
auto spdb = std::unique_ptr<redisDbPersistentDataSnapshot>(new (MALLOC_LOCAL) redisDbPersistentDataSnapshot()); auto spdb = std::unique_ptr<redisDbPersistentDataSnapshot>(new (MALLOC_LOCAL) redisDbPersistentDataSnapshot());
dictRehashMilliseconds(m_pdict, 50); // Give us the best chance at a fast cleanup
spdb->m_fAllChanged = false; spdb->m_fAllChanged = false;
spdb->m_fTrackingChanges = 0; spdb->m_fTrackingChanges = 0;
spdb->m_pdict = m_pdict; spdb->m_pdict = m_pdict;
@ -303,7 +304,7 @@ void redisDbPersistentData::endSnapshot(const redisDbPersistentDataSnapshot *psn
{ {
dictEntry **dePrev; dictEntry **dePrev;
dictht *ht; 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) 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) // The tombstone is for a grand child, propogate it (or possibly in the storage provider - but an extra tombstone won't hurt)