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