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)
{
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);
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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())

View File

@ -70,6 +70,7 @@ const redisDbPersistentDataSnapshot *redisDbPersistentData::createSnapshot(uint6
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_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)