diff --git a/src/db.cpp b/src/db.cpp index bf256edc4..1324c6e14 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -1469,6 +1469,14 @@ int redisDbPersistentData::removeSubkeyExpire(robj *key, robj *subkey) { return found; } +void redisDbPersistentData::resortExpire(expireEntry &e) +{ + auto itr = m_setexpire->find(e.key()); + expireEntry eT = std::move(e); + m_setexpire->erase(itr); + m_setexpire->insert(eT); +} + /* Set an expire to the specified key. If the expire is set in the context * of an user calling a command 'c' is the client, otherwise 'c' is set * to NULL. The 'when' parameter is the absolute unix time in milliseconds diff --git a/src/expire.cpp b/src/expire.cpp index b7cb49eaf..34051b521 100644 --- a/src/expire.cpp +++ b/src/expire.cpp @@ -132,15 +132,17 @@ void activeExpireCycleExpire(redisDb *db, expireEntry &e, long long now) { pfat->popfrontExpireEntry(); } + robj *keyobj = nullptr; + + if (deleted || pfat->FEmpty()) + keyobj = createStringObject(e.key(),sdslen(e.key())); + if (deleted) { if (!pfat->FEmpty()) { // We need to resort the expire entry since it may no longer be in the correct position - auto itr = db->setexpire->find(e.key()); - expireEntry eT = std::move(e); - db->setexpire->erase(itr); - db->setexpire->insert(eT); + db->resortExpire(e); } robj objT; @@ -156,10 +158,11 @@ void activeExpireCycleExpire(redisDb *db, expireEntry &e, long long now) { if (pfat->FEmpty()) { - robj *keyobj = createStringObject(e.key(),sdslen(e.key())); removeExpire(db, keyobj); - decrRefCount(keyobj); } + + if (keyobj) + decrRefCount(keyobj); } int parseUnitString(const char *sz) diff --git a/src/server.h b/src/server.h index 7f1953098..6651837b7 100644 --- a/src/server.h +++ b/src/server.h @@ -1277,6 +1277,7 @@ public: size_t expireSize() const { return m_setexpire->size(); } int removeExpire(robj *key, dict_iter itr); int removeSubkeyExpire(robj *key, robj *subkey); + void resortExpire(expireEntry &e); void clear(void(callback)(void*)); void emptyDbAsync(); // Note: If you do not need the obj then use the objless iterator version. It's faster @@ -1468,6 +1469,7 @@ struct redisDb : public redisDbPersistentDataSnapshot using redisDbPersistentData::consolidate_snapshot; using redisDbPersistentData::removeAllCachedValues; using redisDbPersistentData::dictUnsafeKeyOnly; + using redisDbPersistentData::resortExpire; public: expireset::setiter expireitr;