blob: 7c4989aebff91ed1db495fac6f8aebb47255b01c [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. */
Elliott Hughes5702c6f2017-08-31 17:27:05 -070028 char* key;
Elliott Hughesa4681232019-11-04 13:59:12 -080029 /** The associated data. */
Elliott Hughes5702c6f2017-08-31 17:27:05 -070030 void* data;
31} 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 {
60 struct __hsearch* __hsearch;
61};
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/**
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 */
Elliott Hughesff26a162017-08-17 22:34:21 +000072void insque(void* __element, void* __previous) __INTRODUCED_IN(21);
Elliott Hughesa4681232019-11-04 13:59:12 -080073
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 */
Elliott Hughesff26a162017-08-17 22:34:21 +000080void remque(void* __element) __INTRODUCED_IN(21);
Elliott Hughesb9026412014-07-23 16:02:26 -070081
Elliott Hughesa4681232019-11-04 13:59:12 -080082/**
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 */
92int 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 Hughescc0fe6e2018-01-30 08:54:12 -0800102void hdestroy(void) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800103
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 */
115ENTRY* hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
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/**
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 */
127int hcreate_r(size_t __n, struct hsearch_data* __table) __INTRODUCED_IN(28);
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 */
135void hdestroy_r(struct hsearch_data* __table) __INTRODUCED_IN(28);
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 */
146int hsearch_r(ENTRY __entry, ACTION __action, ENTRY** __result, struct hsearch_data* __table) __INTRODUCED_IN(28);
147
Elliott Hughes5702c6f2017-08-31 17:27:05 -0700148#endif
149
Elliott Hughesa4681232019-11-04 13:59:12 -0800150/**
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 */
161void* lfind(const void* __key, const void* __array, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(21);
Elliott Hughes7f3a2722014-04-01 12:40:00 -0700162
Elliott Hughesa4681232019-11-04 13:59:12 -0800163/**
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 */
176void* lsearch(const void* __key, void* __array, size_t* __count, size_t __size, int (*__comparator)(const void*, const void*)) __INTRODUCED_IN(21);
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 */
185void* tdelete(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*));
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 */
191void tdestroy(void* __root, void (*__free_fn)(void*));
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 */
200void* tfind(const void* __key, void* const* __root_ptr, int (*__comparator)(const void*, const void*));
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 */
211void* tsearch(const void* __key, void** __root_ptr, int (*__comparator)(const void*, const void*));
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 */
Logan Chienaaffa3c2019-11-20 09:21:04 -0800217void twalk(const void* __root, void (*__visitor)(const void*, VISIT, int)) __INTRODUCED_IN(21);
Elliott Hughes7f3a2722014-04-01 12:40:00 -0700218
Ben Cheng21eab512012-03-13 23:04:57 -0700219__END_DECLS