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) { ...@@ -46,7 +46,7 @@ void* activeDefragAlloc(void *ptr) {
/* move this allocation to a new allocation. /* move this allocation to a new allocation.
* make sure not to use the thread cache. so that we don't get back the same * make sure not to use the thread cache. so that we don't get back the same
* pointers we try to free */ * pointers we try to free */
size = zmalloc_size(ptr); size = zmalloc_usable_size(ptr);
newptr = zmalloc_no_tcache(size); newptr = zmalloc_no_tcache(size);
memcpy(newptr, ptr, size); memcpy(newptr, ptr, size);
zfree_no_tcache(ptr); zfree_no_tcache(ptr);
......
...@@ -778,8 +778,15 @@ void kvstoreDictLUTDefrag(kvstore *kvs, kvstoreDictLUTDefragFunction *defragfn) ...@@ -778,8 +778,15 @@ void kvstoreDictLUTDefrag(kvstore *kvs, kvstoreDictLUTDefragFunction *defragfn)
dict **d = kvstoreGetDictRef(kvs, didx), *newd; dict **d = kvstoreGetDictRef(kvs, didx), *newd;
if (!*d) if (!*d)
continue; continue;
if ((newd = defragfn(*d))) if ((newd = defragfn(*d))) {
*d = newd; *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) { ...@@ -862,6 +869,25 @@ void freeTestCallback(dict *d, void *val) {
zfree(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 = { dictType KvstoreDictTestType = {
hashTestCallback, hashTestCallback,
NULL, NULL,
...@@ -988,6 +1014,18 @@ int kvstoreTest(int argc, char **argv, int flags) { ...@@ -988,6 +1014,18 @@ int kvstoreTest(int argc, char **argv, int flags) {
assert(kvstoreSize(kvs2) == 0); 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(kvs1);
kvstoreRelease(kvs2); kvstoreRelease(kvs2);
return 0; 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