Unverified Commit 772564fc authored by debing.sun's avatar debing.sun Committed by GitHub
Browse files

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.
parent 804110a4
......@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment