From cfa9ba8eb1ee4832b36b8facb65497b910093f23 Mon Sep 17 00:00:00 2001 From: John Sully Date: Wed, 27 Apr 2022 17:32:40 +0000 Subject: [PATCH] Ensure we are responsive during storagecache clears --- src/StorageCache.cpp | 18 ++++++++++++++++-- src/StorageCache.h | 3 ++- src/db.cpp | 4 ++-- src/lazyfree.cpp | 2 +- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/StorageCache.cpp b/src/StorageCache.cpp index 2c6dd42b9..d336e2b3d 100644 --- a/src/StorageCache.cpp +++ b/src/StorageCache.cpp @@ -31,11 +31,25 @@ StorageCache::~StorageCache() dictRelease(m_pdict); } -void StorageCache::clear() +void StorageCache::clear(void(callback)(void*)) { std::unique_lock ul(m_lock); if (m_pdict != nullptr) - dictEmpty(m_pdict, nullptr); + dictEmpty(m_pdict, callback); + m_spstorage->clear(); + m_collisionCount = 0; +} + +void StorageCache::clearAsync() +{ + std::unique_lock ul(m_lock); + if (m_pdict != nullptr) { + dict *dSav = m_pdict; + m_pdict = dictCreate(&dbStorageCacheType, nullptr); + g_pserver->asyncworkqueue->AddWorkFunction([dSav]{ + dictEmpty(dSav, nullptr); + }); + } m_spstorage->clear(); m_collisionCount = 0; } diff --git a/src/StorageCache.h b/src/StorageCache.h index 879b512dc..3c38450fb 100644 --- a/src/StorageCache.h +++ b/src/StorageCache.h @@ -38,7 +38,8 @@ public: return cache; } - void clear(); + void clear(void(callback)(void*)); + void clearAsync(); void insert(sds key, const void *data, size_t cbdata, bool fOverwrite); void bulkInsert(char **rgkeys, size_t *rgcbkeys, char **rgvals, size_t *rgcbvals, size_t celem); void retrieve(sds key, IStorage::callbackSingle fn) const; diff --git a/src/db.cpp b/src/db.cpp index a115c887b..5b67a4198 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -2706,7 +2706,7 @@ void redisDbPersistentData::clear(void(callback)(void*)) delete m_setexpire; m_setexpire = new (MALLOC_LOCAL) expireset(); if (m_spstorage != nullptr) - m_spstorage->clear(); + m_spstorage->clear(callback); dictEmpty(m_pdictTombstone,callback); m_pdbSnapshot = nullptr; } @@ -2926,7 +2926,7 @@ bool redisDbPersistentData::processChanges(bool fSnapshot) if (m_fAllChanged) { if (dictSize(m_pdict) > 0 || m_spstorage->count() > 0) { // in some cases we may have pre-sized the StorageCache's dict, and we don't want clear to ruin it - m_spstorage->clear(); + m_spstorage->clearAsync(); storeDatabase(); } m_fAllChanged = 0; diff --git a/src/lazyfree.cpp b/src/lazyfree.cpp index a05101f2e..fe76b2f4a 100644 --- a/src/lazyfree.cpp +++ b/src/lazyfree.cpp @@ -223,7 +223,7 @@ void redisDbPersistentData::emptyDbAsync() { m_setexpire = new (MALLOC_LOCAL) expireset(); m_pdict = dictCreate(&dbDictType,this); if (m_spstorage != nullptr) - m_spstorage->clear(); + m_spstorage->clearAsync(); if (m_fTrackingChanges) m_fAllChanged = true; atomicIncr(lazyfree_objects,dictSize(oldht1));