use dictMerge() in endSnapshot for speed and cleaner code
Former-commit-id: ed8e10234e4499506f2557b0858dba86c30c9dc0
This commit is contained in:
parent
8755f8b115
commit
2bc0075623
@ -42,6 +42,7 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "zmalloc.h"
|
#include "zmalloc.h"
|
||||||
@ -181,6 +182,12 @@ int dictMerge(dict *dst, dict *src)
|
|||||||
if (dictSize(src) == 0)
|
if (dictSize(src) == 0)
|
||||||
return DICT_OK;
|
return DICT_OK;
|
||||||
|
|
||||||
|
if (dictSize(dst) == 0)
|
||||||
|
{
|
||||||
|
std::swap(*dst, *src);
|
||||||
|
return DICT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dictIsRehashing(dst) && !dictIsRehashing(src))
|
if (!dictIsRehashing(dst) && !dictIsRehashing(src))
|
||||||
{
|
{
|
||||||
dst->ht[1] = dst->ht[0];
|
dst->ht[1] = dst->ht[0];
|
||||||
@ -190,6 +197,7 @@ int dictMerge(dict *dst, dict *src)
|
|||||||
return DICT_OK;
|
return DICT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dictExpand(dst, dictSize(dst)+dictSize(src)); // start dst rehashing if necessary
|
||||||
auto &htDst = dictIsRehashing(dst) ? dst->ht[1] : dst->ht[0];
|
auto &htDst = dictIsRehashing(dst) ? dst->ht[1] : dst->ht[0];
|
||||||
for (int iht = 0; iht < 2; ++iht)
|
for (int iht = 0; iht < 2; ++iht)
|
||||||
{
|
{
|
||||||
|
@ -151,6 +151,8 @@ void redisDbPersistentData::endSnapshot(const redisDbPersistentDataSnapshot *psn
|
|||||||
m_spdbSnapshotHOLDER->m_refCount--;
|
m_spdbSnapshotHOLDER->m_refCount--;
|
||||||
if (m_spdbSnapshotHOLDER->m_refCount > 0)
|
if (m_spdbSnapshotHOLDER->m_refCount > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
size_t sizeStart = size();
|
||||||
serverAssert(m_spdbSnapshotHOLDER->m_refCount == 0);
|
serverAssert(m_spdbSnapshotHOLDER->m_refCount == 0);
|
||||||
serverAssert((m_refCount == 0 && m_pdict->iterators == 0) || (m_refCount != 0 && m_pdict->iterators == 1));
|
serverAssert((m_refCount == 0 && m_pdict->iterators == 0) || (m_refCount != 0 && m_pdict->iterators == 1));
|
||||||
|
|
||||||
@ -189,25 +191,7 @@ void redisDbPersistentData::endSnapshot(const redisDbPersistentDataSnapshot *psn
|
|||||||
dictEmpty(m_pdictTombstone, nullptr);
|
dictEmpty(m_pdictTombstone, nullptr);
|
||||||
|
|
||||||
// Stage 2 Move all new keys to the snapshot DB
|
// Stage 2 Move all new keys to the snapshot DB
|
||||||
di = dictGetIterator(m_pdict);
|
dictMerge(m_spdbSnapshotHOLDER->m_pdict, m_pdict);
|
||||||
while ((de = dictNext(di)) != NULL)
|
|
||||||
{
|
|
||||||
robj *o = (robj*)dictGetVal(de);
|
|
||||||
sds newkey = sdsdupshared((sds)dictGetKey(de));
|
|
||||||
if (dictAdd(m_spdbSnapshotHOLDER->m_pdict, newkey, o) != DICT_OK)
|
|
||||||
{
|
|
||||||
// Review: We probably shouldn't even be getting into this state because the tombstone processing above should have cleared this out
|
|
||||||
sdsfree(newkey);
|
|
||||||
dictEntry *deExisting = dictFind(m_spdbSnapshotHOLDER->m_pdict, (const char*)dictGetKey(de));
|
|
||||||
serverAssert(deExisting != nullptr);
|
|
||||||
if (dictGetVal(deExisting) != nullptr)
|
|
||||||
decrRefCount((robj*)dictGetVal(deExisting));
|
|
||||||
dictSetVal(m_spdbSnapshotHOLDER->m_pdict, deExisting, o);
|
|
||||||
}
|
|
||||||
|
|
||||||
dictSetVal(m_pdict, de, nullptr); // remove the object so free'ing the dict doesn't decRef the object
|
|
||||||
}
|
|
||||||
dictReleaseIterator(di);
|
|
||||||
|
|
||||||
// Stage 3 swap the databases with the snapshot
|
// Stage 3 swap the databases with the snapshot
|
||||||
std::swap(m_pdict, m_spdbSnapshotHOLDER->m_pdict);
|
std::swap(m_pdict, m_spdbSnapshotHOLDER->m_pdict);
|
||||||
@ -236,6 +220,7 @@ void redisDbPersistentData::endSnapshot(const redisDbPersistentDataSnapshot *psn
|
|||||||
serverAssert(m_pdbSnapshot == m_spdbSnapshotHOLDER.get() || m_pdbSnapshot == nullptr);
|
serverAssert(m_pdbSnapshot == m_spdbSnapshotHOLDER.get() || m_pdbSnapshot == nullptr);
|
||||||
serverAssert((m_refCount == 0 && m_pdict->iterators == 0) || (m_refCount != 0 && m_pdict->iterators == 1));
|
serverAssert((m_refCount == 0 && m_pdict->iterators == 0) || (m_refCount != 0 && m_pdict->iterators == 1));
|
||||||
serverAssert(m_spdbSnapshotHOLDER != nullptr || dictSize(m_pdictTombstone) == 0);
|
serverAssert(m_spdbSnapshotHOLDER != nullptr || dictSize(m_pdictTombstone) == 0);
|
||||||
|
serverAssert(sizeStart == size());
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_iter redisDbPersistentDataSnapshot::random_cache_threadsafe() const
|
dict_iter redisDbPersistentDataSnapshot::random_cache_threadsafe() const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user