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