blob: 2f43d91f2fbe75d6eeffee90c09492ffe2756cb3 [file] [log] [blame]
Ben Cheng21eab512012-03-13 23:04:57 -07001/*-
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 Hughesa4681232019-11-04 13:59:12 -08009#pragma once
10
11/**
12 * @file search.h
13 * @brief Queues, hash tables, trees, and linear array searches.
14 */
Ben Cheng21eab512012-03-13 23:04:57 -070015
16#include <sys/cdefs.h>
Elliott Hughes7f3a2722014-04-01 12:40:00 -070017#include <sys/types.h>
Ben Cheng21eab512012-03-13 23:04:57 -070018
Elliott Hughesa4681232019-11-04 13:59:12 -080019/** See hsearch()/hsearch_r(). */
Elliott Hughes7f3a2722014-04-01 12:40:00 -070020typedef enum {
Elliott Hughes5702c6f2017-08-31 17:27:05 -070021 FIND,
22 ENTER
23} ACTION;
24
Elliott Hughesa4681232019-11-04 13:59:12 -080025/** See hsearch()/hsearch_r(). */
Elliott Hughes5702c6f2017-08-31 17:27:05 -070026typedef struct entry {
Elliott Hughesa4681232019-11-04 13:59:12 -080027 /** The string key. */
zijunzhaofdf9e2e2023-04-05 19:40:21 +000028 char* _Nullable key;
Elliott Hughesa4681232019-11-04 13:59:12 -080029 /** The associated data. */
zijunzhaofdf9e2e2023-04-05 19:40:21 +000030 void* _Nullable data;
Elliott Hughes5702c6f2017-08-31 17:27:05 -070031} ENTRY;
32
Elliott Hughesa4681232019-11-04 13:59:12 -080033/**
34 * Constants given to the twalk() visitor.
35 * Note that the constant names are misleading.
36 */
Elliott Hughes5702c6f2017-08-31 17:27:05 -070037typedef enum {
Elliott Hughesa4681232019-11-04 13:59:12 -080038 /**
39 * If this is the first visit to a non-leaf node.
40 * Use this for *preorder* traversal.
41 */
Elliott Hughes7f3a2722014-04-01 12:40:00 -070042 preorder,
Elliott Hughesa4681232019-11-04 13:59:12 -080043 /**
44 * If this is the second visit to a non-leaf node.
45 * Use this for *inorder* traversal.
46 */
Elliott Hughes7f3a2722014-04-01 12:40:00 -070047 postorder,
Elliott Hughesa4681232019-11-04 13:59:12 -080048 /**
49 * If this is the third visit to a non-leaf node.
50 * Use this for *postorder* traversal.
51 */
Elliott Hughes7f3a2722014-04-01 12:40:00 -070052 endorder,
Elliott Hughesa4681232019-11-04 13:59:12 -080053 /** If this is the first and only visit to a leaf node. */
Elliott Hughes7f3a2722014-04-01 12:40:00 -070054 leaf
Ben Cheng21eab512012-03-13 23:04:57 -070055} VISIT;
56
Elliott Hughes5702c6f2017-08-31 17:27:05 -070057#if defined(__USE_BSD) || defined(__USE_GNU)
Elliott Hughesa4681232019-11-04 13:59:12 -080058/** The hash table type for hcreate_r()/hdestroy_r()/hsearch_r(). */
Elliott Hughes5702c6f2017-08-31 17:27:05 -070059struct hsearch_data {
zijunzhaofdf9e2e2023-04-05 19:40:21 +000060 struct __hsearch* _Nullable __hsearch;
Elliott Hughes5702c6f2017-08-31 17:27:05 -070061};
Ben Cheng21eab512012-03-13 23:04:57 -070062#endif
63
64__BEGIN_DECLS
Elliott Hughes7f3a2722014-04-01 12:40:00 -070065
Elliott Hughesa4681232019-11-04 13:59:12 -080066/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +000067 * [insque(3)](https://man7.org/linux/man-pages/man3/insque.3.html) inserts
Elliott Hughesa4681232019-11-04 13:59:12 -080068 * an item in a queue (an intrusive doubly-linked list).
Elliott Hughesa4681232019-11-04 13:59:12 -080069 */
Elliott Hughes655e4302023-06-16 12:39:33 -070070void insque(void* _Nonnull __element, void* _Nullable __previous);
Elliott Hughesa4681232019-11-04 13:59:12 -080071
72/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +000073 * [remque(3)](https://man7.org/linux/man-pages/man3/remque.3.html) removes
Elliott Hughesa4681232019-11-04 13:59:12 -080074 * an item from a queue (an intrusive doubly-linked list).
Elliott Hughesa4681232019-11-04 13:59:12 -080075 */
Elliott Hughes655e4302023-06-16 12:39:33 -070076void remque(void* _Nonnull __element);
Elliott Hughesb9026412014-07-23 16:02:26 -070077
Elliott Hughesa4681232019-11-04 13:59:12 -080078/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +000079 * [hcreate(3)](https://man7.org/linux/man-pages/man3/hcreate.3.html)
Elliott Hughesa4681232019-11-04 13:59:12 -080080 * initializes the global hash table, with space for at least `__n` elements.
81 *
82 * See hcreate_r() if you need more than one hash table.
83 *
84 * Returns *non-zero* on success and returns 0 and sets `errno` on failure.
85 *
86 * Available since API level 28.
87 */
Dan Albert02ce4012024-10-25 19:13:49 +000088
89#if __BIONIC_AVAILABILITY_GUARD(28)
Elliott Hughesa4681232019-11-04 13:59:12 -080090int hcreate(size_t __n) __INTRODUCED_IN(28);
91
92/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +000093 * [hdestroy(3)](https://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys
Elliott Hughesa4681232019-11-04 13:59:12 -080094 * the global hash table.
95 *
96 * See hdestroy_r() if you need more than one hash table.
97 *
98 * Available since API level 28.
99 */
Elliott Hughescc0fe6e2018-01-30 08:54:12 -0800100void hdestroy(void) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800101
102/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000103 * [hsearch(3)](https://man7.org/linux/man-pages/man3/hsearch.3.html) finds or
Elliott Hughesa4681232019-11-04 13:59:12 -0800104 * inserts `__entry` in the global hash table, based on `__action`.
105 *
106 * See hsearch_r() if you need more than one hash table.
107 *
108 * Returns a pointer to the entry on success, and returns NULL and sets
109 * `errno` on failure.
110 *
111 * Available since API level 28.
112 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000113ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
Dan Albert02ce4012024-10-25 19:13:49 +0000114#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
115
Elliott Hughes5702c6f2017-08-31 17:27:05 -0700116
117#if defined(__USE_BSD) || defined(__USE_GNU)
Elliott Hughesa4681232019-11-04 13:59:12 -0800118
119/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000120 * [hcreate_r(3)](https://man7.org/linux/man-pages/man3/hcreate_r.3.html)
Elliott Hughesa4681232019-11-04 13:59:12 -0800121 * 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 */
Dan Albert02ce4012024-10-25 19:13:49 +0000127
128#if __BIONIC_AVAILABILITY_GUARD(28)
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000129int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800130
131/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000132 * [hdestroy_r(3)](https://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
Elliott Hughesa4681232019-11-04 13:59:12 -0800133 * the hash table `__table`.
134 *
135 * Available since API level 28.
136 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000137void hdestroy_r(struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800138
139/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000140 * [hsearch_r(3)](https://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or
Elliott Hughesa4681232019-11-04 13:59:12 -0800141 * inserts `__entry` in the hash table `__table`, based on `__action`.
142 *
143 * Returns *non-zero* on success and returns 0 and sets `errno` on failure.
144 * A pointer to the entry is returned in `*__result`.
145 *
146 * Available since API level 28.
147 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000148int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
Dan Albert02ce4012024-10-25 19:13:49 +0000149#endif /* __BIONIC_AVAILABILITY_GUARD(28) */
150
Elliott Hughesa4681232019-11-04 13:59:12 -0800151
Elliott Hughes5702c6f2017-08-31 17:27:05 -0700152#endif
153
Elliott Hughesa4681232019-11-04 13:59:12 -0800154/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000155 * [lfind(3)](https://man7.org/linux/man-pages/man3/lfind.3.html) brute-force
Elliott Hughesa4681232019-11-04 13:59:12 -0800156 * searches the unsorted array `__array` (of `__count` items each of size `__size`)
157 * for `__key`, using `__comparator`.
158 *
159 * See bsearch() if you have a sorted array.
160 *
161 * Returns a pointer to the matching element on success, or NULL on failure.
Elliott Hughesa4681232019-11-04 13:59:12 -0800162 */
Elliott Hughes655e4302023-06-16 12:39:33 -0700163void* _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));
Elliott Hughes7f3a2722014-04-01 12:40:00 -0700164
Elliott Hughesa4681232019-11-04 13:59:12 -0800165/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000166 * [lsearch(3)](https://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
Elliott Hughesa4681232019-11-04 13:59:12 -0800167 * searches the unsorted array `__array` (of `__count` items each of size `__size`)
168 * for `__key`, using `__comparator`.
169 *
170 * Unlike lfind(), on failure lsearch() will *insert* `__key` at the end of
171 * `__array` and increment `*__count`.
172 *
173 * Returns a pointer to the matching element on success, or to the newly-added
174 * element on failure.
Elliott Hughesa4681232019-11-04 13:59:12 -0800175 */
Elliott Hughes655e4302023-06-16 12:39:33 -0700176void* _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));
Elliott Hughesa4681232019-11-04 13:59:12 -0800177
178/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000179 * [tdelete(3)](https://man7.org/linux/man-pages/man3/tdelete.3.html) searches
Elliott Hughesa4681232019-11-04 13:59:12 -0800180 * 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 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000185void* _Nullable tdelete(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
Elliott Hughesa4681232019-11-04 13:59:12 -0800186
187/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000188 * [tdestroy(3)](https://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
Elliott Hughesa4681232019-11-04 13:59:12 -0800189 * the hash table `__root` using `__free_fn` on each node.
190 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000191void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable));
Elliott Hughesa4681232019-11-04 13:59:12 -0800192
193/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000194 * [tfind(3)](https://man7.org/linux/man-pages/man3/tfind.3.html) searches
Elliott Hughesa4681232019-11-04 13:59:12 -0800195 * 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 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000200void* _Nullable tfind(const void* _Nonnull __key, void* _Nullable const* _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
Elliott Hughesa4681232019-11-04 13:59:12 -0800201
202/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000203 * [tsearch(3)](https://man7.org/linux/man-pages/man3/tsearch.3.html) searches
Elliott Hughesa4681232019-11-04 13:59:12 -0800204 * 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 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000211void* _Nullable tsearch(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
Elliott Hughesa4681232019-11-04 13:59:12 -0800212
213/**
Elliott Hughesbbd39aa2024-08-13 20:59:16 +0000214 * [twalk(3)](https://man7.org/linux/man-pages/man3/twalk.3.html) calls
Elliott Hughesa4681232019-11-04 13:59:12 -0800215 * `__visitor` on every node in the tree.
216 */
Elliott Hughes655e4302023-06-16 12:39:33 -0700217void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int));
Elliott Hughes7f3a2722014-04-01 12:40:00 -0700218
Ben Cheng21eab512012-03-13 23:04:57 -0700219__END_DECLS