Remove indirection from t_tree_node to data
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Thu, 31 Jul 2025 06:22:39 +0000 (08:22 +0200)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Thu, 31 Jul 2025 06:25:17 +0000 (08:25 +0200)
This (probably) leads to faster access. I wanted to try to implement it
like this.
This is still not hardened and untested.

ft_struct/ft_tree_access_data.c
ft_struct/ft_tree_append_child.c
ft_struct/ft_tree_erase_child.c
ft_struct/ft_tree_free.c
ft_struct/ft_tree_init.c
ft_struct/ft_tree_replace_with_child.c
inc/ft_struct.h

index 1dc5b543b431e4aae68dda290a588080c35785b6..2eae4ca8139ef6d67b586674d1b3f9f1aaafe365 100644 (file)
@@ -2,5 +2,5 @@
 
 void   *ft_tree_access_data(t_tree_node *tree_node)
 {
-       return (tree_node->data);
+       return (&tree_node->data);
 }
index ef683346db29dee523924f39376a9ca8edb1a626..81884a6889818ed32a12e267e1cfe6592ff35283 100644 (file)
@@ -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);
 }
index d80aef67f5af0d562b0683213e0f549447a01cb0..99c2cf92232513e38818c030c2d2e7504564436c 100644 (file)
@@ -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 ;
 }
index 20c096f17512a9fb31bafc2b97b76c8650d6fb95..16bc1fe03a9129b341769eadfb96a45b0f873c81 100644 (file)
@@ -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 ;
 }
-
index 14e4f09de4bdfccac90232dea695229cb757be97..251daa388ef33880fe3d4533f28b183caf6f86b3 100644 (file)
@@ -1,8 +1,15 @@
 #include "ft_struct.h"
 #include "libft.h"
+#include <stdlib.h>
 
-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));
 }
index 3cdce97fd3fdcd67c2cb0e3ec5cea8771c2cc453..5eaf5e81bea8b3212df7c649c383944b8e611c89 100644 (file)
@@ -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 ;
index 6d5571ab8d18614f5d84cf2494b463487e0fde47..648ff4cc367743417f72d40ec464e2ed5f41848a 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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);