Ben Cheng | 21eab51 | 2012-03-13 23:04:57 -0700 | [diff] [blame] | 1 | /*- |
| 2 | * Written by J.T. Conklin <jtc@netbsd.org> |
| 3 | * Public domain. |
| 4 | * |
| 5 | * $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $ |
| 6 | * $FreeBSD: release/9.0.0/include/search.h 105250 2002-10-16 14:29:23Z robert $ |
| 7 | */ |
| 8 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 9 | #pragma once |
| 10 | |
| 11 | /** |
| 12 | * @file search.h |
| 13 | * @brief Queues, hash tables, trees, and linear array searches. |
| 14 | */ |
Ben Cheng | 21eab51 | 2012-03-13 23:04:57 -0700 | [diff] [blame] | 15 | |
| 16 | #include <sys/cdefs.h> |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 17 | #include <sys/types.h> |
Ben Cheng | 21eab51 | 2012-03-13 23:04:57 -0700 | [diff] [blame] | 18 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 19 | /** See hsearch()/hsearch_r(). */ |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 20 | typedef enum { |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 21 | FIND, |
| 22 | ENTER |
| 23 | } ACTION; |
| 24 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 25 | /** See hsearch()/hsearch_r(). */ |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 26 | typedef struct entry { |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 27 | /** The string key. */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 28 | char* _Nullable key; |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 29 | /** The associated data. */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 30 | void* _Nullable data; |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 31 | } ENTRY; |
| 32 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 33 | /** |
| 34 | * Constants given to the twalk() visitor. |
| 35 | * Note that the constant names are misleading. |
| 36 | */ |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 37 | typedef enum { |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 38 | /** |
| 39 | * If this is the first visit to a non-leaf node. |
| 40 | * Use this for *preorder* traversal. |
| 41 | */ |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 42 | preorder, |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 43 | /** |
| 44 | * If this is the second visit to a non-leaf node. |
| 45 | * Use this for *inorder* traversal. |
| 46 | */ |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 47 | postorder, |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 48 | /** |
| 49 | * If this is the third visit to a non-leaf node. |
| 50 | * Use this for *postorder* traversal. |
| 51 | */ |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 52 | endorder, |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 53 | /** If this is the first and only visit to a leaf node. */ |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 54 | leaf |
Ben Cheng | 21eab51 | 2012-03-13 23:04:57 -0700 | [diff] [blame] | 55 | } VISIT; |
| 56 | |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 57 | #if defined(__USE_BSD) || defined(__USE_GNU) |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 58 | /** The hash table type for hcreate_r()/hdestroy_r()/hsearch_r(). */ |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 59 | struct hsearch_data { |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 60 | struct __hsearch* _Nullable __hsearch; |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 61 | }; |
Ben Cheng | 21eab51 | 2012-03-13 23:04:57 -0700 | [diff] [blame] | 62 | #endif |
| 63 | |
| 64 | __BEGIN_DECLS |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 65 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 66 | /** |
| 67 | * [insque(3)](http://man7.org/linux/man-pages/man3/insque.3.html) inserts |
| 68 | * an item in a queue (an intrusive doubly-linked list). |
| 69 | * |
| 70 | * Available since API level 21. |
| 71 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 72 | void insque(void* _Nonnull __element, void* _Nullable __previous) __INTRODUCED_IN(21); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 73 | |
| 74 | /** |
| 75 | * [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes |
| 76 | * an item from a queue (an intrusive doubly-linked list). |
| 77 | * |
| 78 | * Available since API level 21. |
| 79 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 80 | void remque(void* _Nonnull __element) __INTRODUCED_IN(21); |
Elliott Hughes | b902641 | 2014-07-23 16:02:26 -0700 | [diff] [blame] | 81 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 82 | /** |
| 83 | * [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html) |
| 84 | * initializes the global hash table, with space for at least `__n` elements. |
| 85 | * |
| 86 | * See hcreate_r() if you need more than one hash table. |
| 87 | * |
| 88 | * Returns *non-zero* on success and returns 0 and sets `errno` on failure. |
| 89 | * |
| 90 | * Available since API level 28. |
| 91 | */ |
| 92 | int hcreate(size_t __n) __INTRODUCED_IN(28); |
| 93 | |
| 94 | /** |
| 95 | * [hdestroy(3)](http://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys |
| 96 | * the global hash table. |
| 97 | * |
| 98 | * See hdestroy_r() if you need more than one hash table. |
| 99 | * |
| 100 | * Available since API level 28. |
| 101 | */ |
Elliott Hughes | cc0fe6e | 2018-01-30 08:54:12 -0800 | [diff] [blame] | 102 | void hdestroy(void) __INTRODUCED_IN(28); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 103 | |
| 104 | /** |
| 105 | * [hsearch(3)](http://man7.org/linux/man-pages/man3/hsearch.3.html) finds or |
| 106 | * inserts `__entry` in the global hash table, based on `__action`. |
| 107 | * |
| 108 | * See hsearch_r() if you need more than one hash table. |
| 109 | * |
| 110 | * Returns a pointer to the entry on success, and returns NULL and sets |
| 111 | * `errno` on failure. |
| 112 | * |
| 113 | * Available since API level 28. |
| 114 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 115 | ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28); |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 116 | |
| 117 | #if defined(__USE_BSD) || defined(__USE_GNU) |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 118 | |
| 119 | /** |
| 120 | * [hcreate_r(3)](http://man7.org/linux/man-pages/man3/hcreate_r.3.html) |
| 121 | * initializes a hash table `__table` with space for at least `__n` elements. |
| 122 | * |
| 123 | * Returns *non-zero* on success and returns 0 and sets `errno` on failure. |
| 124 | * |
| 125 | * Available since API level 28. |
| 126 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 127 | int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 128 | |
| 129 | /** |
| 130 | * [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys |
| 131 | * the hash table `__table`. |
| 132 | * |
| 133 | * Available since API level 28. |
| 134 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 135 | void hdestroy_r(struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 136 | |
| 137 | /** |
| 138 | * [hsearch_r(3)](http://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or |
| 139 | * inserts `__entry` in the hash table `__table`, based on `__action`. |
| 140 | * |
| 141 | * Returns *non-zero* on success and returns 0 and sets `errno` on failure. |
| 142 | * A pointer to the entry is returned in `*__result`. |
| 143 | * |
| 144 | * Available since API level 28. |
| 145 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 146 | int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 147 | |
Elliott Hughes | 5702c6f | 2017-08-31 17:27:05 -0700 | [diff] [blame] | 148 | #endif |
| 149 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 150 | /** |
| 151 | * [lfind(3)](http://man7.org/linux/man-pages/man3/lfind.3.html) brute-force |
| 152 | * searches the unsorted array `__array` (of `__count` items each of size `__size`) |
| 153 | * for `__key`, using `__comparator`. |
| 154 | * |
| 155 | * See bsearch() if you have a sorted array. |
| 156 | * |
| 157 | * Returns a pointer to the matching element on success, or NULL on failure. |
| 158 | * |
| 159 | * Available since API level 21. |
| 160 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 161 | void* _Nullable lfind(const void* _Nonnull __key, const void* _Nonnull __array, size_t* _Nonnull __count, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)) __INTRODUCED_IN(21); |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 162 | |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 163 | /** |
| 164 | * [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force |
| 165 | * searches the unsorted array `__array` (of `__count` items each of size `__size`) |
| 166 | * for `__key`, using `__comparator`. |
| 167 | * |
| 168 | * Unlike lfind(), on failure lsearch() will *insert* `__key` at the end of |
| 169 | * `__array` and increment `*__count`. |
| 170 | * |
| 171 | * Returns a pointer to the matching element on success, or to the newly-added |
| 172 | * element on failure. |
| 173 | * |
| 174 | * Available since API level 21. |
| 175 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 176 | void* _Nonnull lsearch(const void* _Nonnull __key, void* _Nonnull __array, size_t* _Nonnull __count, size_t __size, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)) __INTRODUCED_IN(21); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 177 | |
| 178 | /** |
| 179 | * [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches |
| 180 | * for and removes an element in the tree `*__root_ptr`. The search is performed |
| 181 | * using `__comparator`. |
| 182 | * |
| 183 | * Returns a pointer to the parent of the deleted node, or NULL on failure. |
| 184 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 185 | void* _Nullable tdelete(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 186 | |
| 187 | /** |
| 188 | * [tdestroy(3)](http://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys |
| 189 | * the hash table `__root` using `__free_fn` on each node. |
| 190 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 191 | void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable)); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 192 | |
| 193 | /** |
| 194 | * [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches |
| 195 | * for an element in the tree `*__root_ptr`. The search is performed using |
| 196 | * `__comparator`. |
| 197 | * |
| 198 | * Returns a pointer to the matching node, or NULL on failure. |
| 199 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 200 | void* _Nullable tfind(const void* _Nonnull __key, void* _Nullable const* _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 201 | |
| 202 | /** |
| 203 | * [tsearch(3)](http://man7.org/linux/man-pages/man3/tsearch.3.html) searches |
| 204 | * for an element in the tree `*__root_ptr`. The search is performed using |
| 205 | * `__comparator`. |
| 206 | * |
| 207 | * Unlike tfind(), on failure tsearch() will *insert* `__key` into the tree. |
| 208 | * |
| 209 | * Returns a pointer to the matching node, or to the newly-added node. |
| 210 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 211 | void* _Nullable tsearch(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull)); |
Elliott Hughes | a468123 | 2019-11-04 13:59:12 -0800 | [diff] [blame] | 212 | |
| 213 | /** |
| 214 | * [twalk(3)](http://man7.org/linux/man-pages/man3/twalk.3.html) calls |
| 215 | * `__visitor` on every node in the tree. |
| 216 | */ |
zijunzhao | fdf9e2e | 2023-04-05 19:40:21 +0000 | [diff] [blame] | 217 | void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int)) __INTRODUCED_IN(21); |
Elliott Hughes | 7f3a272 | 2014-04-01 12:40:00 -0700 | [diff] [blame] | 218 | |
Ben Cheng | 21eab51 | 2012-03-13 23:04:57 -0700 | [diff] [blame] | 219 | __END_DECLS |