mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 10:25:47 +02:00
chore: add defrag logic for sets (#3833)
* add defrag logic for sets * add small test --------- Signed-off-by: kostas <kostas@dragonflydb.io>
This commit is contained in:
parent
beb2ec2b29
commit
a3abf41f4e
2 changed files with 89 additions and 21 deletions
|
@ -138,39 +138,74 @@ inline void FreeObjZset(unsigned encoding, void* ptr) {
|
|||
}
|
||||
}
|
||||
|
||||
pair<void*, bool> DefragStrMap2(StringMap* sm, float ratio) {
|
||||
bool realloced = false;
|
||||
|
||||
for (auto it = sm->begin(); it != sm->end(); ++it)
|
||||
realloced |= it.ReallocIfNeeded(ratio);
|
||||
|
||||
return {sm, realloced};
|
||||
}
|
||||
|
||||
pair<void*, bool> DefragListPack(uint8_t* lp, float ratio) {
|
||||
if (!zmalloc_page_is_underutilized(lp, ratio))
|
||||
return {lp, false};
|
||||
|
||||
size_t lp_bytes = lpBytes(lp);
|
||||
uint8_t* replacement = lpNew(lpBytes(lp));
|
||||
memcpy(replacement, lp, lp_bytes);
|
||||
lpFree(lp);
|
||||
|
||||
return {replacement, true};
|
||||
}
|
||||
|
||||
pair<void*, bool> DefragIntSet(intset* is, float ratio) {
|
||||
if (!zmalloc_page_is_underutilized(is, ratio))
|
||||
return {is, false};
|
||||
|
||||
const size_t blob_len = intsetBlobLen(is);
|
||||
intset* replacement = (intset*)zmalloc(blob_len);
|
||||
memcpy(replacement, is, blob_len);
|
||||
|
||||
zfree(is);
|
||||
return {replacement, true};
|
||||
}
|
||||
|
||||
// Iterates over allocations of internal hash data structures and re-allocates
|
||||
// them if their pages are underutilized.
|
||||
// Returns pointer to new object ptr and whether any re-allocations happened.
|
||||
pair<void*, bool> DefragHash(MemoryResource* mr, unsigned encoding, void* ptr, float ratio) {
|
||||
pair<void*, bool> DefragHash(unsigned encoding, void* ptr, float ratio) {
|
||||
switch (encoding) {
|
||||
// Listpack is stored as a single contiguous array
|
||||
case kEncodingListPack: {
|
||||
uint8_t* lp = (uint8_t*)ptr;
|
||||
if (!zmalloc_page_is_underutilized(lp, ratio))
|
||||
return {lp, false};
|
||||
|
||||
size_t lp_bytes = lpBytes(lp);
|
||||
uint8_t* replacement = lpNew(lpBytes(lp));
|
||||
memcpy(replacement, lp, lp_bytes);
|
||||
lpFree(lp);
|
||||
|
||||
return {replacement, true};
|
||||
};
|
||||
return DefragListPack((uint8_t*)ptr, ratio);
|
||||
}
|
||||
|
||||
// StringMap supports re-allocation of it's internal nodes
|
||||
case kEncodingStrMap2: {
|
||||
bool realloced = false;
|
||||
|
||||
StringMap* sm = (StringMap*)ptr;
|
||||
for (auto it = sm->begin(); it != sm->end(); ++it)
|
||||
realloced |= it.ReallocIfNeeded(ratio);
|
||||
|
||||
return {sm, realloced};
|
||||
return DefragStrMap2((StringMap*)ptr, ratio);
|
||||
}
|
||||
|
||||
default:
|
||||
ABSL_UNREACHABLE();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pair<void*, bool> DefragSet(unsigned encoding, void* ptr, float ratio) {
|
||||
switch (encoding) {
|
||||
// Int sets have flat storage
|
||||
case kEncodingIntSet: {
|
||||
return DefragIntSet((intset*)ptr, ratio);
|
||||
}
|
||||
|
||||
// StringMap supports re-allocation of it's internal nodes
|
||||
case kEncodingStrMap2: {
|
||||
return DefragStrMap2((StringMap*)ptr, ratio);
|
||||
}
|
||||
|
||||
default:
|
||||
ABSL_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
inline void FreeObjStream(void* ptr) {
|
||||
|
@ -391,7 +426,11 @@ bool RobjWrapper::DefragIfNeeded(float ratio) {
|
|||
return true;
|
||||
}
|
||||
} else if (type() == OBJ_HASH) {
|
||||
auto [new_ptr, realloced] = DefragHash(tl.local_mr, encoding_, inner_obj_, ratio);
|
||||
auto [new_ptr, realloced] = DefragHash(encoding_, inner_obj_, ratio);
|
||||
inner_obj_ = new_ptr;
|
||||
return realloced;
|
||||
} else if (type() == OBJ_SET) {
|
||||
auto [new_ptr, realloced] = DefragSet(encoding_, inner_obj_, ratio);
|
||||
inner_obj_ = new_ptr;
|
||||
return realloced;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue