Skip to content

Commit

Permalink
Implements jv_is_unshared()
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxBrandtner committed Jun 8, 2024
1 parent e600eeb commit cc8f771
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 192 deletions.
87 changes: 4 additions & 83 deletions src/jq_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,96 +492,17 @@ static void jv_test() {
}

{
assert(jv_equal(
jv_paths(
jv_parse("{"
"\"key\":["
"{\"this\":{\"some\":true}},"
"false,"
"null,"
"10,"
"[true]"
"]"
"}")
),
jv_parse("["
"[\"key\"],"
"[\"key\", 0],"
"[\"key\", 0, \"this\"],"
"[\"key\", 0, \"this\", \"some\"],"
"[\"key\", 1],"
"[\"key\", 2],"
"[\"key\", 3],"
"[\"key\", 4],"
"[\"key\", 4, 0]"
"]")
));
jv test_unshared = JV_OBJECT(jv_string("some"), JV_ARRAY(jv_string("other"), jv_true()));

}

{
assert(jv_equal(
jv_addpath(
jv_parse("{"
"\"key\":{"
"\"some\":{"
"\"test\":\"value\""
"},"
"\"other\":\"thing\""
"}"
"}"),
JV_ARRAY(jv_string("key")),
jv_parse("{"
"\"some\":{"
"\"test\":\"other\""
"},"
"\"added\":\"thing\""
"}")
),
jv_parse("{"
"\"key\":{"
"\"some\":{"
"\"test\":\"other\""
"},"
"\"other\":\"thing\","
"\"added\":\"thing\""
"}"
"}")
)
);
assert(jv_is_unshared(test_unshared));
jv_free(test_unshared);

}

{
jv initial = jv_parse("{\"test\":[{\"some\":\"value\"}, 1, true, false, null]}");
jv new = jv_unshare(jv_copy(initial));

assert(jv_equal(jv_copy(initial), jv_copy(new)));
assert(!jv_identical(jv_copy(initial), jv_copy(new)));

jv paths = jv_paths(jv_copy(initial));

size_t paths_length = jv_array_length(jv_copy(paths));

for(size_t i = 0; i < paths_length; i++){
jv path_i = jv_array_get(jv_copy(paths), i);
assert(!jv_identical(
jv_getpath(
jv_copy(initial),
jv_copy(path_i)
),
jv_getpath(
jv_copy(new),
jv_copy(path_i)
)
));

jv_free(path_i);
}

assert(jv_is_unshared(new));
jv_free(initial);
jv_free(new);
jv_free(paths);

}
}
53 changes: 49 additions & 4 deletions src/jv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1865,11 +1865,13 @@ jv jv_object_iter_value(jv object, int iter) {
jv jv_unshare(jv input){
switch(jv_get_kind(input)){
case JV_KIND_INVALID:
if(!jv_invalid_has_msg(jv_copy(input))){
jv_free(input);
return jv_invalid();
{
if(!jv_invalid_has_msg(jv_copy(input))){
jv_free(input);
return jv_invalid();
}
return jv_invalid_with_msg(jv_unshare(jv_invalid_get_msg(jv_copy(input))));
}
return jv_invalid_with_msg(jv_unshare(jv_invalid_get_msg(jv_copy(input))));
case JV_KIND_OBJECT:
{
jv keys = jv_keys(jv_copy(input));
Expand Down Expand Up @@ -1943,6 +1945,49 @@ jv jv_unshare(jv input){
}
}

int jv_is_unshared(jv a){
if(jv_get_refcnt(a) != 1){
fprintf(stderr, "input refcnt != 1\n");
return 1;
}
if(jv_get_kind(a) == JV_KIND_OBJECT){
jv keys = jv_keys(jv_copy(a));
size_t keys_length = jv_array_length(jv_copy(keys));
for(size_t i = 0; i < keys_length; i++){
jv key = jv_array_get(jv_copy(keys), i);
if(jv_get_refcnt(key) > 3){
fprintf(stderr, "key in object does not have refcnt 1, %d\n", jv_get_refcnt(key));
jv_free(key);
jv_free(keys);
return 0;
}

jv value = jv_object_get(jv_copy(a), key);
jv_free(value);
if(!jv_is_unshared(value)){
fprintf(stderr, "failed on object\n");
jv_free(keys);
return 0;
}
}

jv_free(keys);

}else if(jv_get_kind(a) == JV_KIND_ARRAY){
size_t a_length = jv_array_length(jv_copy(a));
for(size_t i = 0; i < a_length; i++){
jv value = jv_array_get(jv_copy(a), i);
jv_free(value);
if(!jv_is_unshared(value)){
fprintf(stderr, "failed on array value\n");
return 0;
}
}
}

return 1;
}

jv jv_copy(jv j) {
if (JVP_IS_ALLOCATED(j)) {
jvp_refcnt_inc(j.u.ptr);
Expand Down
3 changes: 1 addition & 2 deletions src/jv.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ static int jv_is_valid(jv x) { return jv_get_kind(x) != JV_KIND_INVALID; }

//jv_unshare() creates a deep copy of the input aka the content of the output will be identical to the input, but no shared memory exists between them
jv jv_unshare(jv);
int jv_is_unshared(jv);
jv jv_copy(jv);
void jv_free(jv);

Expand Down Expand Up @@ -258,10 +259,8 @@ jv jv_get(jv, jv);
jv jv_set(jv, jv, jv);
jv jv_has(jv, jv);
jv jv_setpath(jv, jv, jv);
jv jv_addpath(jv, jv, jv);
jv jv_getpath(jv, jv);
jv jv_delpaths(jv, jv);
jv jv_paths(jv);
jv jv_keys(jv /*object or array*/);
jv jv_keys_unsorted(jv /*object or array*/);
int jv_cmp(jv, jv);
Expand Down
104 changes: 1 addition & 103 deletions src/jv_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,69 +427,7 @@ jv jv_setpath(jv root, jv path, jv value) {
return jv_set(root, pathcurr, jv_setpath(subroot, pathrest, value));
}

jv jv_addpath(jv root, jv path, jv add){
if(jv_get_kind(path) != JV_KIND_ARRAY || !jv_is_valid(add)){
jv_free(root);
jv_free(path);
jv_free(add);
return jv_invalid();
}

if(jv_get_kind(root) != JV_KIND_OBJECT && jv_get_kind(root) != JV_KIND_ARRAY){
jv_free(root);

if(!jv_equal(jv_copy(path), jv_array())){
jv_free(path);
jv_free(add);
return jv_invalid();
}

jv_free(path);

return add;
}

if(!jv_equal(jv_copy(path), jv_array())){
return jv_setpath(root, path, jv_addpath(jv_getpath(jv_copy(root), jv_copy(path)), jv_array(), add));
}

jv root_paths = jv_paths(jv_copy(root));
jv add_paths = jv_paths(jv_copy(add));

size_t add_paths_length = jv_array_length(jv_copy(add_paths));

for(size_t i = 0; i < add_paths_length; i++){
jv add_path = jv_array_get(jv_copy(add_paths), i);
jv add_path_value = jv_getpath(jv_copy(add), jv_copy(add_path));

if(!jv_is_valid(add_path_value) || jv_get_kind(add_path_value) == JV_KIND_NULL){
jv_free(root);
jv_free(path);
jv_free(add);
jv_free(root_paths);
jv_free(add_paths);
jv_free(add_path);
jv_free(add_path_value);
return jv_invalid();
}

if(jv_get_kind(add_path_value) == JV_KIND_OBJECT || jv_get_kind(add_path_value) == JV_KIND_ARRAY){
jv_free(add_path);
jv_free(add_path_value);
continue;
}

root = jv_setpath(root, add_path, add_path_value);
}

jv_free(path);
jv_free(add);

jv_free(root_paths);
jv_free(add_paths);

return root;
}


jv jv_getpath(jv root, jv path) {
if (jv_get_kind(path) != JV_KIND_ARRAY) {
Expand Down Expand Up @@ -602,46 +540,6 @@ static int string_cmp(const void* pa, const void* pb){
return r;
}

jv jv_paths(jv input){
if(jv_get_kind(input) != JV_KIND_OBJECT && jv_get_kind(input) != JV_KIND_ARRAY){
jv_free(input);
return jv_invalid();
}

jv keys = jv_keys(jv_copy(input));

size_t keys_length = jv_array_length(jv_copy(keys));

jv output = jv_array();

for(size_t i = 0; i < keys_length; i++){
jv key = jv_array_get(jv_copy(keys), i);
jv insert_paths = jv_paths(jv_getpath(jv_copy(input), JV_ARRAY(jv_copy(key))));

output = jv_array_append(output, JV_ARRAY(jv_copy(key)));

if(jv_get_kind(insert_paths) == JV_KIND_INVALID){
jv_free(insert_paths);
jv_free(key);

continue;
}

size_t paths_length = jv_array_length(jv_copy(insert_paths));

for(size_t j = 0; j < paths_length; j++){
output = jv_array_append(output, jv_array_concat(JV_ARRAY(jv_copy(key)), jv_array_get(jv_copy(insert_paths), j)));
}

jv_free(key);
jv_free(insert_paths);
}

jv_free(input);
jv_free(keys);

return output;
}

jv jv_keys_unsorted(jv x) {
if (jv_get_kind(x) != JV_KIND_OBJECT)
Expand Down

0 comments on commit cc8f771

Please sign in to comment.