fix bug when removing the root node of a tree

Sat, 05 Oct 2024 14:22:42 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 05 Oct 2024 14:22:42 +0200
changeset 907
1f72fb9af87e
parent 906
b51e5268bd9b
child 908
f49f8a7060aa

fix bug when removing the root node of a tree

relates to #166

src/tree.c file | annotate | diff | comparison | revisions
tests/test_tree.c file | annotate | diff | comparison | revisions
--- a/src/tree.c	Sat Oct 05 14:16:01 2024 +0200
+++ b/src/tree.c	Sat Oct 05 14:22:42 2024 +0200
@@ -901,6 +901,11 @@
 }
 
 void cxTreeRemove(CxTree *tree, void *node) {
+    if (node == tree->root) {
+        tree->root = NULL;
+        tree->size = 0;
+        return;
+    }
     size_t subtree_size = cxTreeSubtreeSize(tree, node);
     cx_tree_unlink(node, cx_tree_node_layout(tree));
     tree->size -= subtree_size;
--- a/tests/test_tree.c	Sat Oct 05 14:16:01 2024 +0200
+++ b/tests/test_tree.c	Sat Oct 05 14:22:42 2024 +0200
@@ -1789,6 +1789,43 @@
     cx_testing_allocator_destroy(&talloc);
 }
 
+CX_TEST(test_tree_high_remove_root) {
+    CxTestingAllocator talloc;
+    cx_testing_allocator_init(&talloc);
+    CxAllocator *alloc = &talloc.base;
+
+    CX_TEST_DO {
+        CxTree *tree = cxTreeCreate(
+                alloc, tree_node_file_create_hl,
+                tree_node_file_search, tree_node_file_search_data,
+                tree_node_file_layout
+        );
+
+        const char *paths[] = {
+                "/",
+                "/usr/",
+                "/home/",
+                "/usr/lib/",
+                "/home/foo/",
+                "/home/foo/bar/"
+        };
+        cxTreeInsertArray(tree, paths, sizeof(const char*), 6);
+        void *root = tree->root;
+        cxTreeRemove(tree, root);
+        CX_TEST_ASSERT(tree->size == 0);
+        CX_TEST_ASSERT(tree->root == NULL);
+        CX_TEST_ASSERT(cxTreeDepth(tree) == 0);
+        cxTreeDestroy(tree);
+        CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
+        CxTree *w = cxTreeCreateWrapped(alloc, root, tree_node_file_layout);
+        w->advanced_destructor = (cx_destructor_func2) cxFree;
+        w->destructor_data = alloc;
+        cxTreeDestroy(w);
+        CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
+    }
+    cx_testing_allocator_destroy(&talloc);
+}
+
 static void test_tree_high_simple_destructor_func(void *node) {
     ((tree_node *)node)->data++;
 }
@@ -1855,6 +1892,7 @@
     cx_test_register(suite, test_tree_high_insert_one);
     cx_test_register(suite, test_tree_high_insert_many);
     cx_test_register(suite, test_tree_high_add_find_remove_nodes);
+    cx_test_register(suite, test_tree_high_remove_root);
     cx_test_register(suite, test_tree_high_simple_destructor);
 
     return suite;

mercurial