blob: fe897d1152032b3469142f03eef6df3865ca21be [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/**
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).
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/**
73 * [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes
74 * 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/**
79 * [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html)
80 * 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 */
88int hcreate(size_t __n) __INTRODUCED_IN(28);
89
90/**
91 * [hdestroy(3)](http://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys
92 * the global hash table.
93 *
94 * See hdestroy_r() if you need more than one hash table.
95 *
96 * Available since API level 28.
97 */
Elliott Hughescc0fe6e2018-01-30 08:54:12 -080098void hdestroy(void) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -080099
100/**
101 * [hsearch(3)](http://man7.org/linux/man-pages/man3/hsearch.3.html) finds or
102 * inserts `__entry` in the global hash table, based on `__action`.
103 *
104 * See hsearch_r() if you need more than one hash table.
105 *
106 * Returns a pointer to the entry on success, and returns NULL and sets
107 * `errno` on failure.
108 *
109 * Available since API level 28.
110 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000111ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
Elliott Hughes5702c6f2017-08-31 17:27:05 -0700112
113#if defined(__USE_BSD) || defined(__USE_GNU)
Elliott Hughesa4681232019-11-04 13:59:12 -0800114
115/**
116 * [hcreate_r(3)](http://man7.org/linux/man-pages/man3/hcreate_r.3.html)
117 * initializes a hash table `__table` with space for at least `__n` elements.
118 *
119 * Returns *non-zero* on success and returns 0 and sets `errno` on failure.
120 *
121 * Available since API level 28.
122 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000123int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800124
125/**
126 * [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
127 * the hash table `__table`.
128 *
129 * Available since API level 28.
130 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000131void hdestroy_r(struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800132
133/**
134 * [hsearch_r(3)](http://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or
135 * inserts `__entry` in the hash table `__table`, based on `__action`.
136 *
137 * Returns *non-zero* on success and returns 0 and sets `errno` on failure.
138 * A pointer to the entry is returned in `*__result`.
139 *
140 * Available since API level 28.
141 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000142int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
Elliott Hughesa4681232019-11-04 13:59:12 -0800143
Elliott Hughes5702c6f2017-08-31 17:27:05 -0700144#endif
145
Elliott Hughesa4681232019-11-04 13:59:12 -0800146/**
147 * [lfind(3)](http://man7.org/linux/man-pages/man3/lfind.3.html) brute-force
148 * searches the unsorted array `__array` (of `__count` items each of size `__size`)
149 * for `__key`, using `__comparator`.
150 *
151 * See bsearch() if you have a sorted array.
152 *
153 * Returns a pointer to the matching element on success, or NULL on failure.
Elliott Hughesa4681232019-11-04 13:59:12 -0800154 */
Elliott Hughes655e4302023-06-16 12:39:33 -0700155void* _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 -0700156
Elliott Hughesa4681232019-11-04 13:59:12 -0800157/**
158 * [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
159 * searches the unsorted array `__array` (of `__count` items each of size `__size`)
160 * for `__key`, using `__comparator`.
161 *
162 * Unlike lfind(), on failure lsearch() will *insert* `__key` at the end of
163 * `__array` and increment `*__count`.
164 *
165 * Returns a pointer to the matching element on success, or to the newly-added
166 * element on failure.
Elliott Hughesa4681232019-11-04 13:59:12 -0800167 */
Elliott Hughes655e4302023-06-16 12:39:33 -0700168void* _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 -0800169
170/**
171 * [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches
172 * for and removes an element in the tree `*__root_ptr`. The search is performed
173 * using `__comparator`.
174 *
175 * Returns a pointer to the parent of the deleted node, or NULL on failure.
176 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000177void* _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 -0800178
179/**
180 * [tdestroy(3)](http://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
181 * the hash table `__root` using `__free_fn` on each node.
182 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000183void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable));
Elliott Hughesa4681232019-11-04 13:59:12 -0800184
185/**
186 * [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches
187 * for an element in the tree `*__root_ptr`. The search is performed using
188 * `__comparator`.
189 *
190 * Returns a pointer to the matching node, or NULL on failure.
191 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000192void* _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 -0800193
194/**
195 * [tsearch(3)](http://man7.org/linux/man-pages/man3/tsearch.3.html) searches
196 * for an element in the tree `*__root_ptr`. The search is performed using
197 * `__comparator`.
198 *
199 * Unlike tfind(), on failure tsearch() will *insert* `__key` into the tree.
200 *
201 * Returns a pointer to the matching node, or to the newly-added node.
202 */
zijunzhaofdf9e2e2023-04-05 19:40:21 +0000203void* _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 -0800204
205/**
206 * [twalk(3)](http://man7.org/linux/man-pages/man3/twalk.3.html) calls
207 * `__visitor` on every node in the tree.
208 */
Elliott Hughes655e4302023-06-16 12:39:33 -0700209void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int));
Elliott Hughes7f3a2722014-04-01 12:40:00 -0700210
Ben Cheng21eab512012-03-13 23:04:57 -0700211__END_DECLS