xref: /openbsd-src/lib/libutil/ohash_init.3 (revision 301058f158b6b04fe69371b7cb23adfc48be5603)
1*301058f1Sschwarze.\"	$OpenBSD: ohash_init.3,v 1.3 2019/04/23 18:13:11 schwarze Exp $
242dcb487Sespie.\" Copyright (c) 1999 Marc Espie <espie@openbsd.org>
342dcb487Sespie.\"
442dcb487Sespie.\" Permission to use, copy, modify, and distribute this software for any
542dcb487Sespie.\" purpose with or without fee is hereby granted, provided that the above
642dcb487Sespie.\" copyright notice and this permission notice appear in all copies.
742dcb487Sespie.\"
842dcb487Sespie.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
942dcb487Sespie.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1042dcb487Sespie.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1142dcb487Sespie.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1242dcb487Sespie.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1342dcb487Sespie.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1442dcb487Sespie.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1542dcb487Sespie.\"
16*301058f1Sschwarze.Dd $Mdocdate: April 23 2019 $
1742dcb487Sespie.Dt OHASH_INIT 3
1842dcb487Sespie.Os
1942dcb487Sespie.Sh NAME
2042dcb487Sespie.Nm ohash_init ,
2142dcb487Sespie.Nm ohash_delete ,
2242dcb487Sespie.Nm ohash_lookup_interval ,
2342dcb487Sespie.Nm ohash_lookup_memory ,
2442dcb487Sespie.Nm ohash_find ,
2542dcb487Sespie.Nm ohash_remove ,
2642dcb487Sespie.Nm ohash_insert ,
2742dcb487Sespie.Nm ohash_first ,
2842dcb487Sespie.Nm ohash_next ,
2942dcb487Sespie.Nm ohash_entries
3042dcb487Sespie.Nd light-weight open hashing
3142dcb487Sespie.Sh SYNOPSIS
3242dcb487Sespie.In stdint.h
3342dcb487Sespie.In stddef.h
3442dcb487Sespie.In ohash.h
3542dcb487Sespie.Ft void
3642dcb487Sespie.Fn ohash_init "struct ohash *h" "unsigned int size" "struct ohash_info *info"
3742dcb487Sespie.Ft void
3842dcb487Sespie.Fn ohash_delete "struct ohash *h"
3942dcb487Sespie.Ft "unsigned int"
4042dcb487Sespie.Fn ohash_lookup_interval "struct ohash *h" "const char *start" "const char *end" "uint32_t hv"
4142dcb487Sespie.Ft "unsigned int"
4242dcb487Sespie.Fn ohash_lookup_memory "struct ohash *h" "const char *k" "size_t s" "uint32_t hv"
4342dcb487Sespie.Ft void *
4442dcb487Sespie.Fn ohash_find "struct ohash *h" "unsigned int i"
4542dcb487Sespie.Ft void *
4642dcb487Sespie.Fn ohash_remove "struct ohash *h" "unsigned int i"
4742dcb487Sespie.Ft void *
4842dcb487Sespie.Fn ohash_insert "struct ohash *h" "unsigned int i" "void *p"
4942dcb487Sespie.Ft void *
5042dcb487Sespie.Fn ohash_first "struct ohash *h" "unsigned int *i"
5142dcb487Sespie.Ft void *
5242dcb487Sespie.Fn ohash_next "struct ohash *h" "unsigned int *i"
5342dcb487Sespie.Ft "unsigned int"
5442dcb487Sespie.Fn ohash_entries "struct ohash *h"
5542dcb487Sespie.Sh DESCRIPTION
5642dcb487SespieThese functions have been designed as a fast, extensible alternative to
5742dcb487Sespiethe usual hash table functions.
5842dcb487SespieThey provide storage and retrieval of records indexed by keys,
5942dcb487Sespiewhere a key is a contiguous sequence of bytes at a fixed position in
6042dcb487Sespieeach record.
6142dcb487SespieKeys can either be NUL-terminated strings or fixed-size memory areas.
6242dcb487SespieAll functions take a pointer to an ohash structure as the
6342dcb487Sespie.Fa h
6442dcb487Sespiefunction argument.
6542dcb487SespieStorage for this structure should be provided by user code.
6642dcb487Sespie.Pp
6742dcb487Sespie.Fn ohash_init
6842dcb487Sespieinitializes the table to store roughly 2 to the power
6942dcb487Sespie.Fa size
7042dcb487Sespieelements.
7142dcb487Sespie.Fa info
7242dcb487Sespieis a pointer to a
7342dcb487Sespie.Fa struct ohash_info .
7442dcb487Sespie.Bd -literal -offset indent
7542dcb487Sespiestruct ohash_info {
7642dcb487Sespie	ptrdiff_t key_offset;
7742dcb487Sespie	void *data;	/* user data */
7842dcb487Sespie	void *(*calloc)(size_t, size_t, void *);
7942dcb487Sespie	void (*free)(void *, void *);
8042dcb487Sespie	void *(*alloc)(size_t, void *);
8142dcb487Sespie};
8242dcb487Sespie.Ed
8342dcb487Sespie.Pp
8442dcb487SespieThe
8542dcb487Sespie.Va offset
8642dcb487Sespiefield holds the position of the key in each record;
8742dcb487Sespiethe
8842dcb487Sespie.Va calloc
8942dcb487Sespieand
9042dcb487Sespie.Va free
9142dcb487Sespiefields are pointers to
9242dcb487Sespie.Xr calloc 3
9342dcb487Sespieand
9442dcb487Sespie.Xr free 3 Ns -like
9542dcb487Sespiefunctions, used for managing the table internal storage;
9642dcb487Sespiethe
9742dcb487Sespie.Va alloc
9842dcb487Sespiefield is only used by the utility function
9942dcb487Sespie.Xr ohash_create_entry 3 .
10042dcb487Sespie.Pp
10142dcb487SespieEach of these functions are called similarly to their standard counterpart,
10242dcb487Sespiebut with an extra
10342dcb487Sespie.Ft void *
10442dcb487Sespieparameter corresponding to the content of the field
10542dcb487Sespie.Fa data ,
10642dcb487Sespiewhich can be used to communicate specific information to the functions.
10742dcb487Sespie.Pp
10842dcb487Sespie.Fn ohash_init
10942dcb487Sespiestores a copy of those fields internally, so
11042dcb487Sespie.Fa info
11142dcb487Sespiecan be reclaimed after initialization.
11242dcb487Sespie.Pp
11342dcb487Sespie.Fn ohash_delete
11442dcb487Sespiefrees storage internal to
11542dcb487Sespie.Fa h .
11642dcb487SespieElements themselves should be freed by the user first, using for instance
11742dcb487Sespie.Fn ohash_first
11842dcb487Sespieand
11942dcb487Sespie.Fn ohash_next .
12042dcb487Sespie.Pp
12142dcb487Sespie.Fn ohash_lookup_interval
12242dcb487Sespieand
12342dcb487Sespie.Fn ohash_lookup_memory
12442dcb487Sespieare the basic look-up element functions.
12542dcb487SespieThe hashing function result is provided by the user as
12642dcb487Sespie.Fa hv .
12742dcb487SespieThese return a
12842dcb487Sespie.Qq slot
12942dcb487Sespiein the ohash table
13042dcb487Sespie.Fa h ,
13142dcb487Sespieto be used with
13242dcb487Sespie.Fn ohash_find ,
13342dcb487Sespie.Fn ohash_insert ,
13442dcb487Sespieor
13542dcb487Sespie.Fn ohash_remove .
13642dcb487SespieThis slot is only valid up to the next call to
13742dcb487Sespie.Fn ohash_insert
13842dcb487Sespieor
13942dcb487Sespie.Fn ohash_remove .
14042dcb487Sespie.Pp
14142dcb487Sespie.Fn ohash_lookup_interval
14242dcb487Sespiehandles string-like keys.
14342dcb487Sespie.Fn ohash_lookup_interval
14442dcb487Sespieassumes the key is the interval between
14542dcb487Sespie.Fa start
14642dcb487Sespieand
14742dcb487Sespie.Fa end ,
14842dcb487Sespieexclusive,
14942dcb487Sespiethough the actual elements stored in the table should only contain
15042dcb487SespieNUL-terminated keys.
15142dcb487Sespie.Pp
15242dcb487Sespie.Fn ohash_lookup_memory
15342dcb487Sespieassumes the key is the memory area starting at
15442dcb487Sespie.Fa k
15542dcb487Sespieof size
15642dcb487Sespie.Fa s .
15742dcb487SespieAll bytes are significant in key comparison.
15842dcb487Sespie.Pp
15942dcb487Sespie.Fn ohash_find
16042dcb487Sespieretrieves an element from a slot
16142dcb487Sespie.Fa i
16242dcb487Sespiereturned by the
16342dcb487Sespie.Fn ohash_lookup*
16442dcb487Sespiefunctions.
16542dcb487SespieIt returns
16642dcb487Sespie.Dv NULL
16742dcb487Sespieif the slot is empty.
16842dcb487Sespie.Pp
16942dcb487Sespie.Fn ohash_insert
17042dcb487Sespieinserts a new element
17142dcb487Sespie.Fa p
17242dcb487Sespieat slot
17342dcb487Sespie.Fa i .
17442dcb487SespieSlot
17542dcb487Sespie.Fa i
17642dcb487Sespiemust be empty and element
17742dcb487Sespie.Fa p
17842dcb487Sespiemust have a key corresponding to the
17942dcb487Sespie.Fn ohash_lookup*
18042dcb487Sespiecall.
18142dcb487Sespie.Pp
18242dcb487Sespie.Fn ohash_remove
18342dcb487Sespieremoves the element at slot
18442dcb487Sespie.Fa i .
18542dcb487SespieIt returns the removed element, for user code to dispose of, or
18642dcb487Sespie.Dv NULL
18742dcb487Sespieif the slot was empty.
18842dcb487Sespie.Pp
18942dcb487Sespie.Fn ohash_first
19042dcb487Sespieand
19142dcb487Sespie.Fn ohash_next
19242dcb487Sespiecan be used to access all elements in an ohash table, like this:
19342dcb487Sespie.Bd -literal -offset indent
19442dcb487Sespiefor (n = ohash_first(h, &i); n != NULL; n = ohash_next(h, &i))
19542dcb487Sespie	do_something_with(n);
19642dcb487Sespie.Ed
19742dcb487Sespie.Pp
19842dcb487Sespie.Fa i
19942dcb487Sespiepoints to an auxiliary unsigned integer used to record the current position
20042dcb487Sespiein the ohash table.
20142dcb487SespieThose functions are safe to use even while entries are added to/removed
20242dcb487Sespiefrom the table, but in such a case they don't guarantee that new entries
20342dcb487Sespiewill be returned.
20442dcb487SespieAs a special case, they can safely be used to free elements in the table.
20542dcb487Sespie.Pp
20642dcb487Sespie.Fn ohash_entries
20742dcb487Sespiereturns the number of elements in the hash table.
20842dcb487Sespie.Sh STORAGE HANDLING
20942dcb487SespieOnly
21042dcb487Sespie.Fn ohash_init ,
21142dcb487Sespie.Fn ohash_insert ,
21242dcb487Sespie.Fn ohash_remove
21342dcb487Sespieand
21442dcb487Sespie.Fn ohash_delete
21542dcb487Sespiemay call the user-supplied memory functions:
21642dcb487Sespie.Bd -literal -offset indent
21742dcb487Sespiep = (*info->calloc)(n, sizeof_record, info->data);
21842dcb487Sespie/* copy data from old to p */
21942dcb487Sespie(*info->free)(old, info->data);
22042dcb487Sespie.Ed
22142dcb487Sespie.Pp
22242dcb487SespieIt is the responsibility of the user memory allocation code to verify
22342dcb487Sespiethat those calls did not fail.
22442dcb487Sespie.Pp
22542dcb487SespieIf memory allocation fails,
22642dcb487Sespie.Fn ohash_init
22742dcb487Sespiereturns a useless hash table.
22842dcb487Sespie.Fn ohash_insert
22942dcb487Sespieand
23042dcb487Sespie.Fn ohash_remove
23142dcb487Sespiestill perform the requested operation, but the returned table should be
23242dcb487Sespieconsidered read-only.
23342dcb487SespieIt can still be accessed by
23442dcb487Sespie.Fn ohash_lookup* ,
23542dcb487Sespie.Fn ohash_find ,
23642dcb487Sespie.Fn ohash_first
23742dcb487Sespieand
23842dcb487Sespie.Fn ohash_next
23942dcb487Sespieto dump relevant information to disk before aborting.
24042dcb487Sespie.Sh THREAD SAFETY
24142dcb487SespieThe open hashing functions are not thread-safe by design.
24242dcb487SespieIn particular, in a threaded environment, there is no guarantee that a
24342dcb487Sespie.Qq slot
24442dcb487Sespiewill not move between a
24542dcb487Sespie.Fn ohash_lookup*
24642dcb487Sespieand a
24742dcb487Sespie.Fn ohash_find ,
24842dcb487Sespie.Fn ohash_insert
24942dcb487Sespieor
25042dcb487Sespie.Fn ohash_remove
25142dcb487Sespiecall.
25242dcb487Sespie.Pp
25342dcb487SespieMulti-threaded applications should explicitly protect ohash table access.
25442dcb487Sespie.Sh SEE ALSO
25542dcb487Sespie.Xr hcreate 3 ,
25642dcb487Sespie.Xr ohash_interval 3
25742dcb487Sespie.Rs
25842dcb487Sespie.%A Donald E. Knuth
25942dcb487Sespie.%B The Art of Computer Programming
26042dcb487Sespie.%V Vol. 3
261*301058f1Sschwarze.%P pp. 506\(en550
26242dcb487Sespie.%D 1973
26342dcb487Sespie.Re
26442dcb487Sespie.Sh STANDARDS
26542dcb487SespieThose functions are completely non-standard and should be avoided in
26642dcb487Sespieportable programs.
26742dcb487Sespie.Sh HISTORY
26842dcb487SespieThose functions were designed and written for
26942dcb487Sespie.Ox
27042dcb487Sespie.Xr make 1
27142dcb487Sespieby Marc Espie in 1999.
272