chore: implement path mutation for JsonFlat (#2805)

* chore: implement path mutation for JsonFlat

This is done by converting the flat blob into mutable c++ json
and then building a new flat blob.

Also, add JsonFlat encoding to CompactObject class.
---------

Signed-off-by: Roman Gershman <roman@dragonflydb.io>
This commit is contained in:
Roman Gershman 2024-04-04 20:33:56 +03:00 committed by GitHub
parent 845f01c7fd
commit c8426cfd31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 106 additions and 58 deletions

View file

@ -697,22 +697,33 @@ std::optional<int64_t> CompactObj::TryGetInt() const {
auto CompactObj::GetJson() const -> JsonType* {
if (ObjType() == OBJ_JSON) {
DCHECK_EQ(u_.json_obj.encoding, kEncodingJsonCons);
return u_.json_obj.json_ptr;
}
return nullptr;
}
void CompactObj::SetJson(JsonType&& j) {
if (taglen_ == JSON_TAG) { // already json
if (taglen_ == JSON_TAG && u_.json_obj.encoding == kEncodingJsonCons) {
// already json
DCHECK(u_.json_obj.json_ptr != nullptr); // must be allocated
*u_.json_obj.json_ptr = std::move(j);
u_.json_obj.json_ptr->swap(j);
} else {
SetMeta(JSON_TAG);
void* ptr = tl.local_mr->allocate(sizeof(JsonType), kAlignSize);
void* ptr = tl.local_mr->allocate(sizeof(JsonType), alignof(JsonType));
u_.json_obj.json_ptr = new (ptr) JsonType(std::move(j));
u_.json_obj.encoding = kEncodingJsonCons;
}
}
void CompactObj::SetJson(const uint8_t* buf, size_t len) {
SetMeta(JSON_TAG);
u_.json_obj.flat_ptr = (uint8_t*)tl.local_mr->allocate(len, kAlignSize);
memcpy(u_.json_obj.flat_ptr, buf, len);
u_.json_obj.encoding = kEncodingJsonFlat;
u_.json_obj.json_len = len;
}
void CompactObj::SetSBF(uint64_t initial_capacity, double fp_prob, double grow_factor) {
if (taglen_ == SBF_TAG) { // already json
*u_.sbf = SBF(initial_capacity, fp_prob, grow_factor, tl.local_mr);
@ -1009,9 +1020,12 @@ void CompactObj::Free() {
tl.small_str_bytes -= u_.small_str.MallocUsed();
u_.small_str.Free();
} else if (taglen_ == JSON_TAG) {
VLOG(1) << "Freeing JSON object";
u_.json_obj.json_ptr->~JsonType();
tl.local_mr->deallocate(u_.json_obj.json_ptr, sizeof(JsonType), kAlignSize);
DVLOG(1) << "Freeing JSON object";
if (u_.json_obj.encoding == kEncodingJsonCons) {
DeleteMR<JsonType>(u_.json_obj.json_ptr);
} else {
tl.local_mr->deallocate(u_.json_obj.flat_ptr, u_.json_obj.json_len, kAlignSize);
}
} else if (taglen_ == SBF_TAG) {
DeleteMR<SBF>(u_.sbf);
} else {