ucx/cx/linked_list.h

branch
dav-2
changeset 891
4d58cbcc9efa
parent 889
42cdbf9bbd49
equal deleted inserted replaced
890:e77ccf1c4bb3 891:4d58cbcc9efa
60 /** 60 /**
61 * Location of the payload (mandatory). 61 * Location of the payload (mandatory).
62 */ 62 */
63 off_t loc_data; 63 off_t loc_data;
64 /** 64 /**
65 * Location of extra data (optional).
66 * Negative when no extra data is requested.
67 * @see cx_linked_list_extra_data()
68 */
69 off_t loc_extra;
70 /**
65 * Additional bytes to allocate @em behind the payload (e.g. for metadata). 71 * Additional bytes to allocate @em behind the payload (e.g. for metadata).
72 * @see cx_linked_list_extra_data()
66 */ 73 */
67 size_t extra_data_len; 74 size_t extra_data_len;
68 /** 75 /**
69 * Pointer to the first node. 76 * Pointer to the first node.
70 */ 77 */
78 /** 85 /**
79 * Allocates a linked list for storing elements with @p elem_size bytes each. 86 * Allocates a linked list for storing elements with @p elem_size bytes each.
80 * 87 *
81 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of 88 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of
82 * copies of the added elements, and the compare function will be automatically set 89 * copies of the added elements, and the compare function will be automatically set
83 * to cx_cmp_ptr() if none is given. 90 * to cx_cmp_ptr().
84 * 91 *
85 * @param allocator the allocator for allocating the list nodes 92 * @param allocator the allocator for allocating the list nodes
86 * (if @c NULL, the cxDefaultAllocator will be used) 93 * (if @c NULL, the cxDefaultAllocator will be used)
87 * @param comparator the comparator for the elements
88 * (if @c NULL, and the list is not storing pointers, sort and find
89 * functions will not work)
90 * @param elem_size the size of each element in bytes 94 * @param elem_size the size of each element in bytes
91 * @return the created list 95 * @return the created list
92 */ 96 */
93 cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxListFree, 1) 97 cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxListFree, 1)
94 CX_EXPORT CxList *cxLinkedListCreate(const CxAllocator *allocator, 98 CX_EXPORT CxList *cxLinkedListCreate(const CxAllocator *allocator,
95 cx_compare_func comparator, size_t elem_size); 99 size_t elem_size);
96 100
97 /** 101 /**
98 * Allocates a linked list for storing elements with @p elem_size bytes each. 102 * Instructs the linked list to reserve extra data in each node.
99 * 103 *
100 * The list will use cxDefaultAllocator and no comparator function. If you want 104 * The extra data will be aligned and placed behind the element data.
101 * to call functions that need a comparator, you must either set one immediately 105 * The exact location in the node is stored in the @c loc_extra field
102 * after list creation or use cxLinkedListCreate(). 106 * of the linked list.
103 * 107 *
104 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of 108 * You should usually not use this function except when you are creating an
105 * copies of the added elements, and the compare function will be automatically set 109 * own linked-list implementation that is based on the UCX linked list and
106 * to cx_cmp_ptr(). 110 * needs to store extra data in each node.
107 * 111 *
108 * @param elem_size (@c size_t) the size of each element in bytes 112 * @param list the list (must be a linked list)
109 * @return (@c CxList*) the created list 113 * @param len the length of the extra data
110 */ 114 */
111 #define cxLinkedListCreateSimple(elem_size) \ 115 cx_attr_nonnull
112 cxLinkedListCreate(NULL, NULL, elem_size) 116 CX_EXPORT void cx_linked_list_extra_data(cx_linked_list *list, size_t len);
113 117
114 /** 118 /**
115 * Finds the node at a certain index. 119 * Finds the node at a certain index.
116 * 120 *
117 * This function can be used to start at an arbitrary position within the list. 121 * This function can be used to start at an arbitrary position within the list.
136 * Finds the node containing an element within a linked list. 140 * Finds the node containing an element within a linked list.
137 * 141 *
138 * @param start a pointer to the start node 142 * @param start a pointer to the start node
139 * @param loc_advance the location of the pointer to advance 143 * @param loc_advance the location of the pointer to advance
140 * @param loc_data the location of the @c data pointer within your node struct 144 * @param loc_data the location of the @c data pointer within your node struct
141 * @param cmp_func a compare function to compare @p elem against the node data
142 * @param elem a pointer to the element to find 145 * @param elem a pointer to the element to find
143 * @param found_index an optional pointer where the index of the found node 146 * @param found_index an optional pointer where the index of the found node
144 * (given that @p start has index 0) is stored 147 * (given that @p start has index 0) is stored
148 * @param cmp_func a compare function to compare @p elem against the node data
145 * @return a pointer to the found node or @c NULL if no matching node was found 149 * @return a pointer to the found node or @c NULL if no matching node was found
146 */ 150 */
147 cx_attr_nonnull_arg(1, 4, 5) 151 cx_attr_nonnull_arg(1, 4, 6)
148 CX_EXPORT void *cx_linked_list_find(const void *start, ptrdiff_t loc_advance, 152 CX_EXPORT void *cx_linked_list_find(const void *start, ptrdiff_t loc_advance,
149 ptrdiff_t loc_data, cx_compare_func cmp_func, const void *elem, 153 ptrdiff_t loc_data, const void *elem, size_t *found_index,
150 size_t *found_index); 154 cx_compare_func cmp_func);
155
156 /**
157 * Finds the node containing an element within a linked list.
158 *
159 * @param start a pointer to the start node
160 * @param loc_advance the location of the pointer to advance
161 * @param loc_data the location of the @c data pointer within your node struct
162 * @param elem a pointer to the element to find
163 * @param found_index an optional pointer where the index of the found node
164 * (given that @p start has index 0) is stored
165 * @param cmp_func a compare function to compare @p elem against the node data
166 * @param context additional context for the compare function
167 * @return a pointer to the found node or @c NULL if no matching node was found
168 */
169 cx_attr_nonnull_arg(1, 4, 6)
170 CX_EXPORT void *cx_linked_list_find_c(const void *start, ptrdiff_t loc_advance,
171 ptrdiff_t loc_data, const void *elem, size_t *found_index,
172 cx_compare_func2 cmp_func, void *context);
151 173
152 /** 174 /**
153 * Finds the first node in a linked list. 175 * Finds the first node in a linked list.
154 * 176 *
155 * The function starts with the pointer denoted by @p node and traverses the list 177 * The function starts with the pointer denoted by @p node and traverses the list
368 cx_attr_nonnull_arg(1, 5, 6) cx_attr_nodiscard 390 cx_attr_nonnull_arg(1, 5, 6) cx_attr_nodiscard
369 CX_EXPORT void *cx_linked_list_insert_unique_chain(void **begin, void **end, 391 CX_EXPORT void *cx_linked_list_insert_unique_chain(void **begin, void **end,
370 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func cmp_func); 392 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func cmp_func);
371 393
372 /** 394 /**
395 * Inserts a node into a sorted linked list.
396 * The new node must not be part of any list yet.
397 *
398 * If the list starting with the node pointed to by @p begin is not sorted
399 * already, the behavior is undefined.
400 *
401 * @param begin a pointer to the beginning node pointer (required)
402 * @param end a pointer to the end node pointer (if your list has one)
403 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
404 * @param loc_next the location of a @c next pointer within your node struct (required)
405 * @param new_node a pointer to the node that shall be inserted
406 * @param cmp_func a compare function that will receive the node pointers
407 * @param context context for the compare function
408 */
409 cx_attr_nonnull_arg(1, 5, 6)
410 CX_EXPORT void cx_linked_list_insert_sorted_c(void **begin, void **end,
411 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func2 cmp_func, void *context);
412
413 /**
414 * Inserts a chain of nodes into a sorted linked list.
415 * The chain must not be part of any list yet.
416 *
417 * If either the list starting with the node pointed to by @p begin or the list
418 * starting with @p insert_begin is not sorted, the behavior is undefined.
419 *
420 * @attention In contrast to cx_linked_list_insert_chain(), the source chain
421 * will be broken and inserted into the target list so that the resulting list
422 * will be sorted according to @p cmp_func. That means each node in the source
423 * chain may be re-linked with nodes from the target list.
424 *
425 * @param begin a pointer to the beginning node pointer (required)
426 * @param end a pointer to the end node pointer (if your list has one)
427 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
428 * @param loc_next the location of a @c next pointer within your node struct (required)
429 * @param insert_begin a pointer to the first node of the chain that shall be inserted
430 * @param cmp_func a compare function that will receive the node pointers
431 * @param context context for the compare function
432 */
433 cx_attr_nonnull_arg(1, 5, 6)
434 CX_EXPORT void cx_linked_list_insert_sorted_chain_c(void **begin, void **end,
435 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func2 cmp_func, void *context);
436
437 /**
438 * Inserts a node into a sorted linked list if no other node with the same value already exists.
439 * The new node must not be part of any list yet.
440 *
441 * If the list starting with the node pointed to by @p begin is not sorted
442 * already, the behavior is undefined.
443 *
444 * @param begin a pointer to the beginning node pointer (required)
445 * @param end a pointer to the end node pointer (if your list has one)
446 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
447 * @param loc_next the location of a @c next pointer within your node struct (required)
448 * @param new_node a pointer to the node that shall be inserted
449 * @param cmp_func a compare function that will receive the node pointers
450 * @retval zero when the node was inserted
451 * @retval non-zero when a node with the same value already exists
452 */
453 cx_attr_nonnull_arg(1, 5, 6)
454 CX_EXPORT int cx_linked_list_insert_unique_c(void **begin, void **end,
455 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func2 cmp_func, void *context);
456
457 /**
458 * Inserts a chain of nodes into a sorted linked list, avoiding duplicates.
459 * The chain must not be part of any list yet.
460 *
461 * If either the list starting with the node pointed to by @p begin or the list
462 * starting with @p insert_begin is not sorted, the behavior is undefined.
463 *
464 * @attention In contrast to cx_linked_list_insert_sorted(), not all nodes of the
465 * chain might be added. This function returns a new chain consisting of all the duplicates.
466 *
467 * @param begin a pointer to the beginning node pointer (required)
468 * @param end a pointer to the end node pointer (if your list has one)
469 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
470 * @param loc_next the location of a @c next pointer within your node struct (required)
471 * @param insert_begin a pointer to the first node of the chain that shall be inserted
472 * @param cmp_func a compare function that will receive the node pointers
473 * @param context context for the compare function
474 * @return a pointer to a new chain with all duplicates that were not inserted (or @c NULL when there were no duplicates)
475 */
476 cx_attr_nonnull_arg(1, 5, 6) cx_attr_nodiscard
477 CX_EXPORT void *cx_linked_list_insert_unique_chain_c(void **begin, void **end,
478 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func2 cmp_func, void *context);
479
480 /**
373 * Removes a chain of nodes from the linked list. 481 * Removes a chain of nodes from the linked list.
374 * 482 *
375 * If one of the nodes to remove is the beginning (resp. end) node of the list, and if @p begin (resp. @p end) 483 * If one of the nodes to remove is the beginning (resp. end) node of the list, and if @p begin (resp. @p end)
376 * addresses are provided, the pointers are adjusted accordingly. 484 * addresses are provided, the pointers are adjusted accordingly.
377 * 485 *
428 CX_EXPORT size_t cx_linked_list_size(const void *node, ptrdiff_t loc_next); 536 CX_EXPORT size_t cx_linked_list_size(const void *node, ptrdiff_t loc_next);
429 537
430 /** 538 /**
431 * Sorts a linked list based on a comparison function. 539 * Sorts a linked list based on a comparison function.
432 * 540 *
433 * This function can work with linked lists of the following structure:
434 * @code
435 * typedef struct node node;
436 * struct node {
437 * node* prev;
438 * node* next;
439 * my_payload data;
440 * }
441 * @endcode
442 *
443 * @note This is a recursive function with at most logarithmic recursion depth. 541 * @note This is a recursive function with at most logarithmic recursion depth.
444 * 542 *
445 * @param begin a pointer to the beginning node pointer (required) 543 * @param begin a pointer to the beginning node pointer (required)
446 * @param end a pointer to the end node pointer (optional) 544 * @param end a pointer to the end node pointer (optional)
447 * @param loc_prev the location of a @c prev pointer within your node struct (negative if not present) 545 * @param loc_prev the location of a @c prev pointer within your node struct (negative if not present)
450 * @param cmp_func the compare function defining the sort order 548 * @param cmp_func the compare function defining the sort order
451 */ 549 */
452 cx_attr_nonnull_arg(1, 6) 550 cx_attr_nonnull_arg(1, 6)
453 CX_EXPORT void cx_linked_list_sort(void **begin, void **end, 551 CX_EXPORT void cx_linked_list_sort(void **begin, void **end,
454 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func cmp_func); 552 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func cmp_func);
553
554 /**
555 * Sorts a linked list based on a comparison function.
556 *
557 * @note This is a recursive function with at most logarithmic recursion depth.
558 *
559 * @param begin a pointer to the beginning node pointer (required)
560 * @param end a pointer to the end node pointer (optional)
561 * @param loc_prev the location of a @c prev pointer within your node struct (negative if not present)
562 * @param loc_next the location of a @c next pointer within your node struct (required)
563 * @param loc_data the location of the @c data pointer within your node struct
564 * @param cmp_func the compare function defining the sort order
565 * @param context additional context for the compare function
566 */
567 cx_attr_nonnull_arg(1, 6)
568 CX_EXPORT void cx_linked_list_sort_c(void **begin, void **end,
569 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func2 cmp_func, void *context);
455 570
456 571
457 /** 572 /**
458 * Compares two lists element wise. 573 * Compares two lists element wise.
459 * 574 *
470 cx_attr_nonnull_arg(5) 585 cx_attr_nonnull_arg(5)
471 CX_EXPORT int cx_linked_list_compare(const void *begin_left, const void *begin_right, 586 CX_EXPORT int cx_linked_list_compare(const void *begin_left, const void *begin_right,
472 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func); 587 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func);
473 588
474 /** 589 /**
590 * Compares two lists element wise.
591 *
592 * @attention Both lists must have the same structure.
593 *
594 * @param begin_left the beginning of the left list (@c NULL denotes an empty list)
595 * @param begin_right the beginning of the right list (@c NULL denotes an empty list)
596 * @param loc_advance the location of the pointer to advance
597 * @param loc_data the location of the @c data pointer within your node struct
598 * @param cmp_func the function to compare the elements
599 * @return the first non-zero result of invoking @p cmp_func or: negative if the left list is smaller than the
600 * right list, positive if the left list is larger than the right list, zero if both lists are equal.
601 */
602 cx_attr_nonnull_arg(5)
603 CX_EXPORT int cx_linked_list_compare_c(const void *begin_left, const void *begin_right,
604 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func2 cmp_func, void *context);
605
606 /**
475 * Reverses the order of the nodes in a linked list. 607 * Reverses the order of the nodes in a linked list.
476 * 608 *
477 * @param begin a pointer to the beginning node pointer (required) 609 * @param begin a pointer to the beginning node pointer (required)
478 * @param end a pointer to the end node pointer (optional) 610 * @param end a pointer to the end node pointer (optional)
479 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 611 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)

mercurial