Fix issue where expire is lost when performing a defrag

Former-commit-id: aea333bb78fafabbddb340dfd4c232c2e207cfba
This commit is contained in:
John Sully 2020-01-01 20:41:17 -05:00
parent 2e50d383a6
commit 85c8fc72b7

View File

@ -48,7 +48,7 @@ extern "C" int je_get_defrag_hint(void* ptr, int *bin_util, int *run_util);
/* forward declarations*/ /* forward declarations*/
void defragDictBucketCallback(void *privdata, dictEntry **bucketref); void defragDictBucketCallback(void *privdata, dictEntry **bucketref);
dictEntry* replaceSateliteDictKeyPtrAndOrDefragDictEntry(dict *d, sds oldkey, sds newkey, uint64_t hash, long *defragged); dictEntry* replaceSateliteDictKeyPtrAndOrDefragDictEntry(dict *d, sds oldkey, sds newkey, uint64_t hash, long *defragged);
void replaceSateliteOSetKeyPtr(expireset &set, sds oldkey, sds newkey); bool replaceSateliteOSetKeyPtr(expireset &set, sds oldkey, sds newkey);
/* Defrag helper for generic allocations. /* Defrag helper for generic allocations.
* *
@ -407,7 +407,7 @@ dictEntry* replaceSateliteDictKeyPtrAndOrDefragDictEntry(dict *d, sds oldkey, sd
return NULL; return NULL;
} }
void replaceSateliteOSetKeyPtr(expireset &set, sds oldkey, sds newkey) { bool replaceSateliteOSetKeyPtr(expireset &set, sds oldkey, sds newkey) {
auto itr = set.find(oldkey); auto itr = set.find(oldkey);
if (itr != set.end()) if (itr != set.end())
{ {
@ -415,7 +415,10 @@ void replaceSateliteOSetKeyPtr(expireset &set, sds oldkey, sds newkey) {
eNew.setKeyUnsafe(newkey); eNew.setKeyUnsafe(newkey);
set.erase(itr); set.erase(itr);
set.insert(eNew); set.insert(eNew);
serverAssert(set.find(newkey) != set.end());
return true;
} }
return false;
} }
long activeDefragQuickListNodes(quicklist *ql) { long activeDefragQuickListNodes(quicklist *ql) {
@ -777,16 +780,22 @@ long defragKey(redisDb *db, dictEntry *de) {
long defragged = 0; long defragged = 0;
sds newsds; sds newsds;
ob = (robj*)dictGetVal(de);
/* Try to defrag the key name. */ /* Try to defrag the key name. */
newsds = activeDefragSds(keysds); newsds = activeDefragSds(keysds);
if (newsds) if (newsds)
{
defragged++, de->key = newsds; defragged++, de->key = newsds;
if (!db->setexpire->empty()) { if (!db->setexpire->empty()) {
replaceSateliteOSetKeyPtr(*db->setexpire, keysds, newsds); bool fReplaced = replaceSateliteOSetKeyPtr(*db->setexpire, keysds, newsds);
serverAssert(fReplaced == ob->FExpires());
} else {
serverAssert(!ob->FExpires());
}
} }
/* Try to defrag robj and / or string value. */ /* Try to defrag robj and / or string value. */
ob = (robj*)dictGetVal(de);
if ((newob = activeDefragStringOb(ob, &defragged))) { if ((newob = activeDefragStringOb(ob, &defragged))) {
de->v.val = newob; de->v.val = newob;
ob = newob; ob = newob;
@ -839,6 +848,7 @@ long defragKey(redisDb *db, dictEntry *de) {
} else { } else {
serverPanic("Unknown object type"); serverPanic("Unknown object type");
} }
return defragged; return defragged;
} }