# HG changeset patch # User Mike Becker # Date 1744653200 -7200 # Node ID b00c6ae1441a733a3b1cf1eaa8871873df5ea196 # Parent 30d7ae76c76a68963ad783758ec956995b6a2da1 add cxTreeSize() - resolves #624 diff -r 30d7ae76c76a -r b00c6ae1441a CHANGELOG --- a/CHANGELOG Mon Apr 14 19:36:43 2025 +0200 +++ b/CHANGELOG Mon Apr 14 19:53:20 2025 +0200 @@ -5,6 +5,7 @@ * adds cxListSet() * adds cxListContains() * adds cxBufferShrink() + * adds cxTreeSize() * changes grow strategy for the mempory pool to reduce reallocations * changes grow strategy for CxBuffer, which does now take the page size into account * fixes errno value after failing cxBufferSeek() to be consistently EINVAL diff -r 30d7ae76c76a -r b00c6ae1441a docs/Writerside/topics/about.md --- a/docs/Writerside/topics/about.md Mon Apr 14 19:36:43 2025 +0200 +++ b/docs/Writerside/topics/about.md Mon Apr 14 19:53:20 2025 +0200 @@ -32,6 +32,7 @@ * adds cxListSet() * adds cxListContains() * adds cxBufferShrink() +* adds cxTreeSize() * changes grow strategy for the mempory pool to reduce reallocations * changes grow strategy for CxBuffer, which does now take the page size into account * fixes errno value after failing cxBufferSeek() to be consistently EINVAL diff -r 30d7ae76c76a -r b00c6ae1441a docs/Writerside/topics/tree.h.md --- a/docs/Writerside/topics/tree.h.md Mon Apr 14 19:36:43 2025 +0200 +++ b/docs/Writerside/topics/tree.h.md Mon Apr 14 19:53:20 2025 +0200 @@ -257,6 +257,8 @@ size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); +size_t cxTreeSize(CxTree *tree); + size_t cxTreeDepth(CxTree *tree); ``` @@ -265,15 +267,10 @@ The function `cxTreeSubtreeDepth()` reports the maximum depth of the subtree starting with `subtree_root`. If the `subtree_root` does not have any children, this results in a depth of one. -The function `cxTreeDepth()` is equivalent to `cxTreeSubtreeDepth()` where `subtree_root` is the root node of the entire tree. +The functions `cxTreeSize()` and `cxTreeDepth()` are equivalent to `cxTreeSubtreeSize()` and `cxTreeSubtreeDepth()`, respectively, where `subtree_root` is the root node of the entire tree. > Passing a `NULL` pointer as `subtree_root` makes those functions return zero. -> In the current UCX version there is no separate function `cxTreeSize()`, because -> the size attribute can be directly accessed in the `CxTree` structure. -> The next UCX version is planned to have also a function for accessing that attribute. ->{style="note"} - ## Search ```C diff -r 30d7ae76c76a -r b00c6ae1441a src/cx/tree.h --- a/src/cx/tree.h Mon Apr 14 19:36:43 2025 +0200 +++ b/src/cx/tree.h Mon Apr 14 19:53:20 2025 +0200 @@ -1188,6 +1188,18 @@ size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); /** + * Determines the size of the entire tree. + * + * @param tree the tree + * @return the tree size, counting the root as one + */ +cx_attr_nonnull +cx_attr_nodiscard +static inline size_t cxTreeSize(CxTree *tree) { + return tree->size; +} + +/** * Determines the depth of the entire tree. * * @param tree the tree diff -r 30d7ae76c76a -r b00c6ae1441a tests/test_tree.c --- a/tests/test_tree.c Mon Apr 14 19:36:43 2025 +0200 +++ b/tests/test_tree.c Mon Apr 14 19:53:20 2025 +0200 @@ -1909,9 +1909,9 @@ result |= cxTreeInsert(tree, "/home/foo/"); CX_TEST_ASSERT(result == 0); CX_TEST_ASSERT(1 == cxTreeInsertArray(tree, "/home/foo/bar/", sizeof(const char*), 1)); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(0 != cxTreeInsert(tree, "newroot")); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(talloc.alloc_total == 8); CX_TEST_ASSERT(talloc.free_total == 1); // the one that could not be added @@ -1944,7 +1944,7 @@ "newroot" }; CX_TEST_ASSERT(6 == cxTreeInsertArray(tree, paths, sizeof(const char*), 7)); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(talloc.alloc_total == 8); CX_TEST_ASSERT(talloc.free_total == 1); // the one that could not be added @@ -1996,7 +1996,7 @@ CX_TEST_ASSERT(0 == strcmp("/home/foo/", foo->path)); CX_TEST_ASSERT(NULL != foo->parent); CX_TEST_ASSERT(0 == strcmp("/home/", foo->parent->path)); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(0 == cxTreeAddChild(tree, foo->parent, "/home/baz/")); tree_node_file *baz = cxTreeFind(tree, "/home/baz/"); @@ -2004,7 +2004,7 @@ CX_TEST_ASSERT(0 == strcmp("/home/baz/", baz->path)); CX_TEST_ASSERT(NULL != baz->parent); CX_TEST_ASSERT(0 == strcmp("/home/", baz->parent->path)); - CX_TEST_ASSERT(tree->size == 7); + CX_TEST_ASSERT(cxTreeSize(tree) == 7); tree_node_file *home = cxTreeFind(tree, "/home/"); CX_TEST_ASSERT(NULL == cxTreeFindInSubtree(tree, "/usr/", foo, 0)); @@ -2017,10 +2017,10 @@ share->path = "/usr/share/"; tree_node_file *usr = cxTreeFind(tree, "/usr/"); cxTreeAddChildNode(tree, usr, share); - CX_TEST_ASSERT(tree->size == 8); + CX_TEST_ASSERT(cxTreeSize(tree) == 8); cxTreeRemoveSubtree(tree, foo); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(foo->children == bar); CX_TEST_ASSERT(foo->last_child == bar); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/")); @@ -2028,7 +2028,7 @@ CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/bar/")); CX_TEST_ASSERT(0 == cxTreeRemoveNode(tree, usr, test_tree_remove_node_relink_mock)); - CX_TEST_ASSERT(tree->size == 5); + CX_TEST_ASSERT(cxTreeSize(tree) == 5); CX_TEST_ASSERT(usr->parent == NULL); CX_TEST_ASSERT(usr->children == NULL); CX_TEST_ASSERT(usr->last_child == NULL); @@ -2087,7 +2087,7 @@ CX_TEST_ASSERT(0 == strcmp("/home/foo/", foo->path)); CX_TEST_ASSERT(NULL != foo->parent); CX_TEST_ASSERT(0 == strcmp("/home/", foo->parent->path)); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(0 == cxTreeAddChild(tree, foo->parent, "/home/baz/")); tree_node_file *baz = cxTreeFind(tree, "/home/baz/"); @@ -2095,7 +2095,7 @@ CX_TEST_ASSERT(0 == strcmp("/home/baz/", baz->path)); CX_TEST_ASSERT(NULL != baz->parent); CX_TEST_ASSERT(0 == strcmp("/home/", baz->parent->path)); - CX_TEST_ASSERT(tree->size == 7); + CX_TEST_ASSERT(cxTreeSize(tree) == 7); tree_node_file *home = cxTreeFind(tree, "/home/"); CX_TEST_ASSERT(NULL == cxTreeFindInSubtree(tree, "/usr/", foo, 0)); @@ -2108,16 +2108,16 @@ share->path = "/usr/share/"; tree_node_file *usr = cxTreeFind(tree, "/usr/"); cxTreeAddChildNode(tree, usr, share); - CX_TEST_ASSERT(tree->size == 8); + CX_TEST_ASSERT(cxTreeSize(tree) == 8); cxTreeDestroySubtree(tree, foo); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/")); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/foo/bar/")); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/home/bar/")); CX_TEST_ASSERT(0 == cxTreeDestroyNode(tree, usr, test_tree_remove_node_relink_mock)); - CX_TEST_ASSERT(tree->size == 5); + CX_TEST_ASSERT(cxTreeSize(tree) == 5); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/")); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/lib/")); CX_TEST_ASSERT(NULL == cxTreeFind(tree, "/usr/share/")); @@ -2160,12 +2160,12 @@ void *root = tree->root; CX_TEST_ASSERT(0 != cxTreeRemoveNode(tree, root, NULL)); CX_TEST_ASSERT(tree->root == root); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); CX_TEST_ASSERT(0 != cxTreeDestroyNode(tree, root, NULL)); CX_TEST_ASSERT(tree->root == root); - CX_TEST_ASSERT(tree->size == 6); + CX_TEST_ASSERT(cxTreeSize(tree) == 6); cxTreeRemoveSubtree(tree, root); - CX_TEST_ASSERT(tree->size == 0); + CX_TEST_ASSERT(cxTreeSize(tree) == 0); CX_TEST_ASSERT(tree->root == NULL); CX_TEST_ASSERT(cxTreeDepth(tree) == 0); cxTreeFree(tree);