Convert free_json to an iterative function to avoid stack overflow on
large files
This commit is contained in:
parent
2bbf21f90b
commit
621e50ee24
@ -4,9 +4,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// TODO (Abdelrahman): Because print_json and free_json are recursive functions,
|
||||
// they seem to cause stack overflow when dealing with large files. Refactor
|
||||
// both of them to avoid this problem.
|
||||
// TODO (Abdelrahman): Because print_json is a recursive function, it seems to
|
||||
// cause stack overflow when dealing with large files. Refactor if to avoid this
|
||||
// problem.
|
||||
|
||||
void print_json(const jentity_t *entity, u32 indent) {
|
||||
PERSISTENT i32 indentation = 0;
|
||||
@ -114,50 +114,86 @@ void print_json(const jentity_t *entity, u32 indent) {
|
||||
}
|
||||
}
|
||||
|
||||
void free_json(jentity_t **entity) {
|
||||
if (!(*entity)) {
|
||||
void free_json(jentity_t **root) {
|
||||
if (!(*root)) {
|
||||
return;
|
||||
}
|
||||
|
||||
jentity_t *entt_ptr = *entity;
|
||||
|
||||
jentity_t *current = *root;
|
||||
jentity_t *temp = NULL;
|
||||
dstr_t *key = NULL;
|
||||
const jval_t *value = NULL;
|
||||
jval_t *value = NULL;
|
||||
|
||||
if (entt_ptr->type == JENTITY_SINGLE) {
|
||||
value = &(entt_ptr->value);
|
||||
} else {
|
||||
key = entt_ptr->pair.key;
|
||||
value = &(entt_ptr->pair.value);
|
||||
}
|
||||
while (current) {
|
||||
if (current->parent) {
|
||||
// Move the beginning pointer of the collection to the next child
|
||||
|
||||
if (key) {
|
||||
dstr_free(&(entt_ptr->pair.key));
|
||||
}
|
||||
// TODO (Abdelrahman): This part gets repeated for some elements. Try to
|
||||
// avoid that repetition
|
||||
|
||||
switch (value->type) {
|
||||
case JVAL_COLLECTION:
|
||||
if (value->collection->begin) {
|
||||
free_json(&(value->collection->begin));
|
||||
jentity_t *parent = current->parent;
|
||||
jcoll_t *collection = NULL;
|
||||
|
||||
if (parent->type == JENTITY_SINGLE) {
|
||||
collection = parent->value.collection;
|
||||
} else {
|
||||
collection = parent->pair.value.collection;
|
||||
}
|
||||
|
||||
if (collection) {
|
||||
collection->begin = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
free(value->collection);
|
||||
if (current->type == JENTITY_SINGLE) {
|
||||
key = NULL;
|
||||
value = &(current->value);
|
||||
} else {
|
||||
key = current->pair.key;
|
||||
value = &(current->pair.value);
|
||||
}
|
||||
|
||||
break;
|
||||
case JVAL_STRING:
|
||||
dstr_free(&(entt_ptr->pair.value.string));
|
||||
if (key) {
|
||||
dstr_free(&(current->pair.key));
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (!value) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (value->type == JVAL_COLLECTION) {
|
||||
if (!(value->collection->begin)) {
|
||||
// Once all children of the collection has been freed, free the memory
|
||||
// allocated to the collection and the entity that holds it
|
||||
|
||||
free(value->collection);
|
||||
|
||||
temp = current;
|
||||
|
||||
current = current->next != NULL ? current->next : current->parent;
|
||||
|
||||
free(temp);
|
||||
temp = NULL;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
current = value->collection->begin;
|
||||
} else {
|
||||
if (value->type == JVAL_STRING) {
|
||||
dstr_free(&(value->string));
|
||||
}
|
||||
|
||||
temp = current;
|
||||
|
||||
current = current->next != NULL ? current->next : current->parent;
|
||||
|
||||
free(temp);
|
||||
temp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (entt_ptr->next) {
|
||||
free_json(&(entt_ptr->next));
|
||||
}
|
||||
|
||||
free(*entity);
|
||||
*entity = NULL;
|
||||
*root = NULL;
|
||||
}
|
||||
|
||||
jcoll_t *get_collection_from_entity(const jentity_t *entity) {
|
||||
|
Loading…
Reference in New Issue
Block a user