Prevent unnecessary copy when overwriting a value from a snapshot

Former-commit-id: 654a7bc6ea82f4ac45a1c1a25c794e1c27c0d902
This commit is contained in:
John Sully 2020-08-15 22:59:01 +00:00
parent db193a1ef1
commit 07c019fd3d
2 changed files with 24 additions and 0 deletions

View File

@ -338,6 +338,7 @@ int dbMerge(redisDb *db, robj *key, robj *val, int fReplace)
* The client 'c' argument may be set to NULL if the operation is performed * The client 'c' argument may be set to NULL if the operation is performed
* in a context where there is no clear client performing the operation. */ * in a context where there is no clear client performing the operation. */
void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal) { void genericSetKey(client *c, redisDb *db, robj *key, robj *val, int keepttl, int signal) {
db->prepOverwriteForSnapshot(szFromObj(key));
if (!dbAddCore(db, key, val)) { if (!dbAddCore(db, key, val)) {
dbOverwrite(db, key, val, !keepttl); dbOverwrite(db, key, val, !keepttl);
} }
@ -2358,6 +2359,24 @@ bool redisDbPersistentData::insert(char *key, robj *o, bool fAssumeNew)
return (res == DICT_OK); return (res == DICT_OK);
} }
// This is a performance tool to prevent us copying over an object we're going to overwrite anyways
void redisDbPersistentData::prepOverwriteForSnapshot(char *key)
{
if (g_pserver->maxmemory_policy & MAXMEMORY_FLAG_LFU)
return;
if (m_pdbSnapshot != nullptr)
{
auto itr = m_pdbSnapshot->find_cached_threadsafe(key);
if (itr.key() != nullptr)
{
sds keyNew = sdsdupshared(itr.key());
if (dictAdd(m_pdictTombstone, keyNew, (void*)dictHashKey(m_pdict, key)) != DICT_OK)
sdsfree(keyNew);
}
}
}
void redisDbPersistentData::tryResize() void redisDbPersistentData::tryResize()
{ {
if (htNeedsResize(m_pdict)) if (htNeedsResize(m_pdict))

View File

@ -1326,6 +1326,9 @@ public:
void setExpire(robj *key, robj *subkey, long long when); void setExpire(robj *key, robj *subkey, long long when);
void setExpire(expireEntry &&e); void setExpire(expireEntry &&e);
void initialize(); void initialize();
void prepOverwriteForSnapshot(char *key);
bool FRehashing() const { return dictIsRehashing(m_pdict) || dictIsRehashing(m_pdictTombstone); }
void setStorageProvider(StorageCache *pstorage); void setStorageProvider(StorageCache *pstorage);
@ -1527,6 +1530,8 @@ struct redisDb : public redisDbPersistentDataSnapshot
using redisDbPersistentData::dictUnsafeKeyOnly; using redisDbPersistentData::dictUnsafeKeyOnly;
using redisDbPersistentData::resortExpire; using redisDbPersistentData::resortExpire;
using redisDbPersistentData::prefetchKeysAsync; using redisDbPersistentData::prefetchKeysAsync;
using redisDbPersistentData::prepOverwriteForSnapshot;
using redisDbPersistentData::FRehashing;
public: public:
expireset::setiter expireitr; expireset::setiter expireitr;