|
ucx
UAP Common Extensions
|
Interface for tree implementations. More...
Go to the source code of this file.
Data Structures | |
| struct | cx_tree_visitor_queue_s |
| An element in a visitor queue. More... | |
| struct | cx_tree_combined_iterator_s |
| An iterator (DFS) or visitor (BFS) for a tree. More... | |
| struct | cx_tree_node_base_s |
| Base structure that can be used for tree nodes in a CxTree. More... | |
| struct | cx_tree_s |
| Structure for holding the base data of a tree. More... | |
Macros | |
| #define | cxTreeIteratorContinue(iterator) |
| Advises the iterator to skip the subtree below the current node and also continues the current loop. | |
| #define | CX_TREE_SEARCH_INFINITE_DEPTH 0 |
| Macro that can be used instead of the magic value for infinite search depth. | |
| #define | CX_TREE_NODE(type) |
| Macro to roll out the cx_tree_node_base_s structure with a custom node type. | |
| #define | cx_tree_node_layout(struct_name) |
| Macro for specifying the layout of a tree node. | |
Typedefs | |
| typedef struct cx_tree_combined_iterator_s | CxTreeIterator |
| An iterator (DFS) or visitor (BFS) for a tree. | |
| typedef int(* | cx_tree_search_func) (const void *node, const void *data) |
| Function pointer for a search function. | |
| typedef struct cx_tree_s | CxTree |
| Structure for holding the base data of a tree. | |
| typedef void(* | cx_tree_relink_func) (void *node, const void *old_parent, const void *new_parent) |
| A function that is invoked when a node needs to be re-linked to a new parent. | |
Functions | |
| void | cxTreeIteratorDispose (CxTreeIterator *iter) |
| Releases internal memory of the given tree iterator. | |
| void | cx_tree_add (void *parent, void *node, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next) |
| Links a node to a (new) parent. | |
| void | cx_tree_remove (void *node, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next) |
| Unlinks a node from its parent. | |
| int | cx_tree_search (const void *root, size_t max_depth, const void *data, cx_tree_search_func sfunc, void **result, ptrdiff_t loc_children, ptrdiff_t loc_next) |
| Searches for data in a tree. | |
| CxTreeIterator | cx_tree_iterator (void *root, bool visit_on_exit, ptrdiff_t loc_children, ptrdiff_t loc_next) |
| Creates a depth-first iterator for a tree with the specified root node. | |
| CxTreeIterator | cx_tree_visitor (void *root, ptrdiff_t loc_children, ptrdiff_t loc_next) |
| Creates a breadth-first iterator for a tree with the specified root node. | |
| void | cxTreeDestroySubtree (CxTree *tree, void *node) |
| Destroys a node and its subtree. | |
| static void | cxTreeClear (CxTree *tree) |
| Destroys the tree contents. | |
| void | cxTreeFree (CxTree *tree) |
| Deallocates the tree structure. | |
| CxTree * | cxTreeCreate (const CxAllocator *allocator, size_t node_size, size_t elem_size, void *root, ptrdiff_t loc_data, ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, ptrdiff_t loc_prev, ptrdiff_t loc_next) |
| Creates a new tree. | |
| void * | cxTreeFindInSubtree (CxTree *tree, const void *data, void *subtree_root, size_t max_depth, bool use_dfs) |
| Searches the data in the specified subtree. | |
| static void * | cxTreeFind (CxTree *tree, const void *data, bool use_dfs) |
| Searches the data in the specified tree. | |
| void * | cxTreeFindFastInSubtree (CxTree *tree, const void *data, cx_tree_search_func sfunc, void *subtree_root, size_t max_depth) |
| Performs an efficient depth-first search in a branch of the specified tree. | |
| static void * | cxTreeFindFast (CxTree *tree, const void *data, cx_tree_search_func sfunc) |
| Performs an efficient depth-first search in the tree. | |
| size_t | cxTreeSubtreeSize (CxTree *tree, void *subtree_root) |
| Determines the size of the specified subtree. | |
| size_t | cxTreeSubtreeDepth (CxTree *tree, void *subtree_root) |
| Determines the depth of the specified subtree. | |
| size_t | cxTreeSize (CxTree *tree) |
| Determines the size of the entire tree. | |
| size_t | cxTreeDepth (CxTree *tree) |
| Determines the depth of the entire tree. | |
| CxTreeIterator | cxTreeIterateSubtree (CxTree *tree, void *node, bool visit_on_exit) |
Creates a depth-first iterator for the specified tree starting in node. | |
| CxTreeIterator | cxTreeVisitSubtree (CxTree *tree, void *node) |
Creates a breadth-first iterator for the specified tree starting in node. | |
| CxTreeIterator | cxTreeIterate (CxTree *tree, bool visit_on_exit) |
| Creates a depth-first iterator for the specified tree. | |
| CxTreeIterator | cxTreeVisit (CxTree *tree) |
| Creates a breadth-first iterator for the specified tree. | |
| void | cxTreeSetParent (CxTree *tree, void *parent, void *child) |
| Sets the (new) parent of the specified child. | |
| void | cxTreeAddNode (CxTree *tree, void *parent, void *child) |
| Adds a new node to the tree. | |
| void * | cxTreeAddData (CxTree *tree, void *parent, const void *data) |
| Creates a new node and adds it to the tree. | |
| void * | cxTreeCreateNode (CxTree *tree, void *parent) |
| Creates a new node and adds it to the tree. | |
| void * | cxTreeCreateRoot (CxTree *tree) |
| Creates a new root node or returns the existing root node. | |
| void * | cxTreeCreateRootData (CxTree *tree, const void *data) |
| Creates a new root node or uses the existing root node and writes the specified data to that node. | |
| void * | cxTreeSetRoot (CxTree *tree, void *new_root) |
| Exchanges the root of the tree. | |
| int | cxTreeRemoveNode (CxTree *tree, void *node, cx_tree_relink_func relink_func) |
| Removes a node and re-links its children to its former parent. | |
| void | cxTreeRemoveSubtree (CxTree *tree, void *node) |
| Removes a node and its subtree from the tree. | |
| int | cxTreeDestroyNode (CxTree *tree, void *node, cx_tree_relink_func relink_func) |
| Destroys a node and re-links its children to its former parent. | |
Interface for tree implementations.
| #define CX_TREE_NODE | ( | type | ) |
Macro to roll out the cx_tree_node_base_s structure with a custom node type.
Must be used as the first member in your custom tree struct.
| type | the data type for the nodes |
| #define cx_tree_node_layout | ( | struct_name | ) |
Macro for specifying the layout of a tree node.
When your tree uses CX_TREE_NODE, you can use this macro in all tree functions that expect the layout parameters loc_parent, loc_children, loc_last_child, loc_prev, and loc_next.
| struct_name | the name of the node structure |
| #define cxTreeIteratorContinue | ( | iterator | ) |
Advises the iterator to skip the subtree below the current node and also continues the current loop.
| iterator | (CxTreeIterator) the iterator |
| typedef void(* cx_tree_relink_func) (void *node, const void *old_parent, const void *new_parent) |
A function that is invoked when a node needs to be re-linked to a new parent.
When a node is re-linked, sometimes the contents need to be updated. This callback is invoked by cxTreeRemoveNode() and cxTreeDestroyNode() so that those updates can be applied when re-linking the children of the removed node.
| node | the affected node |
| old_parent | the old parent of the node |
| new_parent | the new parent of the node |
| typedef int(* cx_tree_search_func) (const void *node, const void *data) |
Function pointer for a search function.
A function of this kind shall check if the specified node contains the given data or if one of the children might contain the data.
The function should use the returned integer to indicate how close the match is, where a negative number means that it does not match at all. Zero means exact match and a positive number is an implementation defined measure for the distance to an exact match.
For example, consider a tree that stores file path information. A node which is describing a parent directory of a searched file shall return a positive number to indicate that a child node might contain the searched item. On the other hand, if the node denotes a path that is not a prefix of the searched filename, the function would return -1 to indicate that the search does not need to be continued in that branch.
| node | the node that is currently investigated |
| data | the data that is searched for |
| void cx_tree_add | ( | void * | parent, |
| void * | node, | ||
| ptrdiff_t | loc_parent, | ||
| ptrdiff_t | loc_children, | ||
| ptrdiff_t | loc_last_child, | ||
| ptrdiff_t | loc_prev, | ||
| ptrdiff_t | loc_next ) |
Links a node to a (new) parent.
If the node already has a parent, it is unlinked, first. If the parent has children already, the node is appended to the list of all currently existing children.
| parent | the parent node |
| node | the node that shall be linked |
| loc_parent | offset in the node struct for the parent pointer |
| loc_children | offset in the node struct for the children linked list |
| loc_last_child | optional offset in the node struct for the pointer to the last child in the linked list (negative if there is no such pointer) |
| loc_prev | optional offset in the node struct for the prev pointer |
| loc_next | offset in the node struct for the next pointer |
| CxTreeIterator cx_tree_iterator | ( | void * | root, |
| bool | visit_on_exit, | ||
| ptrdiff_t | loc_children, | ||
| ptrdiff_t | loc_next ) |
Creates a depth-first iterator for a tree with the specified root node.
| root | the root node |
| visit_on_exit | set to true, when the iterator shall visit a node again after processing all children |
| loc_children | offset in the node struct for the children linked list |
| loc_next | offset in the node struct for the next pointer |
| void cx_tree_remove | ( | void * | node, |
| ptrdiff_t | loc_parent, | ||
| ptrdiff_t | loc_children, | ||
| ptrdiff_t | loc_last_child, | ||
| ptrdiff_t | loc_prev, | ||
| ptrdiff_t | loc_next ) |
Unlinks a node from its parent.
If the node has no parent, this function does nothing.
| node | the node that shall be unlinked from its parent |
| loc_parent | offset in the node struct for the parent pointer |
| loc_children | offset in the node struct for the children linked list |
| loc_last_child | optional offset in the node struct for the pointer to the last child in the linked list (negative if there is no such pointer) |
| loc_prev | optional offset in the node struct for the prev pointer |
| loc_next | offset in the node struct for the next pointer |
| int cx_tree_search | ( | const void * | root, |
| size_t | max_depth, | ||
| const void * | data, | ||
| cx_tree_search_func | sfunc, | ||
| void ** | result, | ||
| ptrdiff_t | loc_children, | ||
| ptrdiff_t | loc_next ) |
Searches for data in a tree.
When the data cannot be found exactly, the search function might return the closest result, which might be a good starting point for adding a new node to the tree.
Depending on the tree structure, it is not necessarily guaranteed that the "closest" match is uniquely defined. This function will search for a node with the best match according to the sfunc (meaning: the return value of sfunc which is closest to zero). If that is also ambiguous, an arbitrary node matching the criteria is returned.
| root | the root node |
| max_depth | the maximum depth (zero=indefinite, one=just root) |
| data | the data to search for |
| sfunc | the search function |
| result | where the result shall be stored |
| loc_children | offset in the node struct for the children linked list |
| loc_next | offset in the node struct for the next pointer |
| CxTreeIterator cx_tree_visitor | ( | void * | root, |
| ptrdiff_t | loc_children, | ||
| ptrdiff_t | loc_next ) |
Creates a breadth-first iterator for a tree with the specified root node.
| root | the root node |
| loc_children | offset in the node struct for the children linked list |
| loc_next | offset in the node struct for the next pointer |
| void * cxTreeAddData | ( | CxTree * | tree, |
| void * | parent, | ||
| const void * | data ) |
Creates a new node and adds it to the tree.
| tree | the tree |
| parent | the parent node of the new node |
| data | the data that will be submitted to the create function |
NULL when the allocation failed | void cxTreeAddNode | ( | CxTree * | tree, |
| void * | parent, | ||
| void * | child ) |
Adds a new node to the tree.
If the child is already a member of the tree, the behavior is undefined. Use cxTreeSetParent() if you want to move a subtree to another location.
| tree | the tree |
| parent | the parent of the node to add |
| child | the node to add |
|
inlinestatic |
Destroys the tree contents.
It is guaranteed that the simple destructor is invoked before the advanced destructor, starting with the leaf nodes of the subtree.
This is a convenience macro for invoking cxTreeDestroySubtree() on the root node of the tree.
| tree | the tree |
| CxTree * cxTreeCreate | ( | const CxAllocator * | allocator, |
| size_t | node_size, | ||
| size_t | elem_size, | ||
| void * | root, | ||
| ptrdiff_t | loc_data, | ||
| ptrdiff_t | loc_parent, | ||
| ptrdiff_t | loc_children, | ||
| ptrdiff_t | loc_last_child, | ||
| ptrdiff_t | loc_prev, | ||
| ptrdiff_t | loc_next ) |
Creates a new tree.
The specified allocator will be used for creating the tree struct and the nodes.
When you do not specify an existing root, the tree will be created empty. Additionally, cxFree() is registered as the advanced destructor for the tree so that all nodes that you will add to the tree are automatically freed together with the tree. When root is not NULL, no destructors are registered automatically.
| allocator | the allocator to use (if NULL, the cxDefaultAllocator is assumed) |
| node_size | the complete size of one node |
| elem_size | the size of the payload stored in the node (CX_STORE_POINTERS is also supported) |
| root | an optional already existing root node |
| loc_data | optional offset in the node struct for the payload (when negative, cxTreeAddData() is not supported) |
| loc_parent | offset in the node struct for the parent pointer |
| loc_children | offset in the node struct for the children linked list |
| loc_last_child | optional offset in the node struct for the pointer to the last child in the linked list (negative if there is no such pointer) |
| loc_prev | optional offset in the node struct for the prev pointer |
| loc_next | offset in the node struct for the next pointer |
| void * cxTreeCreateNode | ( | CxTree * | tree, |
| void * | parent ) |
Creates a new node and adds it to the tree.
| tree | the tree |
| parent | the parent node of the new node |
NULL when the allocation failed | void * cxTreeCreateRoot | ( | CxTree * | tree | ) |
Creates a new root node or returns the existing root node.
| tree | the tree |
NULL when the allocation failed | void * cxTreeCreateRootData | ( | CxTree * | tree, |
| const void * | data ) |
Creates a new root node or uses the existing root node and writes the specified data to that node.
NULL when loc_data was not initialized with a positive value.| tree | the tree |
| data | the data for the root node |
NULL when the allocation failed or the data location is not known | size_t cxTreeDepth | ( | CxTree * | tree | ) |
Determines the depth of the entire tree.
| tree | the tree |
| int cxTreeDestroyNode | ( | CxTree * | tree, |
| void * | node, | ||
| cx_tree_relink_func | relink_func ) |
Destroys a node and re-links its children to its former parent.
If the node is not part of the tree, the behavior is undefined.
It is guaranteed that the simple destructor is invoked before the advanced destructor.
| tree | the tree |
| node | the node to destroy (must not be the root node) |
| relink_func | optional callback to update the content of each re-linked node |
node is the root node of the tree | void cxTreeDestroySubtree | ( | CxTree * | tree, |
| void * | node ) |
Destroys a node and its subtree.
It is guaranteed that the simple destructor is invoked before the advanced destructor, starting with the leaf nodes of the subtree.
When this function is invoked on the root node of the tree, it destroys the tree contents, but - in contrast to cxTreeFree() - not the tree structure, leaving an empty tree behind.
| tree | the tree |
| node | the node being the root of the subtree to remove |
|
inlinestatic |
Searches the data in the specified tree.
loc_data is not available, this function immediately returns NULL.| tree | the tree |
| data | the data to search for |
| use_dfs | true when depth-first search should be used; false when breadth-first search should be used |
NULL when the data cannot be found
|
inlinestatic |
Performs an efficient depth-first search in the tree.
| tree | the tree |
| data | the data to search for |
| sfunc | the search function |
NULL when the data cannot be found | void * cxTreeFindFastInSubtree | ( | CxTree * | tree, |
| const void * | data, | ||
| cx_tree_search_func | sfunc, | ||
| void * | subtree_root, | ||
| size_t | max_depth ) |
Performs an efficient depth-first search in a branch of the specified tree.
When max_depth is zero, the depth is not limited. The subtree_root itself is on depth 1 and its children have depth 2.
subtree_root is not NULL and not part of the tree, the behavior is undefined.| tree | the tree |
| data | the data to search for |
| sfunc | the search function |
| subtree_root | the node where to start (NULL to start from root) |
| max_depth | the maximum search depth |
NULL when the data cannot be found | void * cxTreeFindInSubtree | ( | CxTree * | tree, |
| const void * | data, | ||
| void * | subtree_root, | ||
| size_t | max_depth, | ||
| bool | use_dfs ) |
Searches the data in the specified subtree.
When max_depth is zero, the depth is not limited. The subtree_root itself is on depth 1 and its children have depth 2.
subtree_root is not NULL and not part of the tree, the behavior is undefined.loc_data is not available, this function immediately returns NULL.| tree | the tree |
| data | the data to search for |
| subtree_root | the node where to start (NULL to start from root) |
| max_depth | the maximum search depth |
| use_dfs | true when depth-first search should be used; false when breadth-first search should be used |
NULL when the data cannot be found | void cxTreeFree | ( | CxTree * | tree | ) |
Deallocates the tree structure.
The destructor functions are invoked for each node, starting with the leaf nodes. It is guaranteed that for each node the simple destructor is invoked before the advanced destructor.
| tree | the tree to free |
| CxTreeIterator cxTreeIterate | ( | CxTree * | tree, |
| bool | visit_on_exit ) |
Creates a depth-first iterator for the specified tree.
| tree | the tree to iterate |
| visit_on_exit | true, if the iterator shall visit a node again when leaving the subtree |
| CxTreeIterator cxTreeIterateSubtree | ( | CxTree * | tree, |
| void * | node, | ||
| bool | visit_on_exit ) |
Creates a depth-first iterator for the specified tree starting in node.
If the node is not part of the tree, the behavior is undefined.
| tree | the tree to iterate |
| node | the node where to start |
| visit_on_exit | true, if the iterator shall visit a node again when leaving the subtree |
| void cxTreeIteratorDispose | ( | CxTreeIterator * | iter | ) |
Releases internal memory of the given tree iterator.
| iter | the iterator |
| int cxTreeRemoveNode | ( | CxTree * | tree, |
| void * | node, | ||
| cx_tree_relink_func | relink_func ) |
Removes a node and re-links its children to its former parent.
If the node is not part of the tree, the behavior is undefined.
| tree | the tree |
| node | the node to remove (must not be the root node) |
| relink_func | optional callback to update the content of each re-linked node |
node is the root node of the tree | void cxTreeRemoveSubtree | ( | CxTree * | tree, |
| void * | node ) |
Removes a node and its subtree from the tree.
If the node is not part of the tree, the behavior is undefined.
| tree | the tree |
| node | the node to remove |
| void cxTreeSetParent | ( | CxTree * | tree, |
| void * | parent, | ||
| void * | child ) |
Sets the (new) parent of the specified child.
If the child is not already a member of the tree, this function behaves as cxTreeAddNode().
| tree | the tree |
| parent | the (new) parent of the child |
| child | the node to add |
| void * cxTreeSetRoot | ( | CxTree * | tree, |
| void * | new_root ) |
Exchanges the root of the tree.
NULL root and setting the root with this function is not equivalent to creating the tree with a reference to an existing root because trees created without a root will have destructors registered.| tree | the tree |
| new_root | the new root node |
NULL when the tree was empty) | size_t cxTreeSize | ( | CxTree * | tree | ) |
Determines the size of the entire tree.
| tree | the tree |
| size_t cxTreeSubtreeDepth | ( | CxTree * | tree, |
| void * | subtree_root ) |
Determines the depth of the specified subtree.
| tree | the tree |
| subtree_root | the root node of the subtree |
subtree_root | size_t cxTreeSubtreeSize | ( | CxTree * | tree, |
| void * | subtree_root ) |
Determines the size of the specified subtree.
| tree | the tree |
| subtree_root | the root node of the subtree |
| CxTreeIterator cxTreeVisit | ( | CxTree * | tree | ) |
Creates a breadth-first iterator for the specified tree.
| tree | the tree to iterate |
| CxTreeIterator cxTreeVisitSubtree | ( | CxTree * | tree, |
| void * | node ) |
Creates a breadth-first iterator for the specified tree starting in node.
If the node is not part of the tree, the behavior is undefined.
| tree | the tree to iterate |
| node | the node where to start |