xref: /freebsd/lib/libopenbsd/ohash_init.3 (revision a36eca08bbd549807428439b536fea522de0dc37)
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