mirror of https://mirror.osredm.com/root/redis.git
Fix forget to update the dict's node in the kvstore's rehashing list after defragment (#13231)
Introducted by #13013 After defragmenting the dictionary in the kvstore, if the dict is reallocated, the value of its node in the kvstore rehashing list must be updated.
This commit is contained in:
parent
804110a487
commit
772564fc9e
|
@ -46,7 +46,7 @@ void* activeDefragAlloc(void *ptr) {
|
|||
/* move this allocation to a new allocation.
|
||||
* make sure not to use the thread cache. so that we don't get back the same
|
||||
* pointers we try to free */
|
||||
size = zmalloc_size(ptr);
|
||||
size = zmalloc_usable_size(ptr);
|
||||
newptr = zmalloc_no_tcache(size);
|
||||
memcpy(newptr, ptr, size);
|
||||
zfree_no_tcache(ptr);
|
||||
|
|
|
@ -778,8 +778,15 @@ void kvstoreDictLUTDefrag(kvstore *kvs, kvstoreDictLUTDefragFunction *defragfn)
|
|||
dict **d = kvstoreGetDictRef(kvs, didx), *newd;
|
||||
if (!*d)
|
||||
continue;
|
||||
if ((newd = defragfn(*d)))
|
||||
if ((newd = defragfn(*d))) {
|
||||
*d = newd;
|
||||
|
||||
/* After defragmenting the dict, update its corresponding
|
||||
* rehashing node in the kvstore's rehashing list. */
|
||||
kvstoreDictMetadata *metadata = (kvstoreDictMetadata *)dictMetadata(*d);
|
||||
if (metadata->rehashing_node)
|
||||
metadata->rehashing_node->value = *d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -862,6 +869,25 @@ void freeTestCallback(dict *d, void *val) {
|
|||
zfree(val);
|
||||
}
|
||||
|
||||
void* defragAllocTest(void *ptr) {
|
||||
size_t size = zmalloc_size(ptr);
|
||||
void *newptr = zmalloc(size);
|
||||
memcpy(newptr, ptr, size);
|
||||
zfree(ptr);
|
||||
return newptr;
|
||||
}
|
||||
|
||||
dict *defragLUTTestCallback(dict *d) {
|
||||
/* handle the dict struct */
|
||||
d = defragAllocTest(d);
|
||||
/* handle the first hash table */
|
||||
d->ht_table[0] = defragAllocTest(d->ht_table[0]);
|
||||
/* handle the second hash table */
|
||||
if (d->ht_table[1])
|
||||
d->ht_table[1] = defragAllocTest(d->ht_table[1]);
|
||||
return d;
|
||||
}
|
||||
|
||||
dictType KvstoreDictTestType = {
|
||||
hashTestCallback,
|
||||
NULL,
|
||||
|
@ -988,6 +1014,18 @@ int kvstoreTest(int argc, char **argv, int flags) {
|
|||
assert(kvstoreSize(kvs2) == 0);
|
||||
}
|
||||
|
||||
TEST("Verify that a rehashing dict's node in the rehashing list is correctly updated after defragmentation") {
|
||||
kvstore *kvs = kvstoreCreate(&KvstoreDictTestType, 0, KVSTORE_ALLOCATE_DICTS_ON_DEMAND);
|
||||
for (i = 0; i < 256; i++) {
|
||||
de = kvstoreDictAddRaw(kvs, 0, stringFromInt(i), NULL);
|
||||
if (listLength(kvs->rehashing)) break;
|
||||
}
|
||||
assert(listLength(kvs->rehashing));
|
||||
kvstoreDictLUTDefrag(kvs, defragLUTTestCallback);
|
||||
while (kvstoreIncrementallyRehash(kvs, 1000)) {}
|
||||
kvstoreRelease(kvs);
|
||||
}
|
||||
|
||||
kvstoreRelease(kvs1);
|
||||
kvstoreRelease(kvs2);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue