]> git.proxmox.com Git - mirror_frr.git/blame - lib/hash.h
*: Rename backet to bucket
[mirror_frr.git] / lib / hash.h
CommitLineData
718e3744 1/* Hash routine.
896014f4
DL
2 * Copyright (C) 1998 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your
9 * option) any later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
718e3744 20
21#ifndef _ZEBRA_HASH_H
22#define _ZEBRA_HASH_H
23
4a1ab8e4 24#include "memory.h"
6f6f0010 25#include "frratomic.h"
4a1ab8e4 26
5e244469
RW
27#ifdef __cplusplus
28extern "C" {
29#endif
30
4a1ab8e4
DL
31DECLARE_MTYPE(HASH)
32DECLARE_MTYPE(HASH_BACKET)
33
d62a17ae 34/* Default hash table size. */
bed7ad83
QY
35#define HASH_INITIAL_SIZE 256
36/* Expansion threshold */
37#define HASH_THRESHOLD(used, size) ((used) > (size))
718e3744 38
3f9c7369
DS
39#define HASHWALK_CONTINUE 0
40#define HASHWALK_ABORT -1
41
e3b78da8 42struct hash_bucket {
6fd8c487 43 /*
e3b78da8 44 * if this bucket is the head of the linked listed, len denotes the
6fd8c487
QY
45 * number of elements in the list
46 */
d62a17ae 47 int len;
6f6f0010 48
d62a17ae 49 /* Linked list. */
e3b78da8 50 struct hash_bucket *next;
718e3744 51
d62a17ae 52 /* Hash key. */
53 unsigned int key;
718e3744 54
d62a17ae 55 /* Data. */
56 void *data;
718e3744 57};
58
d62a17ae 59struct hashstats {
60 /* number of empty hash buckets */
c8a65463 61 atomic_uint_fast32_t empty;
d62a17ae 62 /* sum of squares of bucket length */
c8a65463 63 atomic_uint_fast32_t ssq;
6f6f0010
QY
64};
65
d62a17ae 66struct hash {
e3b78da8
TB
67 /* Hash bucket. */
68 struct hash_bucket **index;
718e3744 69
d62a17ae 70 /* Hash table size. Must be power of 2 */
71 unsigned int size;
718e3744 72
40520c36
DW
73 /* If max_size is 0 there is no limit */
74 unsigned int max_size;
75
d62a17ae 76 /* Key make function. */
77 unsigned int (*hash_key)(void *);
718e3744 78
d62a17ae 79 /* Data compare function. */
74df8d6d 80 bool (*hash_cmp)(const void *, const void *);
718e3744 81
d62a17ae 82 /* Backet alloc. */
83 unsigned long count;
4db0cff1 84
d62a17ae 85 struct hashstats stats;
6f6f0010 86
d62a17ae 87 /* hash name */
88 char *name;
718e3744 89};
90
8234a987 91#define hashcount(X) ((X)->count)
92
6fd8c487
QY
93/*
94 * Create a hash table.
95 *
96 * The created hash table uses chaining and a user-provided comparator function
97 * to resolve collisions. For best performance use a perfect hash function.
98 * Worst case lookup time is O(N) when using a constant hash function. Best
99 * case lookup time is O(1) when using a perfect hash function.
100 *
101 * The initial size of the created hash table is HASH_INITIAL_SIZE.
102 *
103 * hash_key
104 * hash function to use; should return a unique unsigned integer when called
105 * with a data item. Collisions are acceptable.
106 *
107 * hash_cmp
108 * comparison function used for resolving collisions; when called with two
109 * data items, should return nonzero if the two items are equal and 0
110 * otherwise
111 *
112 * name
113 * optional name for the hashtable; this is used when displaying global
114 * hashtable statistics. If this parameter is NULL the hash's name will be
115 * set to NULL and the default name will be displayed when showing
116 * statistics.
117 *
118 * Returns:
119 * a new hash table
120 */
121extern struct hash *hash_create(unsigned int (*hash_key)(void *),
74df8d6d 122 bool (*hash_cmp)(const void *, const void *),
6fd8c487
QY
123 const char *name);
124
125/*
126 * Create a hash table.
127 *
128 * The created hash table uses chaining and a user-provided comparator function
129 * to resolve collisions. For best performance use a perfect hash function.
130 * Worst case lookup time is O(N) when using a constant hash function. Best
131 * case lookup time is O(1) when using a perfect hash function.
132 *
133 * size
134 * initial number of hash buckets to allocate; must be a power of 2 or the
135 * program will assert
136 *
137 * hash_key
138 * hash function to use; should return a unique unsigned integer when called
139 * with a data item. Collisions are acceptable.
140 *
141 * hash_cmp
142 * comparison function used for resolving collisions; when called with two
143 * data items, should return nonzero if the two items are equal and 0
144 * otherwise
145 *
146 * name
147 * optional name for the hashtable; this is used when displaying global
148 * hashtable statistics. If this parameter is NULL the hash's name will be
149 * set to NULL and the default name will be displayed when showing
150 * statistics.
151 *
152 * Returns:
153 * a new hash table
154 */
155extern struct hash *
156hash_create_size(unsigned int size, unsigned int (*hash_key)(void *),
74df8d6d
DS
157 bool (*hash_cmp)(const void *, const void *),
158 const char *name);
6fd8c487
QY
159
160/*
161 * Retrieve or insert data from / into a hash table.
162 *
163 * This function is somewhat counterintuitive in its usage. In order to look up
164 * an element from its key, you must provide the data item itself, with the
165 * portions used in the hash function set to the same values as the data item
166 * to retrieve. To insert a data element, either provide the key as just
167 * described and provide alloc_func as descrbied below to allocate the full
168 * data element, or provide the full data element and pass 'hash_alloc_intern'
169 * to alloc_func.
170 *
171 * hash
172 * hash table to operate on
173 *
174 * data
e3b78da8 175 * data to insert or retrieve - A hash bucket will not be created if
d3ce24ef 176 * the alloc_func returns a NULL pointer and nothing will be added to
e3b78da8 177 * the hash. As such bucket->data will always be non-NULL.
6fd8c487
QY
178 *
179 * alloc_func
180 * function to call if the item is not found in the hash table. This
181 * function is called with the value of 'data' and should create the data
182 * item to insert and return a pointer to it. If the data has already been
183 * completely created and provided in the 'data' parameter, passing
184 * 'hash_alloc_intern' to this parameter will cause 'data' to be inserted.
185 * If this parameter is NULL, then this call to hash_get is equivalent to
186 * hash_lookup.
187 *
188 * Returns:
189 * the data item found or inserted, or NULL if alloc_func is NULL and the
190 * data is not found
191 */
192extern void *hash_get(struct hash *hash, void *data,
193 void *(*alloc_func)(void *));
194
195/*
196 * Dummy element allocation function.
197 *
198 * See hash_get for details.
199 *
200 * data
201 * data to insert into the hash table
202 *
203 * Returns:
204 * data
205 */
206extern void *hash_alloc_intern(void *data);
207
208/*
209 * Retrieve an item from a hash table.
210 *
211 * This function is equivalent to calling hash_get with alloc_func set to NULL.
212 *
213 * hash
214 * hash table to operate on
215 *
216 * data
217 * data element with values used for key computation set
218 *
219 * Returns:
220 * the data element if found, or NULL if not found
221 */
222extern void *hash_lookup(struct hash *hash, void *data);
718e3744 223
6fd8c487
QY
224/*
225 * Remove an element from a hash table.
226 *
227 * hash
228 * hash table to operate on
229 *
230 * data
231 * data element to remove with values used for key computation set
232 *
233 * Returns:
234 * the removed element if found, or NULL if not found
235 */
236extern void *hash_release(struct hash *hash, void *data);
718e3744 237
6fd8c487
QY
238/*
239 * Iterate over the elements in a hash table.
240 *
241 * It is safe to delete items passed to the iteration function from the hash
8b52179d
DS
242 * table during iteration. Please note that adding entries to the hash
243 * during the walk will cause undefined behavior in that some new entries
244 * will be walked and some will not. So do not do this.
6fd8c487 245 *
e3b78da8 246 * The bucket passed to func will have a non-NULL data pointer.
d3ce24ef 247 *
6fd8c487
QY
248 * hash
249 * hash table to operate on
250 *
251 * func
252 * function to call with each data item
253 *
254 * arg
255 * arbitrary argument passed as the second parameter in each call to 'func'
256 */
257extern void hash_iterate(struct hash *hash,
e3b78da8 258 void (*func)(struct hash_bucket *, void *), void *arg);
718e3744 259
6fd8c487
QY
260/*
261 * Iterate over the elements in a hash table, stopping on condition.
262 *
263 * It is safe to delete items passed to the iteration function from the hash
8b52179d
DS
264 * table during iteration. Please note that adding entries to the hash
265 * during the walk will cause undefined behavior in that some new entries
266 * will be walked and some will not. So do not do this.
6fd8c487 267 *
e3b78da8 268 * The bucket passed to func will have a non-NULL data pointer.
d3ce24ef 269 *
6fd8c487
QY
270 * hash
271 * hash table to operate on
272 *
273 * func
274 * function to call with each data item. If this function returns
275 * HASHWALK_ABORT then the iteration stops.
276 *
277 * arg
278 * arbitrary argument passed as the second parameter in each call to 'func'
279 */
280extern void hash_walk(struct hash *hash,
e3b78da8 281 int (*func)(struct hash_bucket *, void *), void *arg);
3f9c7369 282
6fd8c487
QY
283/*
284 * Remove all elements from a hash table.
285 *
286 * hash
287 * hash table to operate on
288 *
289 * free_func
290 * function to call with each removed item; intended to free the data
291 */
292extern void hash_clean(struct hash *hash, void (*free_func)(void *));
293
294/*
295 * Delete a hash table.
296 *
297 * This function assumes the table is empty. Call hash_clean to delete the
298 * hashtable contents if necessary.
299 *
300 * hash
301 * hash table to delete
302 */
303extern void hash_free(struct hash *hash);
718e3744 304
91f10370
QY
305/*
306 * Converts a hash table to an unsorted linked list.
307 * Does not modify the hash table in any way.
308 *
309 * hash
6fd8c487 310 * hash table to convert
91f10370
QY
311 */
312extern struct list *hash_to_list(struct hash *hash);
313
6fd8c487
QY
314/*
315 * Hash a string using the modified Bernstein hash.
316 *
317 * This is not a perfect hash function.
318 *
319 * str
320 * string to hash
321 *
322 * Returns:
323 * modified Bernstein hash of the string
324 */
d62a17ae 325extern unsigned int string_hash_make(const char *);
6392aa83 326
6fd8c487
QY
327/*
328 * Install CLI commands for viewing global hash table statistics.
329 */
d62a17ae 330extern void hash_cmd_init(void);
4db0cff1 331
5e244469
RW
332#ifdef __cplusplus
333}
334#endif
335
718e3744 336#endif /* _ZEBRA_HASH_H */