src/tree.c

branch
feature/tree_add
changeset 867
471c714d5b6f
parent 866
1f636de4a63f
child 868
56a908924510
--- a/src/tree.c	Mon Aug 19 20:46:36 2024 +0200
+++ b/src/tree.c	Tue Aug 20 11:02:54 2024 +0200
@@ -445,6 +445,21 @@
     return iter;
 }
 
+static void cx_tree_add_link_duplicate(
+        void **root, void *original, void *duplicate,
+        ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child,
+        ptrdiff_t loc_prev, ptrdiff_t loc_next
+) {
+    cx_tree_zero_pointers(duplicate, cx_tree_ptr_locations);
+    void *shared_parent = tree_parent(original);
+    if (shared_parent == NULL) {
+        cx_tree_link(duplicate, original, cx_tree_ptr_locations);
+        *root = duplicate;
+    } else {
+        cx_tree_link(shared_parent, duplicate, cx_tree_ptr_locations);
+    }
+}
+
 void *cx_tree_add(
         void const *src,
         cx_tree_search_func sfunc,
@@ -483,14 +498,13 @@
         cx_tree_zero_pointers(node, cx_tree_ptr_locations);
         cx_tree_link(node, *root, cx_tree_ptr_locations);
         *root = node;
-        return node;
     } else if (result == 0) {
         // data already found in the tree, let cfunc decide
         node = cfunc(src, match, cdata);
         if (node == NULL) return NULL;
         if (node != match) {
-            cx_tree_zero_pointers(node, cx_tree_ptr_locations);
-            cx_tree_link(match, node, cx_tree_ptr_locations);
+            cx_tree_add_link_duplicate(
+                    root, match, node, cx_tree_ptr_locations);
         }
     } else {
         // closest match found, add new node as child
@@ -580,8 +594,8 @@
             node = cfunc(elem, match, cdata);
             if (node == NULL) return processed;
             if (node != match) {
-                cx_tree_zero_pointers(node, cx_tree_ptr_locations);
-                cx_tree_link(match, node, cx_tree_ptr_locations);
+                cx_tree_add_link_duplicate(
+                        root, match, node, cx_tree_ptr_locations);
             }
             current_node = node;
         } else {

mercurial