Convert free_json to an iterative function to avoid stack overflow on
large files
This commit is contained in:
		| @@ -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) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user