From: Lukáš Jiřiště Date: Thu, 31 Jul 2025 06:22:39 +0000 (+0200) Subject: Remove indirection from t_tree_node to data X-Git-Url: https://git.ljiriste.work/?a=commitdiff_plain;h=12d162c5f77883eccb65a40e6358da5b3dedb326;p=Libft.git Remove indirection from t_tree_node to data This (probably) leads to faster access. I wanted to try to implement it like this. This is still not hardened and untested. --- diff --git a/ft_struct/ft_tree_access_data.c b/ft_struct/ft_tree_access_data.c index 1dc5b54..2eae4ca 100644 --- a/ft_struct/ft_tree_access_data.c +++ b/ft_struct/ft_tree_access_data.c @@ -2,5 +2,5 @@ void *ft_tree_access_data(t_tree_node *tree_node) { - return (tree_node->data); + return (&tree_node->data); } diff --git a/ft_struct/ft_tree_append_child.c b/ft_struct/ft_tree_append_child.c index ef68334..81884a6 100644 --- a/ft_struct/ft_tree_append_child.c +++ b/ft_struct/ft_tree_append_child.c @@ -3,13 +3,20 @@ t_ft_stat ft_tree_append_child(t_tree_node *tree_node, void *element) { - t_tree_node new_node; + t_tree_node *new_node; t_ft_stat res; - res = ft_tree_init(&new_node); + res = ft_vec_append_empty(&tree_node->children); if (res != success) - return res; - new_node.data = element; - res = ft_vec_append(&tree_node->children, &new_node); - return (res); + return (res); + new_node = ft_tree_access_child(tree_node, tree_node->children.size - 1); + new_node->parent = tree_node; + res = ft_vec_init(&new_node->children, tree_node->children.el_size); + if (res != success) + { + ft_tree_forget_child(tree_node, tree_node->children.size - 1); + return (res); + } + ft_memcpy(&new_node->data, element, new_node->children.el_size - sizeof(t_tree_node)); + return (success); } diff --git a/ft_struct/ft_tree_erase_child.c b/ft_struct/ft_tree_erase_child.c index d80aef6..99c2cf9 100644 --- a/ft_struct/ft_tree_erase_child.c +++ b/ft_struct/ft_tree_erase_child.c @@ -5,7 +5,10 @@ void ft_tree_erase_child(t_tree_node *tree_node, size_t i, void (*free_el)(void t_tree_node *child_to_erase; child_to_erase = ft_tree_access_child(tree_node, i); - ft_tree_free(child_to_erase, free_el); + while (child_to_erase->children.size > 0) + ft_tree_erase_child(child_to_erase, 0, free_el); + if (free_el) + free_el(&child_to_erase->data); ft_tree_forget_child(tree_node, i); return ; } diff --git a/ft_struct/ft_tree_free.c b/ft_struct/ft_tree_free.c index 20c096f..16bc1fe 100644 --- a/ft_struct/ft_tree_free.c +++ b/ft_struct/ft_tree_free.c @@ -3,17 +3,13 @@ void ft_tree_free(t_tree *tree, void (*free_el)(void *)) { - size_t i; + t_tree_node *root; - i = 0; - while (i < tree->children.size) - { - ft_tree_free(ft_tree_access_child(tree, i), free_el); - ++i; - } - free_el(tree->data); - ft_vec_free(&tree->children, NULL); - ft_tree_init(tree); + root = *tree; + while (root->children.size > 0) + ft_tree_erase_child(root, 0, free_el); + if (free_el) + free_el(&root->data); + ft_vec_free(&root->children, NULL); return ; } - diff --git a/ft_struct/ft_tree_init.c b/ft_struct/ft_tree_init.c index 14e4f09..251daa3 100644 --- a/ft_struct/ft_tree_init.c +++ b/ft_struct/ft_tree_init.c @@ -1,8 +1,15 @@ #include "ft_struct.h" #include "libft.h" +#include -t_ft_stat ft_tree_init(t_tree *tree) +t_ft_stat ft_tree_init(t_tree *tree, size_t el_size) { - tree->data = NULL; - return (ft_vec_init(&tree->children, sizeof(t_tree_node))); + t_tree_node *root; + + root = malloc(sizeof(t_tree_node) + el_size); + if (!root) + return (alloc_fail); + root->parent = NULL; + *tree = root; + return (ft_vec_init(&root->children, sizeof(t_tree_node) + el_size)); } diff --git a/ft_struct/ft_tree_replace_with_child.c b/ft_struct/ft_tree_replace_with_child.c index 3cdce97..5eaf5e8 100644 --- a/ft_struct/ft_tree_replace_with_child.c +++ b/ft_struct/ft_tree_replace_with_child.c @@ -13,8 +13,9 @@ void ft_tree_replace_with_child(t_tree_node *tree_node, size_t i, void (*free_el if (res != success) return ; i += child->children.size; - free_el(tree_node->data); - tree_node->data = child->data; + if (free_el) + free_el(&tree_node->data); + ft_memcpy(&tree_node->data, &child->data, tree_node->children.size - sizeof(t_tree_node)); ft_vec_free(&child->children, NULL); ft_vec_forget(&tree_node->children, i); return ; diff --git a/inc/ft_struct.h b/inc/ft_struct.h index 6d5571a..648ff4c 100644 --- a/inc/ft_struct.h +++ b/inc/ft_struct.h @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/20 16:59:43 by ljiriste #+# #+# */ -/* Updated: 2025/07/30 20:56:33 by ljiriste ### ########.fr */ +/* Updated: 2025/07/31 08:09:13 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,15 +35,21 @@ void ft_stack_free(t_stack *stack, void (*free_el)(void *)); // t_vec reserves memory for 8 elements at first // it may be beneficial to add a member defining the number of children // and let a function reserve that number in the t_vec to save some space -typedef struct s_tree_node +// +// element size is stored in the children t_vec, because children.size = sizeof(t_tree_node) + el_size; +// Making the data part of the node makes the el_size fixed - use union if needed +typedef struct s_tree_node t_tree_node; + +struct s_tree_node { - void *data; - t_vec children; -} t_tree_node; + t_tree_node *parent; + t_vec children; + char data[]; +}; -typedef t_tree_node t_tree; +typedef t_tree_node *t_tree; -t_ft_stat ft_tree_init(t_tree *tree); +t_ft_stat ft_tree_init(t_tree *tree, size_t el_size); t_ft_stat ft_tree_append_child(t_tree_node *tree_node, void *element); t_tree_node *ft_tree_access_child(t_tree_node *tree_node, size_t i); void *ft_tree_access_data(t_tree_node *tree_node);