src/tree.c

changeset 904
cdc49211d87f
parent 903
a018f5916d3b
child 905
39aa4f106a71
--- a/src/tree.c	Thu Oct 03 15:42:35 2024 +0200
+++ b/src/tree.c	Thu Oct 03 16:31:09 2024 +0200
@@ -667,7 +667,19 @@
 }
 
 static void cx_tree_default_destructor(CxTree *tree) {
-    // TODO: destroy the nodes
+    if (tree->simple_destructor != NULL || tree->advanced_destructor != NULL) {
+        CxTreeIterator iter = tree->cl->iterator(tree, true);
+        cx_foreach(void *, node, iter) {
+            if (iter.exiting) {
+                if (tree->simple_destructor) {
+                    tree->simple_destructor(node);
+                }
+                if (tree->advanced_destructor) {
+                    tree->advanced_destructor(tree->destructor_data, node);
+                }
+            }
+        }
+    }
     cxFree(tree->allocator, tree);
 }
 
@@ -685,10 +697,60 @@
     return cx_tree_visitor(tree->root, tree->loc_children, tree->loc_next);
 }
 
+static int cx_tree_default_insert_element(
+        CxTree *tree,
+        const void *data
+) {
+    void *node;
+    if (tree->root == NULL) {
+        node = tree->node_create(data, tree);
+        if (node == NULL) return 1;
+        cx_tree_zero_pointers(node, cx_tree_node_layout(tree));
+        tree->root = node;
+        tree->size = 1;
+        return 0;
+    }
+    int result = cx_tree_add(data, tree->search, tree->node_create,
+                tree, &node, tree->root, cx_tree_node_layout(tree));
+    if (0 == result) {
+        tree->size++;
+    } else {
+        cxFree(tree->allocator, node);
+    }
+    return result;
+}
+
+static size_t cx_tree_default_insert_many(
+        CxTree *tree,
+        struct cx_iterator_base_s *iter,
+        size_t n
+) {
+    size_t ins = 0;
+    if (!iter->valid(iter)) return 0;
+    if (tree->root == NULL) {
+        // use the first element from the iter to create the root node
+        void **eptr = iter->current(iter);
+        void *node = tree->node_create(*eptr, tree);
+        if (node == NULL) return 0;
+        cx_tree_zero_pointers(node, cx_tree_node_layout(tree));
+        tree->root = node;
+        ins = 1;
+        iter->next(iter);
+    }
+    void *failed;
+    ins += cx_tree_add_iter(iter, n, tree->search, tree->node_create,
+                                  tree, &failed, tree->root, cx_tree_node_layout(tree));
+    tree->size += ins;
+    if (ins < n) {
+        cxFree(tree->allocator, failed);
+    }
+    return ins;
+}
+
 static cx_tree_class cx_tree_default_class = {
         cx_tree_default_destructor,
-        NULL,
-        NULL,
+        cx_tree_default_insert_element,
+        cx_tree_default_insert_many,
         NULL,
         cx_tree_default_iterator,
         cx_tree_default_visitor

mercurial