1*a36eca08SCraig Rodrigues.\" $OpenBSD: ohash_init.3,v 1.2 2014/05/13 14:01:41 jmc Exp $ 2*a36eca08SCraig Rodrigues.\" Copyright (c) 1999 Marc Espie <espie@openbsd.org> 3*a36eca08SCraig Rodrigues.\" 4*a36eca08SCraig Rodrigues.\" Permission to use, copy, modify, and distribute this software for any 5*a36eca08SCraig Rodrigues.\" purpose with or without fee is hereby granted, provided that the above 6*a36eca08SCraig Rodrigues.\" copyright notice and this permission notice appear in all copies. 7*a36eca08SCraig Rodrigues.\" 8*a36eca08SCraig Rodrigues.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9*a36eca08SCraig Rodrigues.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10*a36eca08SCraig Rodrigues.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11*a36eca08SCraig Rodrigues.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12*a36eca08SCraig Rodrigues.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13*a36eca08SCraig Rodrigues.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14*a36eca08SCraig Rodrigues.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15*a36eca08SCraig Rodrigues.\" 16*a36eca08SCraig Rodrigues.\" $FreeBSD$ 17*a36eca08SCraig Rodrigues.\" 18*a36eca08SCraig Rodrigues.Dd May 12, 2014 19*a36eca08SCraig Rodrigues.Dt OHASH_INIT 3 20*a36eca08SCraig Rodrigues.Os 21*a36eca08SCraig Rodrigues.Sh NAME 22*a36eca08SCraig Rodrigues.Nm ohash_init , 23*a36eca08SCraig Rodrigues.Nm ohash_delete , 24*a36eca08SCraig Rodrigues.Nm ohash_lookup_interval , 25*a36eca08SCraig Rodrigues.Nm ohash_lookup_memory , 26*a36eca08SCraig Rodrigues.Nm ohash_find , 27*a36eca08SCraig Rodrigues.Nm ohash_remove , 28*a36eca08SCraig Rodrigues.Nm ohash_insert , 29*a36eca08SCraig Rodrigues.Nm ohash_first , 30*a36eca08SCraig Rodrigues.Nm ohash_next , 31*a36eca08SCraig Rodrigues.Nm ohash_entries 32*a36eca08SCraig Rodrigues.Nd light-weight open hashing 33*a36eca08SCraig Rodrigues.Sh SYNOPSIS 34*a36eca08SCraig Rodrigues.In stdint.h 35*a36eca08SCraig Rodrigues.In stddef.h 36*a36eca08SCraig Rodrigues.In ohash.h 37*a36eca08SCraig Rodrigues.Ft void 38*a36eca08SCraig Rodrigues.Fn ohash_init "struct ohash *h" "unsigned int size" "struct ohash_info *info" 39*a36eca08SCraig Rodrigues.Ft void 40*a36eca08SCraig Rodrigues.Fn ohash_delete "struct ohash *h" 41*a36eca08SCraig Rodrigues.Ft "unsigned int" 42*a36eca08SCraig Rodrigues.Fn ohash_lookup_interval "struct ohash *h" "const char *start" "const char *end" "uint32_t hv" 43*a36eca08SCraig Rodrigues.Ft "unsigned int" 44*a36eca08SCraig Rodrigues.Fn ohash_lookup_memory "struct ohash *h" "const char *k" "size_t s" "uint32_t hv" 45*a36eca08SCraig Rodrigues.Ft void * 46*a36eca08SCraig Rodrigues.Fn ohash_find "struct ohash *h" "unsigned int i" 47*a36eca08SCraig Rodrigues.Ft void * 48*a36eca08SCraig Rodrigues.Fn ohash_remove "struct ohash *h" "unsigned int i" 49*a36eca08SCraig Rodrigues.Ft void * 50*a36eca08SCraig Rodrigues.Fn ohash_insert "struct ohash *h" "unsigned int i" "void *p" 51*a36eca08SCraig Rodrigues.Ft void * 52*a36eca08SCraig Rodrigues.Fn ohash_first "struct ohash *h" "unsigned int *i" 53*a36eca08SCraig Rodrigues.Ft void * 54*a36eca08SCraig Rodrigues.Fn ohash_next "struct ohash *h" "unsigned int *i" 55*a36eca08SCraig Rodrigues.Ft "unsigned int" 56*a36eca08SCraig Rodrigues.Fn ohash_entries "struct ohash *h" 57*a36eca08SCraig Rodrigues.Sh DESCRIPTION 58*a36eca08SCraig RodriguesThese functions have been designed as a fast, extensible alternative to 59*a36eca08SCraig Rodriguesthe usual hash table functions. 60*a36eca08SCraig RodriguesThey provide storage and retrieval of records indexed by keys, 61*a36eca08SCraig Rodrigueswhere a key is a contiguous sequence of bytes at a fixed position in 62*a36eca08SCraig Rodrigueseach record. 63*a36eca08SCraig RodriguesKeys can either be NUL-terminated strings or fixed-size memory areas. 64*a36eca08SCraig RodriguesAll functions take a pointer to an ohash structure as the 65*a36eca08SCraig Rodrigues.Fa h 66*a36eca08SCraig Rodriguesfunction argument. 67*a36eca08SCraig RodriguesStorage for this structure should be provided by user code. 68*a36eca08SCraig Rodrigues.Pp 69*a36eca08SCraig Rodrigues.Fn ohash_init 70*a36eca08SCraig Rodriguesinitializes the table to store roughly 2 to the power 71*a36eca08SCraig Rodrigues.Fa size 72*a36eca08SCraig Rodrigueselements. 73*a36eca08SCraig Rodrigues.Fa info 74*a36eca08SCraig Rodriguesis a pointer to a 75*a36eca08SCraig Rodrigues.Fa struct ohash_info . 76*a36eca08SCraig Rodrigues.Bd -literal -offset indent 77*a36eca08SCraig Rodriguesstruct ohash_info { 78*a36eca08SCraig Rodrigues ptrdiff_t key_offset; 79*a36eca08SCraig Rodrigues void *data; /* user data */ 80*a36eca08SCraig Rodrigues void *(*calloc)(size_t, size_t, void *); 81*a36eca08SCraig Rodrigues void (*free)(void *, void *); 82*a36eca08SCraig Rodrigues void *(*alloc)(size_t, void *); 83*a36eca08SCraig Rodrigues}; 84*a36eca08SCraig Rodrigues.Ed 85*a36eca08SCraig Rodrigues.Pp 86*a36eca08SCraig RodriguesThe 87*a36eca08SCraig Rodrigues.Va offset 88*a36eca08SCraig Rodriguesfield holds the position of the key in each record; 89*a36eca08SCraig Rodriguesthe 90*a36eca08SCraig Rodrigues.Va calloc 91*a36eca08SCraig Rodriguesand 92*a36eca08SCraig Rodrigues.Va free 93*a36eca08SCraig Rodriguesfields are pointers to 94*a36eca08SCraig Rodrigues.Xr calloc 3 95*a36eca08SCraig Rodriguesand 96*a36eca08SCraig Rodrigues.Xr free 3 Ns -like 97*a36eca08SCraig Rodriguesfunctions, used for managing the table internal storage; 98*a36eca08SCraig Rodriguesthe 99*a36eca08SCraig Rodrigues.Va alloc 100*a36eca08SCraig Rodriguesfield is only used by the utility function 101*a36eca08SCraig Rodrigues.Xr ohash_create_entry 3 . 102*a36eca08SCraig Rodrigues.Pp 103*a36eca08SCraig RodriguesEach of these functions are called similarly to their standard counterpart, 104*a36eca08SCraig Rodriguesbut with an extra 105*a36eca08SCraig Rodrigues.Ft void * 106*a36eca08SCraig Rodriguesparameter corresponding to the content of the field 107*a36eca08SCraig Rodrigues.Fa data , 108*a36eca08SCraig Rodrigueswhich can be used to communicate specific information to the functions. 109*a36eca08SCraig Rodrigues.Pp 110*a36eca08SCraig Rodrigues.Fn ohash_init 111*a36eca08SCraig Rodriguesstores a copy of those fields internally, so 112*a36eca08SCraig Rodrigues.Fa info 113*a36eca08SCraig Rodriguescan be reclaimed after initialization. 114*a36eca08SCraig Rodrigues.Pp 115*a36eca08SCraig Rodrigues.Fn ohash_delete 116*a36eca08SCraig Rodriguesfrees storage internal to 117*a36eca08SCraig Rodrigues.Fa h . 118*a36eca08SCraig RodriguesElements themselves should be freed by the user first, using for instance 119*a36eca08SCraig Rodrigues.Fn ohash_first 120*a36eca08SCraig Rodriguesand 121*a36eca08SCraig Rodrigues.Fn ohash_next . 122*a36eca08SCraig Rodrigues.Pp 123*a36eca08SCraig Rodrigues.Fn ohash_lookup_interval 124*a36eca08SCraig Rodriguesand 125*a36eca08SCraig Rodrigues.Fn ohash_lookup_memory 126*a36eca08SCraig Rodriguesare the basic look-up element functions. 127*a36eca08SCraig RodriguesThe hashing function result is provided by the user as 128*a36eca08SCraig Rodrigues.Fa hv . 129*a36eca08SCraig RodriguesThese return a 130*a36eca08SCraig Rodrigues.Qq slot 131*a36eca08SCraig Rodriguesin the ohash table 132*a36eca08SCraig Rodrigues.Fa h , 133*a36eca08SCraig Rodriguesto be used with 134*a36eca08SCraig Rodrigues.Fn ohash_find , 135*a36eca08SCraig Rodrigues.Fn ohash_insert , 136*a36eca08SCraig Rodriguesor 137*a36eca08SCraig Rodrigues.Fn ohash_remove . 138*a36eca08SCraig RodriguesThis slot is only valid up to the next call to 139*a36eca08SCraig Rodrigues.Fn ohash_insert 140*a36eca08SCraig Rodriguesor 141*a36eca08SCraig Rodrigues.Fn ohash_remove . 142*a36eca08SCraig Rodrigues.Pp 143*a36eca08SCraig Rodrigues.Fn ohash_lookup_interval 144*a36eca08SCraig Rodrigueshandles string-like keys. 145*a36eca08SCraig Rodrigues.Fn ohash_lookup_interval 146*a36eca08SCraig Rodriguesassumes the key is the interval between 147*a36eca08SCraig Rodrigues.Fa start 148*a36eca08SCraig Rodriguesand 149*a36eca08SCraig Rodrigues.Fa end , 150*a36eca08SCraig Rodriguesexclusive, 151*a36eca08SCraig Rodriguesthough the actual elements stored in the table should only contain 152*a36eca08SCraig RodriguesNUL-terminated keys. 153*a36eca08SCraig Rodrigues.Pp 154*a36eca08SCraig Rodrigues.Fn ohash_lookup_memory 155*a36eca08SCraig Rodriguesassumes the key is the memory area starting at 156*a36eca08SCraig Rodrigues.Fa k 157*a36eca08SCraig Rodriguesof size 158*a36eca08SCraig Rodrigues.Fa s . 159*a36eca08SCraig RodriguesAll bytes are significant in key comparison. 160*a36eca08SCraig Rodrigues.Pp 161*a36eca08SCraig Rodrigues.Fn ohash_find 162*a36eca08SCraig Rodriguesretrieves an element from a slot 163*a36eca08SCraig Rodrigues.Fa i 164*a36eca08SCraig Rodriguesreturned by the 165*a36eca08SCraig Rodrigues.Fn ohash_lookup* 166*a36eca08SCraig Rodriguesfunctions. 167*a36eca08SCraig RodriguesIt returns 168*a36eca08SCraig Rodrigues.Dv NULL 169*a36eca08SCraig Rodriguesif the slot is empty. 170*a36eca08SCraig Rodrigues.Pp 171*a36eca08SCraig Rodrigues.Fn ohash_insert 172*a36eca08SCraig Rodriguesinserts a new element 173*a36eca08SCraig Rodrigues.Fa p 174*a36eca08SCraig Rodriguesat slot 175*a36eca08SCraig Rodrigues.Fa i . 176*a36eca08SCraig RodriguesSlot 177*a36eca08SCraig Rodrigues.Fa i 178*a36eca08SCraig Rodriguesmust be empty and element 179*a36eca08SCraig Rodrigues.Fa p 180*a36eca08SCraig Rodriguesmust have a key corresponding to the 181*a36eca08SCraig Rodrigues.Fn ohash_lookup* 182*a36eca08SCraig Rodriguescall. 183*a36eca08SCraig Rodrigues.Pp 184*a36eca08SCraig Rodrigues.Fn ohash_remove 185*a36eca08SCraig Rodriguesremoves the element at slot 186*a36eca08SCraig Rodrigues.Fa i . 187*a36eca08SCraig RodriguesIt returns the removed element, for user code to dispose of, or 188*a36eca08SCraig Rodrigues.Dv NULL 189*a36eca08SCraig Rodriguesif the slot was empty. 190*a36eca08SCraig Rodrigues.Pp 191*a36eca08SCraig Rodrigues.Fn ohash_first 192*a36eca08SCraig Rodriguesand 193*a36eca08SCraig Rodrigues.Fn ohash_next 194*a36eca08SCraig Rodriguescan be used to access all elements in an ohash table, like this: 195*a36eca08SCraig Rodrigues.Bd -literal -offset indent 196*a36eca08SCraig Rodriguesfor (n = ohash_first(h, &i); n != NULL; n = ohash_next(h, &i)) 197*a36eca08SCraig Rodrigues do_something_with(n); 198*a36eca08SCraig Rodrigues.Ed 199*a36eca08SCraig Rodrigues.Pp 200*a36eca08SCraig Rodrigues.Fa i 201*a36eca08SCraig Rodriguespoints to an auxiliary unsigned integer used to record the current position 202*a36eca08SCraig Rodriguesin the ohash table. 203*a36eca08SCraig RodriguesThose functions are safe to use even while entries are added to/removed 204*a36eca08SCraig Rodriguesfrom the table, but in such a case they don't guarantee that new entries 205*a36eca08SCraig Rodrigueswill be returned. 206*a36eca08SCraig RodriguesAs a special case, they can safely be used to free elements in the table. 207*a36eca08SCraig Rodrigues.Pp 208*a36eca08SCraig Rodrigues.Fn ohash_entries 209*a36eca08SCraig Rodriguesreturns the number of elements in the hash table. 210*a36eca08SCraig Rodrigues.Sh STORAGE HANDLING 211*a36eca08SCraig RodriguesOnly 212*a36eca08SCraig Rodrigues.Fn ohash_init , 213*a36eca08SCraig Rodrigues.Fn ohash_insert , 214*a36eca08SCraig Rodrigues.Fn ohash_remove 215*a36eca08SCraig Rodriguesand 216*a36eca08SCraig Rodrigues.Fn ohash_delete 217*a36eca08SCraig Rodriguesmay call the user-supplied memory functions: 218*a36eca08SCraig Rodrigues.Bd -literal -offset indent 219*a36eca08SCraig Rodriguesp = (*info->calloc)(n, sizeof_record, info->data); 220*a36eca08SCraig Rodrigues/* copy data from old to p */ 221*a36eca08SCraig Rodrigues(*info->free)(old, info->data); 222*a36eca08SCraig Rodrigues.Ed 223*a36eca08SCraig Rodrigues.Pp 224*a36eca08SCraig RodriguesIt is the responsibility of the user memory allocation code to verify 225*a36eca08SCraig Rodriguesthat those calls did not fail. 226*a36eca08SCraig Rodrigues.Pp 227*a36eca08SCraig RodriguesIf memory allocation fails, 228*a36eca08SCraig Rodrigues.Fn ohash_init 229*a36eca08SCraig Rodriguesreturns a useless hash table. 230*a36eca08SCraig Rodrigues.Fn ohash_insert 231*a36eca08SCraig Rodriguesand 232*a36eca08SCraig Rodrigues.Fn ohash_remove 233*a36eca08SCraig Rodriguesstill perform the requested operation, but the returned table should be 234*a36eca08SCraig Rodriguesconsidered read-only. 235*a36eca08SCraig RodriguesIt can still be accessed by 236*a36eca08SCraig Rodrigues.Fn ohash_lookup* , 237*a36eca08SCraig Rodrigues.Fn ohash_find , 238*a36eca08SCraig Rodrigues.Fn ohash_first 239*a36eca08SCraig Rodriguesand 240*a36eca08SCraig Rodrigues.Fn ohash_next 241*a36eca08SCraig Rodriguesto dump relevant information to disk before aborting. 242*a36eca08SCraig Rodrigues.Sh THREAD SAFETY 243*a36eca08SCraig RodriguesThe open hashing functions are not thread-safe by design. 244*a36eca08SCraig RodriguesIn particular, in a threaded environment, there is no guarantee that a 245*a36eca08SCraig Rodrigues.Qq slot 246*a36eca08SCraig Rodrigueswill not move between a 247*a36eca08SCraig Rodrigues.Fn ohash_lookup* 248*a36eca08SCraig Rodriguesand a 249*a36eca08SCraig Rodrigues.Fn ohash_find , 250*a36eca08SCraig Rodrigues.Fn ohash_insert 251*a36eca08SCraig Rodriguesor 252*a36eca08SCraig Rodrigues.Fn ohash_remove 253*a36eca08SCraig Rodriguescall. 254*a36eca08SCraig Rodrigues.Pp 255*a36eca08SCraig RodriguesMulti-threaded applications should explicitly protect ohash table access. 256*a36eca08SCraig Rodrigues.Sh SEE ALSO 257*a36eca08SCraig Rodrigues.Xr hcreate 3 , 258*a36eca08SCraig Rodrigues.Xr ohash_interval 3 259*a36eca08SCraig Rodrigues.Rs 260*a36eca08SCraig Rodrigues.%A Donald E. Knuth 261*a36eca08SCraig Rodrigues.%B The Art of Computer Programming 262*a36eca08SCraig Rodrigues.%V Vol. 3 263*a36eca08SCraig Rodrigues.%P pp 506-550 264*a36eca08SCraig Rodrigues.%D 1973 265*a36eca08SCraig Rodrigues.Re 266*a36eca08SCraig Rodrigues.Sh STANDARDS 267*a36eca08SCraig RodriguesThose functions are completely non-standard and should be avoided in 268*a36eca08SCraig Rodriguesportable programs. 269*a36eca08SCraig Rodrigues.Sh HISTORY 270*a36eca08SCraig RodriguesThose functions were designed and written for 271*a36eca08SCraig Rodrigues.Ox 272*a36eca08SCraig Rodrigues.Xr make 1 273*a36eca08SCraig Rodriguesby Marc Espie in 1999. 274