2012-03-14 07:04:57 +01:00
|
|
|
/*-
|
|
|
|
* Written by J.T. Conklin <jtc@netbsd.org>
|
|
|
|
* Public domain.
|
|
|
|
*
|
|
|
|
* $NetBSD: search.h,v 1.12 1999/02/22 10:34:28 christos Exp $
|
|
|
|
* $FreeBSD: release/9.0.0/include/search.h 105250 2002-10-16 14:29:23Z robert $
|
|
|
|
*/
|
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file search.h
|
|
|
|
* @brief Queues, hash tables, trees, and linear array searches.
|
|
|
|
*/
|
2012-03-14 07:04:57 +01:00
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
2014-04-01 21:40:00 +02:00
|
|
|
#include <sys/types.h>
|
2012-03-14 07:04:57 +01:00
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/** See hsearch()/hsearch_r(). */
|
2017-09-01 02:27:05 +02:00
|
|
|
typedef enum {
|
|
|
|
FIND,
|
|
|
|
ENTER
|
|
|
|
} ACTION;
|
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/** See hsearch()/hsearch_r(). */
|
2017-09-01 02:27:05 +02:00
|
|
|
typedef struct entry {
|
2019-11-04 22:59:12 +01:00
|
|
|
/** The string key. */
|
2023-04-05 21:40:21 +02:00
|
|
|
char* _Nullable key;
|
2019-11-04 22:59:12 +01:00
|
|
|
/** The associated data. */
|
2023-04-05 21:40:21 +02:00
|
|
|
void* _Nullable data;
|
2017-09-01 02:27:05 +02:00
|
|
|
} ENTRY;
|
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* Constants given to the twalk() visitor.
|
|
|
|
* Note that the constant names are misleading.
|
|
|
|
*/
|
2014-04-01 21:40:00 +02:00
|
|
|
typedef enum {
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* If this is the first visit to a non-leaf node.
|
|
|
|
* Use this for *preorder* traversal.
|
|
|
|
*/
|
2014-04-01 21:40:00 +02:00
|
|
|
preorder,
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* If this is the second visit to a non-leaf node.
|
|
|
|
* Use this for *inorder* traversal.
|
|
|
|
*/
|
2014-04-01 21:40:00 +02:00
|
|
|
postorder,
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* If this is the third visit to a non-leaf node.
|
|
|
|
* Use this for *postorder* traversal.
|
|
|
|
*/
|
2014-04-01 21:40:00 +02:00
|
|
|
endorder,
|
2019-11-04 22:59:12 +01:00
|
|
|
/** If this is the first and only visit to a leaf node. */
|
2014-04-01 21:40:00 +02:00
|
|
|
leaf
|
2012-03-14 07:04:57 +01:00
|
|
|
} VISIT;
|
|
|
|
|
2017-09-01 02:27:05 +02:00
|
|
|
#if defined(__USE_BSD) || defined(__USE_GNU)
|
2019-11-04 22:59:12 +01:00
|
|
|
/** The hash table type for hcreate_r()/hdestroy_r()/hsearch_r(). */
|
2017-09-01 02:27:05 +02:00
|
|
|
struct hsearch_data {
|
2023-04-05 21:40:21 +02:00
|
|
|
struct __hsearch* _Nullable __hsearch;
|
2017-09-01 02:27:05 +02:00
|
|
|
};
|
2012-03-14 07:04:57 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
__BEGIN_DECLS
|
2014-04-01 21:40:00 +02:00
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* [insque(3)](http://man7.org/linux/man-pages/man3/insque.3.html) inserts
|
|
|
|
* an item in a queue (an intrusive doubly-linked list).
|
|
|
|
*/
|
2023-06-16 21:39:33 +02:00
|
|
|
void insque(void* _Nonnull __element, void* _Nullable __previous);
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [remque(3)](http://man7.org/linux/man-pages/man3/remque.3.html) removes
|
|
|
|
* an item from a queue (an intrusive doubly-linked list).
|
|
|
|
*/
|
2023-06-16 21:39:33 +02:00
|
|
|
void remque(void* _Nonnull __element);
|
2016-04-29 21:00:55 +02:00
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* [hcreate(3)](http://man7.org/linux/man-pages/man3/hcreate.3.html)
|
|
|
|
* initializes the global hash table, with space for at least `__n` elements.
|
|
|
|
*
|
|
|
|
* See hcreate_r() if you need more than one hash table.
|
|
|
|
*
|
|
|
|
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
|
|
|
|
*
|
|
|
|
* Available since API level 28.
|
|
|
|
*/
|
|
|
|
int hcreate(size_t __n) __INTRODUCED_IN(28);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* [hdestroy(3)](http://man7.org/linux/man-pages/man3/hdestroy.3.html) destroys
|
|
|
|
* the global hash table.
|
|
|
|
*
|
|
|
|
* See hdestroy_r() if you need more than one hash table.
|
|
|
|
*
|
|
|
|
* Available since API level 28.
|
|
|
|
*/
|
2018-01-30 17:54:12 +01:00
|
|
|
void hdestroy(void) __INTRODUCED_IN(28);
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [hsearch(3)](http://man7.org/linux/man-pages/man3/hsearch.3.html) finds or
|
|
|
|
* inserts `__entry` in the global hash table, based on `__action`.
|
|
|
|
*
|
|
|
|
* See hsearch_r() if you need more than one hash table.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the entry on success, and returns NULL and sets
|
|
|
|
* `errno` on failure.
|
|
|
|
*
|
|
|
|
* Available since API level 28.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
ENTRY* _Nullable hsearch(ENTRY __entry, ACTION __action) __INTRODUCED_IN(28);
|
2017-09-01 02:27:05 +02:00
|
|
|
|
|
|
|
#if defined(__USE_BSD) || defined(__USE_GNU)
|
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* [hcreate_r(3)](http://man7.org/linux/man-pages/man3/hcreate_r.3.html)
|
|
|
|
* initializes a hash table `__table` with space for at least `__n` elements.
|
|
|
|
*
|
|
|
|
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
|
|
|
|
*
|
|
|
|
* Available since API level 28.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
int hcreate_r(size_t __n, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
|
2016-04-29 21:00:55 +02:00
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* [hdestroy_r(3)](http://man7.org/linux/man-pages/man3/hdestroy_r.3.html) destroys
|
|
|
|
* the hash table `__table`.
|
|
|
|
*
|
|
|
|
* Available since API level 28.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
void hdestroy_r(struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
|
2014-04-01 21:40:00 +02:00
|
|
|
|
2019-11-04 22:59:12 +01:00
|
|
|
/**
|
|
|
|
* [hsearch_r(3)](http://man7.org/linux/man-pages/man3/hsearch_r.3.html) finds or
|
|
|
|
* inserts `__entry` in the hash table `__table`, based on `__action`.
|
|
|
|
*
|
|
|
|
* Returns *non-zero* on success and returns 0 and sets `errno` on failure.
|
|
|
|
* A pointer to the entry is returned in `*__result`.
|
|
|
|
*
|
|
|
|
* Available since API level 28.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
int hsearch_r(ENTRY __entry, ACTION __action, ENTRY* _Nullable * _Nonnull __result, struct hsearch_data* _Nonnull __table) __INTRODUCED_IN(28);
|
2012-03-14 07:04:57 +01:00
|
|
|
|
2017-08-18 00:34:21 +02:00
|
|
|
#endif
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [lfind(3)](http://man7.org/linux/man-pages/man3/lfind.3.html) brute-force
|
|
|
|
* searches the unsorted array `__array` (of `__count` items each of size `__size`)
|
|
|
|
* for `__key`, using `__comparator`.
|
|
|
|
*
|
|
|
|
* See bsearch() if you have a sorted array.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the matching element on success, or NULL on failure.
|
|
|
|
*/
|
2023-06-16 21:39:33 +02:00
|
|
|
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));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [lsearch(3)](http://man7.org/linux/man-pages/man3/lsearch.3.html) brute-force
|
|
|
|
* searches the unsorted array `__array` (of `__count` items each of size `__size`)
|
|
|
|
* for `__key`, using `__comparator`.
|
|
|
|
*
|
|
|
|
* Unlike lfind(), on failure lsearch() will *insert* `__key` at the end of
|
|
|
|
* `__array` and increment `*__count`.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the matching element on success, or to the newly-added
|
|
|
|
* element on failure.
|
|
|
|
*/
|
2023-06-16 21:39:33 +02:00
|
|
|
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));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [tdelete(3)](http://man7.org/linux/man-pages/man3/tdelete.3.html) searches
|
|
|
|
* for and removes an element in the tree `*__root_ptr`. The search is performed
|
|
|
|
* using `__comparator`.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the parent of the deleted node, or NULL on failure.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
void* _Nullable tdelete(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [tdestroy(3)](http://man7.org/linux/man-pages/man3/tdestroy.3.html) destroys
|
|
|
|
* the hash table `__root` using `__free_fn` on each node.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
void tdestroy(void* _Nullable __root, void (* _Nullable __free_fn)(void* _Nullable));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [tfind(3)](http://man7.org/linux/man-pages/man3/tfind.3.html) searches
|
|
|
|
* for an element in the tree `*__root_ptr`. The search is performed using
|
|
|
|
* `__comparator`.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the matching node, or NULL on failure.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
void* _Nullable tfind(const void* _Nonnull __key, void* _Nullable const* _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [tsearch(3)](http://man7.org/linux/man-pages/man3/tsearch.3.html) searches
|
|
|
|
* for an element in the tree `*__root_ptr`. The search is performed using
|
|
|
|
* `__comparator`.
|
|
|
|
*
|
|
|
|
* Unlike tfind(), on failure tsearch() will *insert* `__key` into the tree.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the matching node, or to the newly-added node.
|
|
|
|
*/
|
2023-04-05 21:40:21 +02:00
|
|
|
void* _Nullable tsearch(const void* _Nonnull __key, void* _Nullable * _Nullable __root_ptr, int (* _Nonnull __comparator)(const void* _Nonnull, const void* _Nonnull));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* [twalk(3)](http://man7.org/linux/man-pages/man3/twalk.3.html) calls
|
|
|
|
* `__visitor` on every node in the tree.
|
|
|
|
*/
|
2023-06-16 21:39:33 +02:00
|
|
|
void twalk(const void* _Nullable __root, void (* _Nullable __visitor)(const void* _Nullable, VISIT, int));
|
2019-11-04 22:59:12 +01:00
|
|
|
|
|
|
|
__END_DECLS
|