Closed faultaddr closed 1 year ago
The yyjson_mut_doc
is designed to create JSON data from scratch as quickly as possible. As a result, the memory pool is designed to be simple and not focused on releasing individual values. This allows for fast and easy creation and release of all values. You can find more information about it here: API.md#create-json-document
If you want to control the memory for individual values, a simpler solution would be to use calloc
or your own memory pool to create all yyjson_mut_val
, and then use yyjson_mut_set_xxx()
to assign values. Would this approach work for your needs?
Usually a json object is obtained through Parse, In my opinion, remove the single yyjson_mut_val
from the original yyjson_mut_doc
, and then attach it as a child for another yyjson_mut_doc
is impossible under current circumstances.
jsonA: "{\"test1\": \"true\", \"test2\": false}"
jsonB: "{\"test1\": {\"test3\": \"nb\"}, \"test3\": false}"
we would like to make jsonA become {\"test1\": \"true\"}
and jsonB become "{\"test1\": {\"test3\": \"nb\"}, \"test2\": false,\"test3\": false}"
without any copy operation, something like the std::move
to saving time.
so, we define the
struct yyjson_mut_val {
uint64_t tag;
yyjson_val_uni uni;
yyjson_mut_val* next;
yyjson_val_chunk* val_chunk;
yyjson_str_chunk* str_chunk;
};
and change the
// do the same thing in unsafe_yyjson_str_pool_grow
bool unsafe_yyjson_val_pool_grow(yyjson_val_pool* pool, yyjson_alc* alc, usize count) {
yyjson_val_chunk* chunk;
usize size;
if (count >= USIZE_MAX / sizeof(yyjson_mut_val) - 16)
return false;
size = (count + 1) * sizeof(yyjson_mut_val);
// size = yyjson_max(pool->chunk_size, size);
chunk = (yyjson_val_chunk*)alc->malloc(alc->ctx, size);
if (yyjson_unlikely(!chunk))
return false;
chunk->next = pool->chunks;
pool->chunks = chunk;
pool->cur = (yyjson_mut_val*)(void*)((u8*)chunk + sizeof(yyjson_mut_val));
pool->end = (yyjson_mut_val*)(void*)((u8*)chunk + size);
// size = yyjson_min(pool->chunk_size * 2, pool->chunk_size_max);
// pool->chunk_size = size;
return true;
}
when we create new yyjson_mut_val, just record the chunk addr for both val/str. so we can tansfer the ownership when needed.
so we have defined several functions to solve the problem
yyjson_val_chunk* unsafe_yyjson_str_pool_shrink(yyjson_str_pool* pool, yyjson_mut_val* val);
yyjson_str_chunk* unsafe_yyjson_val_pool_shrink(yyjson_val_pool* pool,yyjson_mut_val* val);
bool unsafe_yyjson_str_pool_grow_without_malloc(yyjson_str_pool* pool, yyjson_str_chunk *chunk);
bool unsafe_yyjson_val_pool_grow_without_malloc(yyjson_val_pool* pool, yyjson_val_chunk* chunk);
// change the detach function
yyjson_mut_val* unsafe_yyjson_mut_val_detach(yyjson_mut_doc* old_doc, yyjson_mut_doc* doc, yyjson_mut_val* parent, yyjson_mut_val* item)
Maybe tonight, I would create the PR. lol :) 😁talk is cheap, I will show u the code.
Problem:
I found that we malloc the memory when needed, but the val not keep the ref of the memory access.So, In our situation, It's difficult to detach the memory from the doc for single yyjson_mut_val.
Solution:
So, I try to make some changes, making the real memory detach become possible.
The code is on the way, But I don't know is it reasonable to do as above.