| 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
| 27 */ |
27 */ |
| 28 /** |
28 /** |
| 29 * \file tree.h |
29 * @file tree.h |
| 30 * \brief Interface for tree implementations. |
30 * @brief Interface for tree implementations. |
| 31 * \author Mike Becker |
31 * @author Mike Becker |
| 32 * \author Olaf Wintermann |
32 * @author Olaf Wintermann |
| 33 * \copyright 2-Clause BSD License |
33 * @copyright 2-Clause BSD License |
| 34 */ |
34 */ |
| 35 |
35 |
| 36 #ifndef UCX_TREE_H |
36 #ifndef UCX_TREE_H |
| 37 #define UCX_TREE_H |
37 #define UCX_TREE_H |
| 38 |
38 |
| 231 |
231 |
| 232 /** |
232 /** |
| 233 * Advises the iterator to skip the subtree below the current node and |
233 * Advises the iterator to skip the subtree below the current node and |
| 234 * also continues the current loop. |
234 * also continues the current loop. |
| 235 * |
235 * |
| 236 * @param iterator the iterator |
236 * @param iterator (@c CxTreeIterator) the iterator |
| 237 */ |
237 */ |
| 238 #define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue |
238 #define cxTreeIteratorContinue(iterator) (iterator).skip = true; continue |
| 239 |
239 |
| 240 /** |
240 /** |
| 241 * Advises the visitor to skip the subtree below the current node and |
241 * Advises the visitor to skip the subtree below the current node and |
| 242 * also continues the current loop. |
242 * also continues the current loop. |
| 243 * |
243 * |
| 244 * @param visitor the visitor |
244 * @param visitor (@c CxTreeVisitor) the visitor |
| 245 */ |
245 */ |
| 246 #define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor) |
246 #define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor) |
| 247 |
247 |
| 248 /** |
248 /** |
| 249 * Links a node to a (new) parent. |
249 * Links a node to a (new) parent. |
| 250 * |
250 * |
| 251 * If the node has already a parent, it is unlinked, first. |
251 * If the node has already a parent, it is unlinked, first. |
| 252 * If the parent has children already, the node is \em appended to the list |
252 * If the parent has children already, the node is @em appended to the list |
| 253 * of all currently existing children. |
253 * of all currently existing children. |
| 254 * |
254 * |
| 255 * @param parent the parent node |
255 * @param parent the parent node |
| 256 * @param node the node that shall be linked |
256 * @param node the node that shall be linked |
| 257 * @param loc_parent offset in the node struct for the parent pointer |
257 * @param loc_parent offset in the node struct for the parent pointer |
| 303 #define CX_TREE_SEARCH_INFINITE_DEPTH 0 |
305 #define CX_TREE_SEARCH_INFINITE_DEPTH 0 |
| 304 |
306 |
| 305 /** |
307 /** |
| 306 * Function pointer for a search function. |
308 * Function pointer for a search function. |
| 307 * |
309 * |
| 308 * A function of this kind shall check if the specified \p node |
310 * A function of this kind shall check if the specified @p node |
| 309 * contains the given \p data or if one of the children might contain |
311 * contains the given @p data or if one of the children might contain |
| 310 * the data. |
312 * the data. |
| 311 * |
313 * |
| 312 * The function should use the returned integer to indicate how close the |
314 * The function should use the returned integer to indicate how close the |
| 313 * match is, where a negative number means that it does not match at all. |
315 * match is, where a negative number means that it does not match at all. |
| 314 * Zero means exact match and a positive number is an implementation defined |
316 * Zero means exact match and a positive number is an implementation defined |
| 352 * that the search does not need to be continued in that branch. |
354 * that the search does not need to be continued in that branch. |
| 353 * |
355 * |
| 354 * @param node the node that is currently investigated |
356 * @param node the node that is currently investigated |
| 355 * @param new_node a new node with the information which is searched |
357 * @param new_node a new node with the information which is searched |
| 356 * |
358 * |
| 357 * @return 0 if \p node contains the same data as \p new_node, |
359 * @return 0 if @p node contains the same data as @p new_node, |
| 358 * positive if one of the children might contain the data, |
360 * positive if one of the children might contain the data, |
| 359 * negative if neither the node, nor the children contains the data |
361 * negative if neither the node, nor the children contains the data |
| 360 */ |
362 */ |
| 361 cx_attr_nonnull |
363 cx_attr_nonnull |
| 362 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); |
364 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); |
| 368 * closest result which might be a good starting point for adding a new node |
370 * closest result which might be a good starting point for adding a new node |
| 369 * to the tree (see also #cx_tree_add()). |
371 * to the tree (see also #cx_tree_add()). |
| 370 * |
372 * |
| 371 * Depending on the tree structure it is not necessarily guaranteed that the |
373 * Depending on the tree structure it is not necessarily guaranteed that the |
| 372 * "closest" match is uniquely defined. This function will search for a node |
374 * "closest" match is uniquely defined. This function will search for a node |
| 373 * with the best match according to the \p sfunc (meaning: the return value of |
375 * with the best match according to the @p sfunc (meaning: the return value of |
| 374 * \p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
376 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
| 375 * node matching the criteria is returned. |
377 * node matching the criteria is returned. |
| 376 * |
378 * |
| 377 * @param root the root node |
379 * @param root the root node |
| 378 * @param depth the maximum depth (zero=indefinite, one=just root) |
380 * @param depth the maximum depth (zero=indefinite, one=just root) |
| 379 * @param data the data to search for |
381 * @param data the data to search for |
| 404 * return a closest result which might be a good starting point for adding the |
407 * return a closest result which might be a good starting point for adding the |
| 405 * new node to the tree (see also #cx_tree_add()). |
408 * new node to the tree (see also #cx_tree_add()). |
| 406 * |
409 * |
| 407 * Depending on the tree structure it is not necessarily guaranteed that the |
410 * Depending on the tree structure it is not necessarily guaranteed that the |
| 408 * "closest" match is uniquely defined. This function will search for a node |
411 * "closest" match is uniquely defined. This function will search for a node |
| 409 * with the best match according to the \p sfunc (meaning: the return value of |
412 * with the best match according to the @p sfunc (meaning: the return value of |
| 410 * \p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
413 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary |
| 411 * node matching the criteria is returned. |
414 * node matching the criteria is returned. |
| 412 * |
415 * |
| 413 * @param root the root node |
416 * @param root the root node |
| 414 * @param depth the maximum depth (zero=indefinite, one=just root) |
417 * @param depth the maximum depth (zero=indefinite, one=just root) |
| 415 * @param node the node to search for |
418 * @param node the node to search for |
| 489 /** |
495 /** |
| 490 * Describes a function that creates a tree node from the specified data. |
496 * Describes a function that creates a tree node from the specified data. |
| 491 * The first argument points to the data the node shall contain and |
497 * The first argument points to the data the node shall contain and |
| 492 * the second argument may be used for additional data (e.g. an allocator). |
498 * the second argument may be used for additional data (e.g. an allocator). |
| 493 * Functions of this type shall either return a new pointer to a newly |
499 * Functions of this type shall either return a new pointer to a newly |
| 494 * created node or \c NULL when allocation fails. |
500 * created node or @c NULL when allocation fails. |
| 495 * |
501 * |
| 496 * \note the function may leave the node pointers in the struct uninitialized. |
502 * @note the function may leave the node pointers in the struct uninitialized. |
| 497 * The caller is responsible to set them according to the intended use case. |
503 * The caller is responsible to set them according to the intended use case. |
| 498 */ |
504 */ |
| 499 cx_attr_nonnull_arg(1) |
505 cx_attr_nonnull_arg(1) |
| 500 typedef void *(*cx_tree_node_create_func)(const void *, void *); |
506 typedef void *(*cx_tree_node_create_func)(const void *, void *); |
| 501 |
507 |
| 503 * The local search depth for a new subtree when adding multiple elements. |
509 * The local search depth for a new subtree when adding multiple elements. |
| 504 * The default value is 3. |
510 * The default value is 3. |
| 505 * This variable is used by #cx_tree_add_array() and #cx_tree_add_iter() to |
511 * This variable is used by #cx_tree_add_array() and #cx_tree_add_iter() to |
| 506 * implement optimized insertion of multiple elements into a tree. |
512 * implement optimized insertion of multiple elements into a tree. |
| 507 */ |
513 */ |
| |
514 cx_attr_export |
| 508 extern unsigned int cx_tree_add_look_around_depth; |
515 extern unsigned int cx_tree_add_look_around_depth; |
| 509 |
516 |
| 510 /** |
517 /** |
| 511 * Adds multiple elements efficiently to a tree. |
518 * Adds multiple elements efficiently to a tree. |
| 512 * |
519 * |
| 513 * Once an element cannot be added to the tree, this function returns, leaving |
520 * Once an element cannot be added to the tree, this function returns, leaving |
| 514 * the iterator in a valid state pointing to the element that could not be |
521 * the iterator in a valid state pointing to the element that could not be |
| 515 * added. |
522 * added. |
| 516 * Also, the pointer of the created node will be stored to \p failed. |
523 * Also, the pointer of the created node will be stored to @p failed. |
| 517 * The integer returned by this function denotes the number of elements obtained |
524 * The integer returned by this function denotes the number of elements obtained |
| 518 * from the \p iter that have been successfully processed. |
525 * from the @p iter that have been successfully processed. |
| 519 * When all elements could be processed, a \c NULL pointer will be written to |
526 * When all elements could be processed, a @c NULL pointer will be written to |
| 520 * \p failed. |
527 * @p failed. |
| 521 * |
528 * |
| 522 * The advantage of this function compared to multiple invocations of |
529 * The advantage of this function compared to multiple invocations of |
| 523 * #cx_tree_add() is that the search for the insert locations is not always |
530 * #cx_tree_add() is that the search for the insert locations is not always |
| 524 * started from the root node. |
531 * started from the root node. |
| 525 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes |
532 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes |
| 545 * @return the number of nodes created and added |
552 * @return the number of nodes created and added |
| 546 * @see cx_tree_add() |
553 * @see cx_tree_add() |
| 547 */ |
554 */ |
| 548 cx_attr_nonnull_arg(1, 3, 4, 6, 7) |
555 cx_attr_nonnull_arg(1, 3, 4, 6, 7) |
| 549 cx_attr_access_w(6) |
556 cx_attr_access_w(6) |
| |
557 cx_attr_export |
| 550 size_t cx_tree_add_iter( |
558 size_t cx_tree_add_iter( |
| 551 struct cx_iterator_base_s *iter, |
559 struct cx_iterator_base_s *iter, |
| 552 size_t num, |
560 size_t num, |
| 553 cx_tree_search_func sfunc, |
561 cx_tree_search_func sfunc, |
| 554 cx_tree_node_create_func cfunc, |
562 cx_tree_node_create_func cfunc, |
| 564 |
572 |
| 565 /** |
573 /** |
| 566 * Adds multiple elements efficiently to a tree. |
574 * Adds multiple elements efficiently to a tree. |
| 567 * |
575 * |
| 568 * Once an element cannot be added to the tree, this function returns, storing |
576 * Once an element cannot be added to the tree, this function returns, storing |
| 569 * the pointer of the created node to \p failed. |
577 * the pointer of the created node to @p failed. |
| 570 * The integer returned by this function denotes the number of elements from |
578 * The integer returned by this function denotes the number of elements from |
| 571 * the \p src array that have been successfully processed. |
579 * the @p src array that have been successfully processed. |
| 572 * When all elements could be processed, a \c NULL pointer will be written to |
580 * When all elements could be processed, a @c NULL pointer will be written to |
| 573 * \p failed. |
581 * @p failed. |
| 574 * |
582 * |
| 575 * The advantage of this function compared to multiple invocations of |
583 * The advantage of this function compared to multiple invocations of |
| 576 * #cx_tree_add() is that the search for the insert locations is not always |
584 * #cx_tree_add() is that the search for the insert locations is not always |
| 577 * started from the root node. |
585 * started from the root node. |
| 578 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes |
586 * Instead, the function checks #cx_tree_add_look_around_depth many parent nodes |
| 581 * again. |
589 * again. |
| 582 * |
590 * |
| 583 * Refer to the documentation of #cx_tree_add() for more details. |
591 * Refer to the documentation of #cx_tree_add() for more details. |
| 584 * |
592 * |
| 585 * @param src a pointer to the source data array |
593 * @param src a pointer to the source data array |
| 586 * @param num the number of elements in the \p src array |
594 * @param num the number of elements in the @p src array |
| 587 * @param elem_size the size of each element in the \p src array |
595 * @param elem_size the size of each element in the @p src array |
| 588 * @param sfunc a search function |
596 * @param sfunc a search function |
| 589 * @param cfunc a node creation function |
597 * @param cfunc a node creation function |
| 590 * @param cdata optional additional data |
598 * @param cdata optional additional data |
| 591 * @param failed location where the pointer to a failed node shall be stored |
599 * @param failed location where the pointer to a failed node shall be stored |
| 592 * @param root the root node of the tree |
600 * @param root the root node of the tree |
| 619 |
628 |
| 620 /** |
629 /** |
| 621 * Adds data to a tree. |
630 * Adds data to a tree. |
| 622 * |
631 * |
| 623 * An adequate location where to add the new tree node is searched with the |
632 * An adequate location where to add the new tree node is searched with the |
| 624 * specified \p sfunc. |
633 * specified @p sfunc. |
| 625 * |
634 * |
| 626 * When a location is found, the \p cfunc will be invoked with \p cdata. |
635 * When a location is found, the @p cfunc will be invoked with @p cdata. |
| 627 * |
636 * |
| 628 * The node returned by \p cfunc will be linked into the tree. |
637 * The node returned by @p cfunc will be linked into the tree. |
| 629 * When \p sfunc returned a positive integer, the new node will be linked as a |
638 * When @p sfunc returned a positive integer, the new node will be linked as a |
| 630 * child. The other children (now siblings of the new node) are then checked |
639 * child. The other children (now siblings of the new node) are then checked |
| 631 * with \p sfunc, whether they could be children of the new node and re-linked |
640 * with @p sfunc, whether they could be children of the new node and re-linked |
| 632 * accordingly. |
641 * accordingly. |
| 633 * |
642 * |
| 634 * When \p sfunc returned zero and the found node has a parent, the new |
643 * When @p sfunc returned zero and the found node has a parent, the new |
| 635 * node will be added as sibling - otherwise, the new node will be added |
644 * node will be added as sibling - otherwise, the new node will be added |
| 636 * as a child. |
645 * as a child. |
| 637 * |
646 * |
| 638 * When \p sfunc returned a negative value, the new node will not be added to |
647 * When @p sfunc returned a negative value, the new node will not be added to |
| 639 * the tree and this function returns a non-zero value. |
648 * the tree and this function returns a non-zero value. |
| 640 * The caller should check if \p cnode contains a node pointer and deal with the |
649 * The caller should check if @p cnode contains a node pointer and deal with the |
| 641 * node that could not be added. |
650 * node that could not be added. |
| 642 * |
651 * |
| 643 * This function also returns a non-zero value when \p cfunc tries to allocate |
652 * This function also returns a non-zero value when @p cfunc tries to allocate |
| 644 * a new node but fails to do so. In that case, the pointer stored to \p cnode |
653 * a new node but fails to do so. In that case, the pointer stored to @p cnode |
| 645 * will be \c NULL. |
654 * will be @c NULL. |
| 646 * |
655 * |
| 647 * Multiple elements can be added more efficiently with |
656 * Multiple elements can be added more efficiently with |
| 648 * #cx_tree_add_array() or #cx_tree_add_iter(). |
657 * #cx_tree_add_array() or #cx_tree_add_iter(). |
| 649 * |
658 * |
| 650 * @param src a pointer to the data |
659 * @param src a pointer to the data |
| 799 }; |
809 }; |
| 800 |
810 |
| 801 /** |
811 /** |
| 802 * Macro to roll out the #cx_tree_node_base_s structure with a custom |
812 * Macro to roll out the #cx_tree_node_base_s structure with a custom |
| 803 * node type. |
813 * node type. |
| |
814 * |
| |
815 * Must be used as first member in your custom tree struct. |
| |
816 * |
| |
817 * @param type the data type for the nodes |
| 804 */ |
818 */ |
| 805 #define CX_TREE_NODE_BASE(type) \ |
819 #define CX_TREE_NODE_BASE(type) \ |
| 806 type *parent; \ |
820 type *parent; \ |
| 807 type *children;\ |
821 type *children;\ |
| 808 type *last_child;\ |
822 type *last_child;\ |
| 809 type *prev;\ |
823 type *prev;\ |
| 810 type *next |
824 type *next |
| 811 |
825 |
| 812 /** |
826 /** |
| 813 * Macro for specifying the layout of a base node tree. |
827 * Macro for specifying the layout of a base node tree. |
| |
828 * |
| |
829 * When your tree uses #CX_TREE_NODE_BASE, you can use this |
| |
830 * macro in all tree functions that expect the layout parameters |
| |
831 * @c loc_parent, @c loc_children, @c loc_last_child, @c loc_prev, |
| |
832 * and @c loc_next. |
| 814 */ |
833 */ |
| 815 #define cx_tree_node_base_layout \ |
834 #define cx_tree_node_base_layout \ |
| 816 offsetof(struct cx_tree_node_base_s, parent),\ |
835 offsetof(struct cx_tree_node_base_s, parent),\ |
| 817 offsetof(struct cx_tree_node_base_s, children),\ |
836 offsetof(struct cx_tree_node_base_s, children),\ |
| 818 offsetof(struct cx_tree_node_base_s, last_child),\ |
837 offsetof(struct cx_tree_node_base_s, last_child),\ |
| 819 offsetof(struct cx_tree_node_base_s, prev), \ |
838 offsetof(struct cx_tree_node_base_s, prev), \ |
| 820 offsetof(struct cx_tree_node_base_s, next) |
839 offsetof(struct cx_tree_node_base_s, next) |
| 821 |
840 |
| 822 /** |
841 /** |
| 823 * Macro for obtaining the node pointer layout for a specific tree. |
|
| 824 */ |
|
| 825 #define cx_tree_node_layout(tree) \ |
|
| 826 (tree)->loc_parent,\ |
|
| 827 (tree)->loc_children,\ |
|
| 828 (tree)->loc_last_child,\ |
|
| 829 (tree)->loc_prev, \ |
|
| 830 (tree)->loc_next |
|
| 831 |
|
| 832 /** |
|
| 833 * The class definition for arbitrary trees. |
842 * The class definition for arbitrary trees. |
| 834 */ |
843 */ |
| 835 struct cx_tree_class_s { |
844 struct cx_tree_class_s { |
| 836 /** |
845 /** |
| 837 * Member function for inserting a single element. |
846 * Member function for inserting a single element. |
| 838 * |
847 * |
| 839 * Implementations SHALL NOT simply invoke \p insert_many as this comes |
848 * Implementations SHALL NOT simply invoke @p insert_many as this comes |
| 840 * with too much overhead. |
849 * with too much overhead. |
| 841 */ |
850 */ |
| 842 cx_attr_nonnull |
|
| 843 int (*insert_element)( |
851 int (*insert_element)( |
| 844 struct cx_tree_s *tree, |
852 struct cx_tree_s *tree, |
| 845 const void *data |
853 const void *data |
| 846 ); |
854 ); |
| 847 |
855 |
| 849 * Member function for inserting multiple elements. |
857 * Member function for inserting multiple elements. |
| 850 * |
858 * |
| 851 * Implementations SHALL avoid to perform a full search in the tree for |
859 * Implementations SHALL avoid to perform a full search in the tree for |
| 852 * every element even though the source data MAY be unsorted. |
860 * every element even though the source data MAY be unsorted. |
| 853 */ |
861 */ |
| 854 cx_attr_nonnull |
|
| 855 size_t (*insert_many)( |
862 size_t (*insert_many)( |
| 856 struct cx_tree_s *tree, |
863 struct cx_tree_s *tree, |
| 857 struct cx_iterator_base_s *iter, |
864 struct cx_iterator_base_s *iter, |
| 858 size_t n |
865 size_t n |
| 859 ); |
866 ); |
| 860 |
867 |
| 861 /** |
868 /** |
| 862 * Member function for finding a node. |
869 * Member function for finding a node. |
| 863 */ |
870 */ |
| 864 cx_attr_nonnull |
|
| 865 void *(*find)( |
871 void *(*find)( |
| 866 struct cx_tree_s *tree, |
872 struct cx_tree_s *tree, |
| 867 const void *subtree, |
873 const void *subtree, |
| 868 const void *data, |
874 const void *data, |
| 869 size_t depth |
875 size_t depth |
| 884 * |
890 * |
| 885 * When this function is invoked on the root node of the tree, it destroys the |
891 * When this function is invoked on the root node of the tree, it destroys the |
| 886 * tree contents, but - in contrast to #cxTreeFree() - not the tree |
892 * tree contents, but - in contrast to #cxTreeFree() - not the tree |
| 887 * structure, leaving an empty tree behind. |
893 * structure, leaving an empty tree behind. |
| 888 * |
894 * |
| 889 * \note The destructor function, if any, will \em not be invoked. That means |
895 * @note The destructor function, if any, will @em not be invoked. That means |
| 890 * you will need to free the removed subtree by yourself, eventually. |
896 * you will need to free the removed subtree by yourself, eventually. |
| 891 * |
897 * |
| 892 * \attention This function will not free the memory of the nodes with the |
898 * @attention This function will not free the memory of the nodes with the |
| 893 * tree's allocator, because that is usually done by the advanced destructor |
899 * tree's allocator, because that is usually done by the advanced destructor |
| 894 * and would therefore result in a double-free. |
900 * and would therefore result in a double-free. |
| 895 * |
901 * |
| 896 * @param tree the tree |
902 * @param tree the tree |
| 897 * @param node the node to remove |
903 * @param node the node to remove |
| 898 * @see cxTreeFree() |
904 * @see cxTreeFree() |
| 899 */ |
905 */ |
| 900 cx_attr_nonnull |
906 cx_attr_nonnull |
| |
907 cx_attr_export |
| 901 void cxTreeDestroySubtree(CxTree *tree, void *node); |
908 void cxTreeDestroySubtree(CxTree *tree, void *node); |
| 902 |
909 |
| 903 |
910 |
| 904 /** |
911 /** |
| 905 * Destroys the tree contents. |
912 * Destroys the tree contents. |
| 908 * the advanced destructor, starting with the leaf nodes of the subtree. |
915 * the advanced destructor, starting with the leaf nodes of the subtree. |
| 909 * |
916 * |
| 910 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the |
917 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the |
| 911 * root node of the tree. |
918 * root node of the tree. |
| 912 * |
919 * |
| 913 * \attention Be careful when calling this function when no destructor function |
920 * @attention Be careful when calling this function when no destructor function |
| 914 * is registered that actually frees the memory of nodes. In that case you will |
921 * is registered that actually frees the memory of nodes. In that case you will |
| 915 * need a reference to the (former) root node of the tree somewhere or |
922 * need a reference to the (former) root node of the tree somewhere or |
| 916 * otherwise you will be leaking memory. |
923 * otherwise you will be leaking memory. |
| 917 * |
924 * |
| 918 * @param tree the tree |
925 * @param tree the tree |
| 926 * The destructor functions are invoked for each node, starting with the leaf |
933 * The destructor functions are invoked for each node, starting with the leaf |
| 927 * nodes. |
934 * nodes. |
| 928 * It is guaranteed that for each node the simple destructor is invoked before |
935 * It is guaranteed that for each node the simple destructor is invoked before |
| 929 * the advanced destructor. |
936 * the advanced destructor. |
| 930 * |
937 * |
| 931 * \attention This function will only invoke the destructor functions |
938 * @attention This function will only invoke the destructor functions |
| 932 * on the nodes. |
939 * on the nodes. |
| 933 * It will NOT additionally free the nodes with the tree's allocator, because |
940 * It will NOT additionally free the nodes with the tree's allocator, because |
| 934 * that would cause a double-free in most scenarios where the advanced |
941 * that would cause a double-free in most scenarios where the advanced |
| 935 * destructor is already freeing the memory. |
942 * destructor is already freeing the memory. |
| 936 * |
943 * |
| 937 * @param tree the tree to free |
944 * @param tree the tree to free |
| 938 */ |
945 */ |
| 939 static inline void cxTreeFree(CxTree *tree) { |
946 cx_attr_export |
| 940 if (tree == NULL) return; |
947 void cxTreeFree(CxTree *tree); |
| 941 if (tree->root != NULL) { |
|
| 942 cxTreeClear(tree); |
|
| 943 } |
|
| 944 cxFree(tree->allocator, tree); |
|
| 945 } |
|
| 946 |
948 |
| 947 /** |
949 /** |
| 948 * Creates a new tree structure based on the specified layout. |
950 * Creates a new tree structure based on the specified layout. |
| 949 * |
951 * |
| 950 * The specified \p allocator will be used for creating the tree struct |
952 * The specified @p allocator will be used for creating the tree struct |
| 951 * and SHALL be used by \p create_func to allocate memory for the nodes. |
953 * and SHALL be used by @p create_func to allocate memory for the nodes. |
| 952 * |
954 * |
| 953 * \note This function will also register an advanced destructor which |
955 * @note This function will also register an advanced destructor which |
| 954 * will free the nodes with the allocator's free() method. |
956 * will free the nodes with the allocator's free() method. |
| 955 * |
957 * |
| 956 * @param allocator the allocator that shall be used |
958 * @param allocator the allocator that shall be used |
| 957 * (if \c NULL, a default stdlib allocator will be used) |
959 * (if @c NULL, a default stdlib allocator will be used) |
| 958 * @param create_func a function that creates new nodes |
960 * @param create_func a function that creates new nodes |
| 959 * @param search_func a function that compares two nodes |
961 * @param search_func a function that compares two nodes |
| 960 * @param search_data_func a function that compares a node with data |
962 * @param search_data_func a function that compares a node with data |
| 961 * @param loc_parent offset in the node struct for the parent pointer |
963 * @param loc_parent offset in the node struct for the parent pointer |
| 962 * @param loc_children offset in the node struct for the children linked list |
964 * @param loc_children offset in the node struct for the children linked list |
| 970 */ |
972 */ |
| 971 cx_attr_nonnull_arg(2, 3, 4) |
973 cx_attr_nonnull_arg(2, 3, 4) |
| 972 cx_attr_nodiscard |
974 cx_attr_nodiscard |
| 973 cx_attr_malloc |
975 cx_attr_malloc |
| 974 cx_attr_dealloc(cxTreeFree, 1) |
976 cx_attr_dealloc(cxTreeFree, 1) |
| |
977 cx_attr_export |
| 975 CxTree *cxTreeCreate( |
978 CxTree *cxTreeCreate( |
| 976 const CxAllocator *allocator, |
979 const CxAllocator *allocator, |
| 977 cx_tree_node_create_func create_func, |
980 cx_tree_node_create_func create_func, |
| 978 cx_tree_search_func search_func, |
981 cx_tree_search_func search_func, |
| 979 cx_tree_search_data_func search_data_func, |
982 cx_tree_search_data_func search_data_func, |
| 985 ); |
988 ); |
| 986 |
989 |
| 987 /** |
990 /** |
| 988 * Creates a new tree structure based on a default layout. |
991 * Creates a new tree structure based on a default layout. |
| 989 * |
992 * |
| 990 * Nodes created by \p create_func MUST contain #cx_tree_node_base_s as first |
993 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as first |
| 991 * member (or at least respect the default offsets specified in the tree |
994 * member (or at least respect the default offsets specified in the tree |
| 992 * struct) and they MUST be allocated with the specified allocator. |
995 * struct) and they MUST be allocated with the specified allocator. |
| 993 * |
996 * |
| 994 * \note This function will also register an advanced destructor which |
997 * @note This function will also register an advanced destructor which |
| 995 * will free the nodes with the allocator's free() method. |
998 * will free the nodes with the allocator's free() method. |
| 996 * |
999 * |
| 997 * @param allocator the allocator that shall be used |
1000 * @param allocator (@c CxAllocator*) the allocator that shall be used |
| 998 * @param create_func a function that creates new nodes |
1001 * @param create_func (@c cx_tree_node_create_func) a function that creates new nodes |
| 999 * @param search_func a function that compares two nodes |
1002 * @param search_func (@c cx_tree_search_func) a function that compares two nodes |
| 1000 * @param search_data_func a function that compares a node with data |
1003 * @param search_data_func (@c cx_tree_search_data_func) a function that compares a node with data |
| 1001 * @return the new tree |
1004 * @return (@c CxTree*) the new tree |
| 1002 * @see cxTreeCreate() |
1005 * @see cxTreeCreate() |
| 1003 */ |
1006 */ |
| 1004 #define cxTreeCreateSimple(\ |
1007 #define cxTreeCreateSimple(\ |
| 1005 allocator, create_func, search_func, search_data_func \ |
1008 allocator, create_func, search_func, search_data_func \ |
| 1006 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \ |
1009 ) cxTreeCreate(allocator, create_func, search_func, search_data_func, \ |
| 1007 cx_tree_node_base_layout) |
1010 cx_tree_node_base_layout) |
| 1008 |
1011 |
| 1009 /** |
1012 /** |
| 1010 * Creates a new tree structure based on an existing tree. |
1013 * Creates a new tree structure based on an existing tree. |
| 1011 * |
1014 * |
| 1012 * The specified \p allocator will be used for creating the tree struct. |
1015 * The specified @p allocator will be used for creating the tree struct. |
| 1013 * |
1016 * |
| 1014 * \attention This function will create an incompletely defined tree structure |
1017 * @attention This function will create an incompletely defined tree structure |
| 1015 * where neither the create function, the search function, nor a destructor |
1018 * where neither the create function, the search function, nor a destructor |
| 1016 * will be set. If you wish to use any of this functionality for the wrapped |
1019 * will be set. If you wish to use any of this functionality for the wrapped |
| 1017 * tree, you need to specify those functions afterwards. |
1020 * tree, you need to specify those functions afterwards. |
| 1018 * |
1021 * |
| 1019 * @param allocator the allocator that was used for nodes of the wrapped tree |
1022 * @param allocator the allocator that was used for nodes of the wrapped tree |
| 1020 * (if \c NULL, a default stdlib allocator is assumed) |
1023 * (if @c NULL, a default stdlib allocator is assumed) |
| 1021 * @param root the root node of the tree that shall be wrapped |
1024 * @param root the root node of the tree that shall be wrapped |
| 1022 * @param loc_parent offset in the node struct for the parent pointer |
1025 * @param loc_parent offset in the node struct for the parent pointer |
| 1023 * @param loc_children offset in the node struct for the children linked list |
1026 * @param loc_children offset in the node struct for the children linked list |
| 1024 * @param loc_last_child optional offset in the node struct for the pointer to |
1027 * @param loc_last_child optional offset in the node struct for the pointer to |
| 1025 * the last child in the linked list (negative if there is no such pointer) |
1028 * the last child in the linked list (negative if there is no such pointer) |
| 1043 ); |
1047 ); |
| 1044 |
1048 |
| 1045 /** |
1049 /** |
| 1046 * Inserts data into the tree. |
1050 * Inserts data into the tree. |
| 1047 * |
1051 * |
| 1048 * \remark For this function to work, the tree needs specified search and |
1052 * @remark For this function to work, the tree needs specified search and |
| 1049 * create functions, which might not be available for wrapped trees |
1053 * create functions, which might not be available for wrapped trees |
| 1050 * (see #cxTreeCreateWrapped()). |
1054 * (see #cxTreeCreateWrapped()). |
| 1051 * |
1055 * |
| 1052 * @param tree the tree |
1056 * @param tree the tree |
| 1053 * @param data the data to insert |
1057 * @param data the data to insert |
| 1054 * @return zero on success, non-zero on failure |
1058 * @retval zero success |
| |
1059 * @retval non-zero failure |
| 1055 */ |
1060 */ |
| 1056 cx_attr_nonnull |
1061 cx_attr_nonnull |
| 1057 static inline int cxTreeInsert( |
1062 static inline int cxTreeInsert( |
| 1058 CxTree *tree, |
1063 CxTree *tree, |
| 1059 const void *data |
1064 const void *data |
| 1074 * @return the number of elements that could be successfully inserted |
1079 * @return the number of elements that could be successfully inserted |
| 1075 */ |
1080 */ |
| 1076 cx_attr_nonnull |
1081 cx_attr_nonnull |
| 1077 static inline size_t cxTreeInsertIter( |
1082 static inline size_t cxTreeInsertIter( |
| 1078 CxTree *tree, |
1083 CxTree *tree, |
| 1079 struct cx_iterator_base_s *iter, |
1084 CxIteratorBase *iter, |
| 1080 size_t n |
1085 size_t n |
| 1081 ) { |
1086 ) { |
| 1082 return tree->cl->insert_many(tree, iter, n); |
1087 return tree->cl->insert_many(tree, iter, n); |
| 1083 } |
1088 } |
| 1084 |
1089 |
| 1085 /** |
1090 /** |
| 1086 * Inserts an array of data efficiently into the tree. |
1091 * Inserts an array of data efficiently into the tree. |
| 1087 * |
1092 * |
| 1088 * \remark For this function to work, the tree needs specified search and |
1093 * @remark For this function to work, the tree needs specified search and |
| 1089 * create functions, which might not be available for wrapped trees |
1094 * create functions, which might not be available for wrapped trees |
| 1090 * (see #cxTreeCreateWrapped()). |
1095 * (see #cxTreeCreateWrapped()). |
| 1091 * |
1096 * |
| 1092 * @param tree the tree |
1097 * @param tree the tree |
| 1093 * @param data the array of data to insert |
1098 * @param data the array of data to insert |
| 1109 } |
1114 } |
| 1110 |
1115 |
| 1111 /** |
1116 /** |
| 1112 * Searches the data in the specified tree. |
1117 * Searches the data in the specified tree. |
| 1113 * |
1118 * |
| 1114 * \remark For this function to work, the tree needs a specified \c search_data |
1119 * @remark For this function to work, the tree needs a specified @c search_data |
| 1115 * function, which might not be available wrapped trees |
1120 * function, which might not be available wrapped trees |
| 1116 * (see #cxTreeCreateWrapped()). |
1121 * (see #cxTreeCreateWrapped()). |
| 1117 * |
1122 * |
| 1118 * @param tree the tree |
1123 * @param tree the tree |
| 1119 * @param data the data to search for |
1124 * @param data the data to search for |
| 1120 * @return the first matching node, or \c NULL when the data cannot be found |
1125 * @return the first matching node, or @c NULL when the data cannot be found |
| 1121 */ |
1126 */ |
| 1122 cx_attr_nonnull |
1127 cx_attr_nonnull |
| 1123 cx_attr_nodiscard |
1128 cx_attr_nodiscard |
| 1124 static inline void *cxTreeFind( |
1129 static inline void *cxTreeFind( |
| 1125 CxTree *tree, |
1130 CxTree *tree, |
| 1129 } |
1134 } |
| 1130 |
1135 |
| 1131 /** |
1136 /** |
| 1132 * Searches the data in the specified subtree. |
1137 * Searches the data in the specified subtree. |
| 1133 * |
1138 * |
| 1134 * When \p max_depth is zero, the depth is not limited. |
1139 * When @p max_depth is zero, the depth is not limited. |
| 1135 * The \p subtree_root itself is on depth 1 and its children have depth 2. |
1140 * The @p subtree_root itself is on depth 1 and its children have depth 2. |
| 1136 * |
1141 * |
| 1137 * \note When \p subtree_root is not part of the \p tree, the behavior is |
1142 * @note When @p subtree_root is not part of the @p tree, the behavior is |
| 1138 * undefined. |
1143 * undefined. |
| 1139 * |
1144 * |
| 1140 * \remark For this function to work, the tree needs a specified \c search_data |
1145 * @remark For this function to work, the tree needs a specified @c search_data |
| 1141 * function, which might not be the case for wrapped trees |
1146 * function, which might not be the case for wrapped trees |
| 1142 * (see #cxTreeCreateWrapped()). |
1147 * (see #cxTreeCreateWrapped()). |
| 1143 * |
1148 * |
| 1144 * @param tree the tree |
1149 * @param tree the tree |
| 1145 * @param data the data to search for |
1150 * @param data the data to search for |
| 1146 * @param subtree_root the node where to start |
1151 * @param subtree_root the node where to start |
| 1147 * @param max_depth the maximum search depth |
1152 * @param max_depth the maximum search depth |
| 1148 * @return the first matching node, or \c NULL when the data cannot be found |
1153 * @return the first matching node, or @c NULL when the data cannot be found |
| 1149 */ |
1154 */ |
| 1150 cx_attr_nonnull |
1155 cx_attr_nonnull |
| 1151 cx_attr_nodiscard |
1156 cx_attr_nodiscard |
| 1152 static inline void *cxTreeFindInSubtree( |
1157 static inline void *cxTreeFindInSubtree( |
| 1153 CxTree *tree, |
1158 CxTree *tree, |
| 1165 * @param subtree_root the root node of the subtree |
1170 * @param subtree_root the root node of the subtree |
| 1166 * @return the number of nodes in the specified subtree |
1171 * @return the number of nodes in the specified subtree |
| 1167 */ |
1172 */ |
| 1168 cx_attr_nonnull |
1173 cx_attr_nonnull |
| 1169 cx_attr_nodiscard |
1174 cx_attr_nodiscard |
| |
1175 cx_attr_export |
| 1170 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
1176 size_t cxTreeSubtreeSize(CxTree *tree, void *subtree_root); |
| 1171 |
1177 |
| 1172 /** |
1178 /** |
| 1173 * Determines the depth of the specified subtree. |
1179 * Determines the depth of the specified subtree. |
| 1174 * |
1180 * |
| 1175 * @param tree the tree |
1181 * @param tree the tree |
| 1176 * @param subtree_root the root node of the subtree |
1182 * @param subtree_root the root node of the subtree |
| 1177 * @return the tree depth including the \p subtree_root |
1183 * @return the tree depth including the @p subtree_root |
| 1178 */ |
1184 */ |
| 1179 cx_attr_nonnull |
1185 cx_attr_nonnull |
| 1180 cx_attr_nodiscard |
1186 cx_attr_nodiscard |
| |
1187 cx_attr_export |
| 1181 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
1188 size_t cxTreeSubtreeDepth(CxTree *tree, void *subtree_root); |
| 1182 |
1189 |
| 1183 /** |
1190 /** |
| 1184 * Determines the depth of the entire tree. |
1191 * Determines the depth of the entire tree. |
| 1185 * |
1192 * |
| 1186 * @param tree the tree |
1193 * @param tree the tree |
| 1187 * @return the tree depth, counting the root as one |
1194 * @return the tree depth, counting the root as one |
| 1188 */ |
1195 */ |
| 1189 cx_attr_nonnull |
1196 cx_attr_nonnull |
| 1190 cx_attr_nodiscard |
1197 cx_attr_nodiscard |
| |
1198 cx_attr_export |
| 1191 size_t cxTreeDepth(CxTree *tree); |
1199 size_t cxTreeDepth(CxTree *tree); |
| 1192 |
1200 |
| 1193 /** |
1201 /** |
| 1194 * Creates a depth-first iterator for the specified tree starting in \p node. |
1202 * Creates a depth-first iterator for the specified tree starting in @p node. |
| 1195 * |
1203 * |
| 1196 * If the node is not part of the tree, the behavior is undefined. |
1204 * If the node is not part of the tree, the behavior is undefined. |
| 1197 * |
1205 * |
| 1198 * @param tree the tree to iterate |
1206 * @param tree the tree to iterate |
| 1199 * @param node the node where to start |
1207 * @param node the node where to start |
| 1265 } |
1273 } |
| 1266 |
1274 |
| 1267 /** |
1275 /** |
| 1268 * Sets the (new) parent of the specified child. |
1276 * Sets the (new) parent of the specified child. |
| 1269 * |
1277 * |
| 1270 * If the \p child is not already member of the tree, this function behaves |
1278 * If the @p child is not already member of the tree, this function behaves |
| 1271 * as #cxTreeAddChildNode(). |
1279 * as #cxTreeAddChildNode(). |
| 1272 * |
1280 * |
| 1273 * @param tree the tree |
1281 * @param tree the tree |
| 1274 * @param parent the (new) parent of the child |
1282 * @param parent the (new) parent of the child |
| 1275 * @param child the node to add |
1283 * @param child the node to add |
| 1276 * @see cxTreeAddChildNode() |
1284 * @see cxTreeAddChildNode() |
| 1277 */ |
1285 */ |
| 1278 cx_attr_nonnull |
1286 cx_attr_nonnull |
| |
1287 cx_attr_export |
| 1279 void cxTreeSetParent( |
1288 void cxTreeSetParent( |
| 1280 CxTree *tree, |
1289 CxTree *tree, |
| 1281 void *parent, |
1290 void *parent, |
| 1282 void *child |
1291 void *child |
| 1283 ); |
1292 ); |
| 1284 |
1293 |
| 1285 /** |
1294 /** |
| 1286 * Adds a new node to the tree. |
1295 * Adds a new node to the tree. |
| 1287 * |
1296 * |
| 1288 * If the \p child is already member of the tree, the behavior is undefined. |
1297 * If the @p child is already member of the tree, the behavior is undefined. |
| 1289 * Use #cxTreeSetParent() if you want to move a subtree to another location. |
1298 * Use #cxTreeSetParent() if you want to move a subtree to another location. |
| 1290 * |
1299 * |
| 1291 * \attention The node may be externally created, but MUST obey the same rules |
1300 * @attention The node may be externally created, but MUST obey the same rules |
| 1292 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use |
1301 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use |
| 1293 * the same allocator). |
1302 * the same allocator). |
| 1294 * |
1303 * |
| 1295 * @param tree the tree |
1304 * @param tree the tree |
| 1296 * @param parent the parent of the node to add |
1305 * @param parent the parent of the node to add |
| 1297 * @param child the node to add |
1306 * @param child the node to add |
| 1298 * @see cxTreeSetParent() |
1307 * @see cxTreeSetParent() |
| 1299 */ |
1308 */ |
| 1300 cx_attr_nonnull |
1309 cx_attr_nonnull |
| |
1310 cx_attr_export |
| 1301 void cxTreeAddChildNode( |
1311 void cxTreeAddChildNode( |
| 1302 CxTree *tree, |
1312 CxTree *tree, |
| 1303 void *parent, |
1313 void *parent, |
| 1304 void *child |
1314 void *child |
| 1305 ); |
1315 ); |
| 1350 /** |
1361 /** |
| 1351 * Removes a node and re-links its children to its former parent. |
1362 * Removes a node and re-links its children to its former parent. |
| 1352 * |
1363 * |
| 1353 * If the node is not part of the tree, the behavior is undefined. |
1364 * If the node is not part of the tree, the behavior is undefined. |
| 1354 * |
1365 * |
| 1355 * \note The destructor function, if any, will \em not be invoked. That means |
1366 * @note The destructor function, if any, will @em not be invoked. That means |
| 1356 * you will need to free the removed node by yourself, eventually. |
1367 * you will need to free the removed node by yourself, eventually. |
| 1357 * |
1368 * |
| 1358 * @param tree the tree |
1369 * @param tree the tree |
| 1359 * @param node the node to remove (must not be the root node) |
1370 * @param node the node to remove (must not be the root node) |
| 1360 * @param relink_func optional callback to update the content of each re-linked |
1371 * @param relink_func optional callback to update the content of each re-linked |
| 1361 * node |
1372 * node |
| 1362 * @return zero on success, non-zero if \p node is the root node of the tree |
1373 * @return zero on success, non-zero if @p node is the root node of the tree |
| 1363 */ |
1374 */ |
| 1364 cx_attr_nonnull_arg(1, 2) |
1375 cx_attr_nonnull_arg(1, 2) |
| |
1376 cx_attr_export |
| 1365 int cxTreeRemoveNode( |
1377 int cxTreeRemoveNode( |
| 1366 CxTree *tree, |
1378 CxTree *tree, |
| 1367 void *node, |
1379 void *node, |
| 1368 cx_tree_relink_func relink_func |
1380 cx_tree_relink_func relink_func |
| 1369 ); |
1381 ); |
| 1371 /** |
1383 /** |
| 1372 * Removes a node and it's subtree from the tree. |
1384 * Removes a node and it's subtree from the tree. |
| 1373 * |
1385 * |
| 1374 * If the node is not part of the tree, the behavior is undefined. |
1386 * If the node is not part of the tree, the behavior is undefined. |
| 1375 * |
1387 * |
| 1376 * \note The destructor function, if any, will \em not be invoked. That means |
1388 * @note The destructor function, if any, will @em not be invoked. That means |
| 1377 * you will need to free the removed subtree by yourself, eventually. |
1389 * you will need to free the removed subtree by yourself, eventually. |
| 1378 * |
1390 * |
| 1379 * @param tree the tree |
1391 * @param tree the tree |
| 1380 * @param node the node to remove |
1392 * @param node the node to remove |
| 1381 */ |
1393 */ |
| 1382 cx_attr_nonnull |
1394 cx_attr_nonnull |
| |
1395 cx_attr_export |
| 1383 void cxTreeRemoveSubtree(CxTree *tree, void *node); |
1396 void cxTreeRemoveSubtree(CxTree *tree, void *node); |
| 1384 |
1397 |
| 1385 /** |
1398 /** |
| 1386 * Destroys a node and re-links its children to its former parent. |
1399 * Destroys a node and re-links its children to its former parent. |
| 1387 * |
1400 * |
| 1388 * If the node is not part of the tree, the behavior is undefined. |
1401 * If the node is not part of the tree, the behavior is undefined. |
| 1389 * |
1402 * |
| 1390 * It is guaranteed that the simple destructor is invoked before |
1403 * It is guaranteed that the simple destructor is invoked before |
| 1391 * the advanced destructor. |
1404 * the advanced destructor. |
| 1392 * |
1405 * |
| 1393 * \attention This function will not free the memory of the node with the |
1406 * @attention This function will not free the memory of the node with the |
| 1394 * tree's allocator, because that is usually done by the advanced destructor |
1407 * tree's allocator, because that is usually done by the advanced destructor |
| 1395 * and would therefore result in a double-free. |
1408 * and would therefore result in a double-free. |
| 1396 * |
1409 * |
| 1397 * @param tree the tree |
1410 * @param tree the tree |
| 1398 * @param node the node to destroy (must not be the root node) |
1411 * @param node the node to destroy (must not be the root node) |
| 1399 * @param relink_func optional callback to update the content of each re-linked |
1412 * @param relink_func optional callback to update the content of each re-linked |
| 1400 * node |
1413 * node |
| 1401 * @return zero on success, non-zero if \p node is the root node of the tree |
1414 * @return zero on success, non-zero if @p node is the root node of the tree |
| 1402 */ |
1415 */ |
| 1403 cx_attr_nonnull_arg(1, 2) |
1416 cx_attr_nonnull_arg(1, 2) |
| |
1417 cx_attr_export |
| 1404 int cxTreeDestroyNode( |
1418 int cxTreeDestroyNode( |
| 1405 CxTree *tree, |
1419 CxTree *tree, |
| 1406 void *node, |
1420 void *node, |
| 1407 cx_tree_relink_func relink_func |
1421 cx_tree_relink_func relink_func |
| 1408 ); |
1422 ); |