src/cx/tree.h

changeset 899
303a981e6834
parent 898
9b2c12494ccf
child 900
793fe631e877
equal deleted inserted replaced
898:9b2c12494ccf 899:303a981e6834
739 * A function to compare two nodes. 739 * A function to compare two nodes.
740 */ 740 */
741 cx_tree_search_func search; 741 cx_tree_search_func search;
742 742
743 /** 743 /**
744 * The total size of a node, including the element size.
745 */
746 size_t node_size;
747
748 /**
749 * The number of currently stored elements. 744 * The number of currently stored elements.
750 */ 745 */
751 size_t size; 746 size_t size;
752 747
753 /** 748 /**
864 /** 859 /**
865 * Creates a new tree structure based on the specified layout. 860 * Creates a new tree structure based on the specified layout.
866 * 861 *
867 * The specified \p allocator will be used for creating the tree struct 862 * The specified \p allocator will be used for creating the tree struct
868 * and SHALL be used by \p create_func to allocate memory for the nodes. 863 * and SHALL be used by \p create_func to allocate memory for the nodes.
864 *
865 * \attention This function will also register a simple destructor which
866 * will free the nodes with the allocator's free() method.
869 * 867 *
870 * @param allocator the allocator that shall be used 868 * @param allocator the allocator that shall be used
871 * @param create_func a function that creates new nodes 869 * @param create_func a function that creates new nodes
872 * @param search_func a function that compares two nodes 870 * @param search_func a function that compares two nodes
873 * @param loc_parent offset in the node struct for the parent pointer 871 * @param loc_parent offset in the node struct for the parent pointer
876 * the last child in the linked list (negative if there is no such pointer) 874 * the last child in the linked list (negative if there is no such pointer)
877 * @param loc_prev offset in the node struct for the prev pointer 875 * @param loc_prev offset in the node struct for the prev pointer
878 * @param loc_next offset in the node struct for the next pointer 876 * @param loc_next offset in the node struct for the next pointer
879 * @return the new tree 877 * @return the new tree
880 * @see cxTreeCreateSimple() 878 * @see cxTreeCreateSimple()
879 * @see cxTreeCreateWrapped()
881 */ 880 */
882 __attribute__((__nonnull__, __warn_unused_result__)) 881 __attribute__((__nonnull__, __warn_unused_result__))
883 CxTree *cxTreeCreate( 882 CxTree *cxTreeCreate(
884 const CxAllocator *allocator, 883 const CxAllocator *allocator,
885 cx_tree_node_create_func create_func, 884 cx_tree_node_create_func create_func,
914 return cxTreeCreate(cxDefaultAllocator, 913 return cxTreeCreate(cxDefaultAllocator,
915 create_func, search_func, cx_tree_node_base_layout); 914 create_func, search_func, cx_tree_node_base_layout);
916 } 915 }
917 916
918 /** 917 /**
918 * Creates a new tree structure based on an existing tree.
919 *
920 * The specified \p allocator will be used for creating the tree struct
921 * and SHALL be used by \p create_func to allocate memory for the nodes.
922 *
923 * \attention This function will create an incompletely defined tree structure
924 * where neither the create function, the search function, nor a destructor
925 * will be set. If you wish to use any of this functionality for the wrapped
926 * tree, you need to specify those functions afterwards.
927 *
928 * @param root the root node of the tree that shall be wrapped
929 * @param loc_parent offset in the node struct for the parent pointer
930 * @param loc_children offset in the node struct for the children linked list
931 * @param loc_last_child optional offset in the node struct for the pointer to
932 * the last child in the linked list (negative if there is no such pointer)
933 * @param loc_prev offset in the node struct for the prev pointer
934 * @param loc_next offset in the node struct for the next pointer
935 * @return the new tree
936 * @see cxTreeCreate()
937 */
938 __attribute__((__nonnull__, __warn_unused_result__))
939 CxTree *cxTreeCreateWrapped(
940 void *root,
941 ptrdiff_t loc_parent,
942 ptrdiff_t loc_children,
943 ptrdiff_t loc_last_child,
944 ptrdiff_t loc_prev,
945 ptrdiff_t loc_next
946 );
947
948 /**
919 * Destroys the tree structure. 949 * Destroys the tree structure.
920 * 950 *
921 * \attention This function will only invoke the destructor functions 951 * \attention This function will only invoke the destructor functions
922 * on the nodes, if specified. 952 * on the nodes, if specified.
923 * It will NOT automatically free the nodes with the allocator, because that 953 * It will NOT automatically free the nodes with the allocator, because that
925 * a tree which memory is managed by someone else. 955 * a tree which memory is managed by someone else.
926 * 956 *
927 * @param tree the tree to destroy 957 * @param tree the tree to destroy
928 */ 958 */
929 __attribute__((__nonnull__)) 959 __attribute__((__nonnull__))
930 void cxTreeDestroy(CxTree *tree); 960 static inline void cxTreeDestroy(CxTree *tree) {
961 tree->cl->destructor(tree);
962 }
963
964 /**
965 * Inserts data into the tree.
966 *
967 * \remark For this function to work, the tree needs specified search and
968 * create functions, which might not be available for wrapped trees
969 * (see #cxTreeCreateWrapped()).
970 *
971 * @param tree the tree
972 * @param data the data to insert
973 * @return zero on success, non-zero on failure
974 */
975 __attribute__((__nonnull__))
976 static inline int cxTreeInsert(
977 CxTree *tree,
978 const void *data
979 ) {
980 return tree->cl->insert_element(tree, data);
981 }
982
983 /**
984 * Inserts elements provided by an iterator efficiently into the tree.
985 *
986 * \remark For this function to work, the tree needs specified search and
987 * create functions, which might not be available for wrapped trees
988 * (see #cxTreeCreateWrapped()).
989 *
990 * @param tree the tree
991 * @param iter the iterator providing the elements
992 * @param n the maximum number of elements to insert
993 * @return the number of elements that could be successfully inserted
994 */
995 __attribute__((__nonnull__))
996 static inline size_t cxTreeInsertIter(
997 CxTree *tree,
998 struct cx_iterator_base_s *iter,
999 size_t n
1000 ) {
1001 return tree->cl->insert_many(tree, iter, n);
1002 }
1003
1004 /**
1005 * Inserts an array of data efficiently into the tree.
1006 *
1007 * \remark For this function to work, the tree needs specified search and
1008 * create functions, which might not be available for wrapped trees
1009 * (see #cxTreeCreateWrapped()).
1010 *
1011 * @param tree the tree
1012 * @param data the array of data to insert
1013 * @param elem_size the size of each element in the array
1014 * @param n the number of elements in the array
1015 * @return the number of elements that could be successfully inserted
1016 */
1017 __attribute__((__nonnull__))
1018 static inline size_t cxTreeInsertArray(
1019 CxTree *tree,
1020 const void *data,
1021 size_t elem_size,
1022 size_t n
1023 ) {
1024 if (n == 0) return 0;
1025 if (n == 1) return 0 == cxTreeInsert(tree, data) ? 1 : 0;
1026 CxIterator iter = cxIterator(data, elem_size, n);
1027 return tree->cl->insert_many(tree, cxIteratorRef(iter), n);
1028 }
1029
1030 /**
1031 * Searches the data in the specified tree.
1032 *
1033 * \remark For this function to work, the tree needs a specified search
1034 * function, which might not be available wrapped trees
1035 * (see #cxTreeCreateWrapped()).
1036 *
1037 * @param tree the tree
1038 * @param data the data to search for
1039 * @return the first matching node, or \c NULL when the data cannot be found
1040 */
1041 __attribute__((__nonnull__))
1042 static inline void *cxTreeFind(
1043 CxTree *tree,
1044 const void *data
1045 ) {
1046 return tree->cl->find(tree, tree->root, data);
1047 }
1048
1049 /**
1050 * Searches the data in the specified subtree.
1051 *
1052 * \note When \p subtree_root is not part of the \p tree, the behavior is
1053 * undefined.
1054 *
1055 * \remark For this function to work, the tree needs a specified search
1056 * function, which might not be the case for wrapped trees
1057 * (see #cxTreeCreateWrapped()).
1058 *
1059 * @param tree the tree
1060 * @param data the data to search for
1061 * @param subtree_root the node where to start
1062 * @return the first matching node, or \c NULL when the data cannot be found
1063 */
1064 __attribute__((__nonnull__))
1065 static inline void *cxTreeFindInSubtree(
1066 CxTree *tree,
1067 const void *data,
1068 void *subtree_root
1069 ) {
1070 return tree->cl->find(tree, subtree_root, data);
1071 }
1072
1073 /**
1074 * Creates a depth-first iterator for the specified tree.
1075 *
1076 * @param tree the tree to iterate
1077 * @param visit_on_exit true, if the iterator shall visit a node again when
1078 * leaving the sub-tree
1079 * @return a tree iterator (depth-first)
1080 * @see cxTreeVisitor()
1081 */
1082 __attribute__((__nonnull__, __warn_unused_result__))
1083 static inline CxTreeIterator cxTreeIterator(
1084 CxTree *tree,
1085 bool visit_on_exit
1086 ) {
1087 return tree->cl->iterator(tree, visit_on_exit);
1088 }
1089
1090 /**
1091 * Creates a breadth-first iterator for the specified tree.
1092 *
1093 * @param tree the tree to iterate
1094 * @return a tree visitor (a.k.a. breadth-first iterator)
1095 * @see cxTreeIterator()
1096 */
1097 __attribute__((__nonnull__, __warn_unused_result__))
1098 static inline CxTreeVisitor cxTreeVisitor(CxTree *tree) {
1099 return tree->cl->visitor(tree);
1100 }
931 1101
932 #ifdef __cplusplus 1102 #ifdef __cplusplus
933 } // extern "C" 1103 } // extern "C"
934 #endif 1104 #endif
935 1105

mercurial