src/cx/tree.h

changeset 1424
563033aa998c
parent 1319
aa1f580f8f59
equal deleted inserted replaced
1423:9a72258446cd 1424:563033aa998c
47 /** 47 /**
48 * A depth-first tree iterator. 48 * A depth-first tree iterator.
49 * 49 *
50 * This iterator is not position-aware in a strict sense, as it does not assume 50 * This iterator is not position-aware in a strict sense, as it does not assume
51 * a particular order of elements in the tree. However, the iterator keeps track 51 * a particular order of elements in the tree. However, the iterator keeps track
52 * of the number of nodes it has passed in a counter variable. 52 * of the number of nodes it has passed in a counter-variable.
53 * Each node, regardless of the number of passes, is counted only once. 53 * Each node, regardless of the number of passes, is counted only once.
54 * 54 *
55 * @note Objects that are pointed to by an iterator are mutable through that 55 * @note Objects that are pointed to by an iterator are mutable through that
56 * iterator. However, if the 56 * iterator. However, if the
57 * underlying data structure is mutated by other means than this iterator (e.g. 57 * underlying data structure is mutated by other means than this iterator (e.g.,
58 * elements added or removed), the iterator becomes invalid (regardless of what 58 * elements added or removed), the iterator becomes invalid (regardless of what
59 * cxIteratorValid() returns). 59 * cxIteratorValid() returns).
60 * 60 *
61 * @see CxIterator 61 * @see CxIterator
62 */ 62 */
69 * Indicates whether the subtree below the current node shall be skipped. 69 * Indicates whether the subtree below the current node shall be skipped.
70 */ 70 */
71 bool skip; 71 bool skip;
72 /** 72 /**
73 * Set to true, when the iterator shall visit a node again 73 * Set to true, when the iterator shall visit a node again
74 * when all it's children have been processed. 74 * when all its children have been processed.
75 */ 75 */
76 bool visit_on_exit; 76 bool visit_on_exit;
77 /** 77 /**
78 * True, if this iterator is currently leaving the node. 78 * True, if this iterator is currently leaving the node.
79 */ 79 */
95 * 95 *
96 * This is the same what cxIteratorCurrent() would return. 96 * This is the same what cxIteratorCurrent() would return.
97 */ 97 */
98 void *node; 98 void *node;
99 /** 99 /**
100 * Stores a copy of the next pointer of the visited node. 100 * Stores a copy of the pointer to the successor of the visited node.
101 * Allows freeing a node on exit without corrupting the iteration. 101 * Allows freeing a node on exit without corrupting the iteration.
102 */ 102 */
103 void *node_next; 103 void *node_next;
104 /** 104 /**
105 * Internal stack. 105 * Internal stack.
153 * If you want to discard the iterator before, you MUST manually call 153 * If you want to discard the iterator before, you MUST manually call
154 * cxTreeVisitorDispose(). 154 * cxTreeVisitorDispose().
155 * 155 *
156 * This iterator is not position-aware in a strict sense, as it does not assume 156 * This iterator is not position-aware in a strict sense, as it does not assume
157 * a particular order of elements in the tree. However, the iterator keeps track 157 * a particular order of elements in the tree. However, the iterator keeps track
158 * of the number of nodes it has passed in a counter variable. 158 * of the number of nodes it has passed in a counter-variable.
159 * Each node, regardless of the number of passes, is counted only once. 159 * Each node, regardless of the number of passes, is counted only once.
160 * 160 *
161 * @note Objects that are pointed to by an iterator are mutable through that 161 * @note Objects that are pointed to by an iterator are mutable through that
162 * iterator. However, if the 162 * iterator. However, if the
163 * underlying data structure is mutated by other means than this iterator (e.g. 163 * underlying data structure is mutated by other means than this iterator (e.g.,
164 * elements added or removed), the iterator becomes invalid (regardless of what 164 * elements added or removed), the iterator becomes invalid (regardless of what
165 * cxIteratorValid() returns). 165 * cxIteratorValid() returns).
166 * 166 *
167 * @see CxIterator 167 * @see CxIterator
168 */ 168 */
248 #define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor) 248 #define cxTreeVisitorContinue(visitor) cxTreeIteratorContinue(visitor)
249 249
250 /** 250 /**
251 * Links a node to a (new) parent. 251 * Links a node to a (new) parent.
252 * 252 *
253 * If the node has already a parent, it is unlinked, first. 253 * If the node already has a parent, it is unlinked, first.
254 * If the parent has children already, the node is @em appended to the list 254 * If the parent has children already, the node is @em appended to the list
255 * of all currently existing children. 255 * of all currently existing children.
256 * 256 *
257 * @param parent the parent node 257 * @param parent the parent node
258 * @param node the node that shall be linked 258 * @param node the node that shall be linked
316 * The function should use the returned integer to indicate how close the 316 * The function should use the returned integer to indicate how close the
317 * match is, where a negative number means that it does not match at all. 317 * match is, where a negative number means that it does not match at all.
318 * Zero means exact match and a positive number is an implementation defined 318 * Zero means exact match and a positive number is an implementation defined
319 * measure for the distance to an exact match. 319 * measure for the distance to an exact match.
320 * 320 *
321 * For example if a tree stores file path information, a node that is 321 * For example, consider a tree that stores file path information.
322 * describing a parent directory of a filename that is searched, shall 322 * A node which is describing a parent directory of a searched file shall
323 * return a positive number to indicate that a child node might contain the 323 * return a positive number to indicate that a child node might contain the
324 * searched item. On the other hand, if the node denotes a path that is not a 324 * searched item. On the other hand, if the node denotes a path that is not a
325 * prefix of the searched filename, the function would return -1 to indicate 325 * prefix of the searched filename, the function would return -1 to indicate
326 * that the search does not need to be continued in that branch. 326 * that the search does not need to be continued in that branch.
327 * 327 *
328 * @param node the node that is currently investigated 328 * @param node the node that is currently investigated
329 * @param data the data that is searched for 329 * @param data the data that is searched for
330 * 330 *
331 * @return 0 if the node contains the data, 331 * @return 0 if the node contains the data,
332 * positive if one of the children might contain the data, 332 * positive if one of the children might contain the data,
333 * negative if neither the node, nor the children contains the data 333 * negative if neither the node nor the children contains the data
334 */ 334 */
335 cx_attr_nonnull 335 cx_attr_nonnull
336 typedef int (*cx_tree_search_data_func)(const void *node, const void *data); 336 typedef int (*cx_tree_search_data_func)(const void *node, const void *data);
337 337
338 338
346 * The function should use the returned integer to indicate how close the 346 * The function should use the returned integer to indicate how close the
347 * match is, where a negative number means that it does not match at all. 347 * match is, where a negative number means that it does not match at all.
348 * Zero means exact match and a positive number is an implementation defined 348 * Zero means exact match and a positive number is an implementation defined
349 * measure for the distance to an exact match. 349 * measure for the distance to an exact match.
350 * 350 *
351 * For example if a tree stores file path information, a node that is 351 * For example, consider a tree that stores file path information.
352 * describing a parent directory of a filename that is searched, shall 352 * A node which is describing a parent directory of a searched file shall
353 * return a positive number to indicate that a child node might contain the 353 * return a positive number to indicate that a child node might contain the
354 * searched item. On the other hand, if the node denotes a path that is not a 354 * searched item. On the other hand, if the node denotes a path that is not a
355 * prefix of the searched filename, the function would return -1 to indicate 355 * prefix of the searched filename, the function would return -1 to indicate
356 * that the search does not need to be continued in that branch. 356 * that the search does not need to be continued in that branch.
357 * 357 *
358 * @param node the node that is currently investigated 358 * @param node the node that is currently investigated
359 * @param new_node a new node with the information which is searched 359 * @param new_node a new node with the information which is searched
360 * 360 *
361 * @return 0 if @p node contains the same data as @p new_node, 361 * @return 0 if @p node contains the same data as @p new_node,
362 * positive if one of the children might contain the data, 362 * positive if one of the children might contain the data,
363 * negative if neither the node, nor the children contains the data 363 * negative if neither the node nor the children contains the data
364 */ 364 */
365 cx_attr_nonnull 365 cx_attr_nonnull
366 typedef int (*cx_tree_search_func)(const void *node, const void *new_node); 366 typedef int (*cx_tree_search_func)(const void *node, const void *new_node);
367 367
368 /** 368 /**
369 * Searches for data in a tree. 369 * Searches for data in a tree.
370 * 370 *
371 * When the data cannot be found exactly, the search function might return a 371 * When the data cannot be found exactly, the search function might return the
372 * closest result which might be a good starting point for adding a new node 372 * closest result, which might be a good starting point for adding a new node
373 * to the tree (see also #cx_tree_add()). 373 * to the tree (see also #cx_tree_add()).
374 * 374 *
375 * Depending on the tree structure it is not necessarily guaranteed that the 375 * Depending on the tree structure, it is not necessarily guaranteed that the
376 * "closest" match is uniquely defined. This function will search for a node 376 * "closest" match is uniquely defined. This function will search for a node
377 * with the best match according to the @p sfunc (meaning: the return value of 377 * with the best match according to the @p sfunc (meaning: the return value of
378 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary 378 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary
379 * node matching the criteria is returned. 379 * node matching the criteria is returned.
380 * 380 *
404 404
405 /** 405 /**
406 * Searches for a node in a tree. 406 * Searches for a node in a tree.
407 * 407 *
408 * When no node with the same data can be found, the search function might 408 * When no node with the same data can be found, the search function might
409 * return a closest result which might be a good starting point for adding the 409 * return the closest result, which might be a good starting point for adding the
410 * new node to the tree (see also #cx_tree_add()). 410 * new node to the tree (see also #cx_tree_add()).
411 * 411 *
412 * Depending on the tree structure it is not necessarily guaranteed that the 412 * Depending on the tree structure, it is not necessarily guaranteed that the
413 * "closest" match is uniquely defined. This function will search for a node 413 * "closest" match is uniquely defined. This function will search for a node
414 * with the best match according to the @p sfunc (meaning: the return value of 414 * with the best match according to the @p sfunc (meaning: the return value of
415 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary 415 * @p sfunc which is closest to zero). If that is also ambiguous, an arbitrary
416 * node matching the criteria is returned. 416 * node matching the criteria is returned.
417 * 417 *
494 ptrdiff_t loc_next 494 ptrdiff_t loc_next
495 ); 495 );
496 496
497 /** 497 /**
498 * Describes a function that creates a tree node from the specified data. 498 * Describes a function that creates a tree node from the specified data.
499 * The first argument points to the data the node shall contain and 499 * The first argument points to the data the node shall contain, and
500 * the second argument may be used for additional data (e.g. an allocator). 500 * the second argument may be used for additional data (e.g., an allocator).
501 * Functions of this type shall either return a new pointer to a newly 501 * Functions of this type shall either return a new pointer to a newly
502 * created node or @c NULL when allocation fails. 502 * created node or @c NULL when allocation fails.
503 * 503 *
504 * @note the function may leave the node pointers in the struct uninitialized. 504 * @note the function may leave the node pointers in the struct uninitialized.
505 * The caller is responsible to set them according to the intended use case. 505 * The caller is responsible to set them according to the intended use case.
635 * specified @p sfunc. 635 * specified @p sfunc.
636 * 636 *
637 * When a location is found, the @p cfunc will be invoked with @p cdata. 637 * When a location is found, the @p cfunc will be invoked with @p cdata.
638 * 638 *
639 * The node returned by @p cfunc will be linked into the tree. 639 * The node returned by @p cfunc will be linked into the tree.
640 * When @p sfunc returned a positive integer, the new node will be linked as a 640 * When @p sfunc returns a positive integer, the new node will be linked as a
641 * child. The other children (now siblings of the new node) are then checked 641 * child. The other children (now siblings of the new node) are then checked
642 * with @p sfunc, whether they could be children of the new node and re-linked 642 * with @p sfunc, whether they could be children of the new node and re-linked
643 * accordingly. 643 * accordingly.
644 * 644 *
645 * When @p sfunc returned zero and the found node has a parent, the new 645 * When @p sfunc returns zero and the found node has a parent, the new
646 * node will be added as sibling - otherwise, the new node will be added 646 * node will be added as a sibling - otherwise, the new node will be added
647 * as a child. 647 * as a child.
648 * 648 *
649 * When @p sfunc returned a negative value, the new node will not be added to 649 * When @p sfunc returns a negative value, the new node will not be added to
650 * the tree and this function returns a non-zero value. 650 * the tree, and this function returns a non-zero value.
651 * The caller should check if @p cnode contains a node pointer and deal with the 651 * The caller should check if @p cnode contains a node pointer and deal with the
652 * node that could not be added. 652 * node that could not be added.
653 * 653 *
654 * This function also returns a non-zero value when @p cfunc tries to allocate 654 * This function also returns a non-zero value when @p cfunc tries to allocate
655 * a new node but fails to do so. In that case, the pointer stored to @p cnode 655 * a new node but fails to do so. In that case, the pointer stored to @p cnode
745 745
746 /** 746 /**
747 * A function to create new nodes. 747 * A function to create new nodes.
748 * 748 *
749 * Invocations to this function will receive a pointer to this tree 749 * Invocations to this function will receive a pointer to this tree
750 * structure as second argument. 750 * structure as the second argument.
751 * 751 *
752 * Nodes MAY use #cx_tree_node_base_s as base layout, but do not need to. 752 * Nodes MAY use #cx_tree_node_base_s as the base layout, but do not need to.
753 */ 753 */
754 cx_tree_node_create_func node_create; 754 cx_tree_node_create_func node_create;
755 755
756 /** 756 /**
757 * An optional simple destructor for the tree nodes. 757 * An optional simple destructor for the tree nodes.
812 812
813 /** 813 /**
814 * Macro to roll out the #cx_tree_node_base_s structure with a custom 814 * Macro to roll out the #cx_tree_node_base_s structure with a custom
815 * node type. 815 * node type.
816 * 816 *
817 * Must be used as first member in your custom tree struct. 817 * Must be used as the first member in your custom tree struct.
818 * 818 *
819 * @param type the data type for the nodes 819 * @param type the data type for the nodes
820 */ 820 */
821 #define CX_TREE_NODE_BASE(type) \ 821 #define CX_TREE_NODE_BASE(type) \
822 type *parent; \ 822 type *parent; \
856 ); 856 );
857 857
858 /** 858 /**
859 * Member function for inserting multiple elements. 859 * Member function for inserting multiple elements.
860 * 860 *
861 * Implementations SHALL avoid to perform a full search in the tree for 861 * Implementations SHALL avoid performing a full search in the tree for
862 * every element even though the source data MAY be unsorted. 862 * every element even though the source data MAY be unsorted.
863 */ 863 */
864 size_t (*insert_many)( 864 size_t (*insert_many)(
865 struct cx_tree_s *tree, 865 struct cx_tree_s *tree,
866 struct cx_iterator_base_s *iter, 866 struct cx_iterator_base_s *iter,
883 */ 883 */
884 typedef struct cx_tree_s CxTree; 884 typedef struct cx_tree_s CxTree;
885 885
886 886
887 /** 887 /**
888 * Destroys a node and it's subtree. 888 * Destroys a node and its subtree.
889 * 889 *
890 * It is guaranteed that the simple destructor is invoked before 890 * It is guaranteed that the simple destructor is invoked before
891 * the advanced destructor, starting with the leaf nodes of the subtree. 891 * the advanced destructor, starting with the leaf nodes of the subtree.
892 * 892 *
893 * When this function is invoked on the root node of the tree, it destroys the 893 * When this function is invoked on the root node of the tree, it destroys the
919 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the 919 * This is a convenience macro for invoking #cxTreeDestroySubtree() on the
920 * root node of the tree. 920 * root node of the tree.
921 * 921 *
922 * @attention Be careful when calling this function when no destructor function 922 * @attention Be careful when calling this function when no destructor function
923 * is registered that actually frees the memory of nodes. In that case you will 923 * is registered that actually frees the memory of nodes. In that case you will
924 * need a reference to the (former) root node of the tree somewhere or 924 * need a reference to the (former) root node of the tree somewhere, or
925 * otherwise you will be leaking memory. 925 * otherwise you will be leaking memory.
926 * 926 *
927 * @param tree the tree 927 * @param tree the tree
928 * @see cxTreeDestroySubtree() 928 * @see cxTreeDestroySubtree()
929 */ 929 */
990 ); 990 );
991 991
992 /** 992 /**
993 * Creates a new tree structure based on a default layout. 993 * Creates a new tree structure based on a default layout.
994 * 994 *
995 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as first 995 * Nodes created by @p create_func MUST contain #cx_tree_node_base_s as the first
996 * member (or at least respect the default offsets specified in the tree 996 * member (or at least respect the default offsets specified in the tree
997 * struct) and they MUST be allocated with the specified allocator. 997 * struct), and they MUST be allocated with the specified allocator.
998 * 998 *
999 * @note This function will also register an advanced destructor which 999 * @note This function will also register an advanced destructor which
1000 * will free the nodes with the allocator's free() method. 1000 * will free the nodes with the allocator's free() method.
1001 * 1001 *
1002 * @param allocator (@c CxAllocator*) the allocator that shall be used 1002 * @param allocator (@c CxAllocator*) the allocator that shall be used
1017 * The specified @p allocator will be used for creating the tree struct. 1017 * The specified @p allocator will be used for creating the tree struct.
1018 * 1018 *
1019 * @attention This function will create an incompletely defined tree structure 1019 * @attention This function will create an incompletely defined tree structure
1020 * where neither the create function, the search function, nor a destructor 1020 * where neither the create function, the search function, nor a destructor
1021 * will be set. If you wish to use any of this functionality for the wrapped 1021 * will be set. If you wish to use any of this functionality for the wrapped
1022 * tree, you need to specify those functions afterwards. 1022 * tree, you need to specify those functions afterward.
1023 * 1023 *
1024 * @param allocator the allocator that was used for nodes of the wrapped tree 1024 * @param allocator the allocator that was used for nodes of the wrapped tree
1025 * (if @c NULL, the cxDefaultAllocator is assumed) 1025 * (if @c NULL, the cxDefaultAllocator is assumed)
1026 * @param root the root node of the tree that shall be wrapped 1026 * @param root the root node of the tree that shall be wrapped
1027 * @param loc_parent offset in the node struct for the parent pointer 1027 * @param loc_parent offset in the node struct for the parent pointer
1287 } 1287 }
1288 1288
1289 /** 1289 /**
1290 * Sets the (new) parent of the specified child. 1290 * Sets the (new) parent of the specified child.
1291 * 1291 *
1292 * If the @p child is not already member of the tree, this function behaves 1292 * If the @p child is not already a member of the tree, this function behaves
1293 * as #cxTreeAddChildNode(). 1293 * as #cxTreeAddChildNode().
1294 * 1294 *
1295 * @param tree the tree 1295 * @param tree the tree
1296 * @param parent the (new) parent of the child 1296 * @param parent the (new) parent of the child
1297 * @param child the node to add 1297 * @param child the node to add
1306 ); 1306 );
1307 1307
1308 /** 1308 /**
1309 * Adds a new node to the tree. 1309 * Adds a new node to the tree.
1310 * 1310 *
1311 * If the @p child is already member of the tree, the behavior is undefined. 1311 * If the @p child is already a member of the tree, the behavior is undefined.
1312 * Use #cxTreeSetParent() if you want to move a subtree to another location. 1312 * Use #cxTreeSetParent() if you want to move a subtree to another location.
1313 * 1313 *
1314 * @attention The node may be externally created, but MUST obey the same rules 1314 * @attention The node may be externally created, but MUST obey the same rules
1315 * as if it was created by the tree itself with #cxTreeAddChild() (e.g. use 1315 * as if it was created by the tree itself with #cxTreeAddChild() (e.g., use
1316 * the same allocator). 1316 * the same allocator).
1317 * 1317 *
1318 * @param tree the tree 1318 * @param tree the tree
1319 * @param parent the parent of the node to add 1319 * @param parent the parent of the node to add
1320 * @param child the node to add 1320 * @param child the node to add
1334 * With this function you can decide where exactly the new node shall be added. 1334 * With this function you can decide where exactly the new node shall be added.
1335 * If you specified an appropriate search function, you may want to consider 1335 * If you specified an appropriate search function, you may want to consider
1336 * leaving this task to the tree by using #cxTreeInsert(). 1336 * leaving this task to the tree by using #cxTreeInsert().
1337 * 1337 *
1338 * Be aware that adding nodes at arbitrary locations in the tree might cause 1338 * Be aware that adding nodes at arbitrary locations in the tree might cause
1339 * wrong or undesired results when subsequently invoking #cxTreeInsert() and 1339 * wrong or undesired results when subsequently invoking #cxTreeInsert(), and
1340 * the invariant imposed by the search function does not hold any longer. 1340 * the invariant imposed by the search function does not hold any longer.
1341 * 1341 *
1342 * @param tree the tree 1342 * @param tree the tree
1343 * @param parent the parent node of the new node 1343 * @param parent the parent node of the new node
1344 * @param data the data that will be submitted to the create function 1344 * @param data the data that will be submitted to the create function
1393 void *node, 1393 void *node,
1394 cx_tree_relink_func relink_func 1394 cx_tree_relink_func relink_func
1395 ); 1395 );
1396 1396
1397 /** 1397 /**
1398 * Removes a node and it's subtree from the tree. 1398 * Removes a node and its subtree from the tree.
1399 * 1399 *
1400 * If the node is not part of the tree, the behavior is undefined. 1400 * If the node is not part of the tree, the behavior is undefined.
1401 * 1401 *
1402 * @note The destructor function, if any, will @em not be invoked. That means 1402 * @note The destructor function, if any, will @em not be invoked. That means
1403 * you will need to free the removed subtree by yourself, eventually. 1403 * you will need to free the removed subtree by yourself, eventually.

mercurial