blob: e4a65d21e65b00b93ee7c1f75a7585ef3dd65cd1 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2001-2005 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
37
38#ifndef included_hash_h
39#define included_hash_h
40
41#include <vppinfra/error.h>
42#include <vppinfra/format.h>
43#include <vppinfra/vec.h>
44#include <vppinfra/vector.h>
45
46struct hash_header;
47
Dave Barachc3799992016-08-15 11:12:27 -040048typedef uword (hash_key_sum_function_t) (struct hash_header *, uword key);
Ed Warnickecb9cada2015-12-08 15:45:58 -070049typedef uword (hash_key_equal_function_t)
50 (struct hash_header *, uword key1, uword key2);
51
52/* Vector header for hash tables. */
Dave Barachc3799992016-08-15 11:12:27 -040053typedef struct hash_header
54{
Ed Warnickecb9cada2015-12-08 15:45:58 -070055 /* Number of elements in hash table. */
56 uword elts;
57
58 /* Flags as follows. */
59 u32 flags;
60
61 /* Set if user does not want table to auto-resize when sufficiently full. */
62#define HASH_FLAG_NO_AUTO_GROW (1 << 0)
63 /* Set if user does not want table to auto-resize when sufficiently empty. */
64#define HASH_FLAG_NO_AUTO_SHRINK (1 << 1)
65 /* Set when hash_next is in the process of iterating through this hash table. */
66#define HASH_FLAG_HASH_NEXT_IN_PROGRESS (1 << 2)
67
68 u32 log2_pair_size;
69
70 /* Function to compute the "sum" of a hash key.
71 Hash function is this sum modulo the prime size of
72 the hash table (vec_len (v)). */
Dave Barachc3799992016-08-15 11:12:27 -040073 hash_key_sum_function_t *key_sum;
Ed Warnickecb9cada2015-12-08 15:45:58 -070074
75 /* Special values for key_sum "function". */
Dave Barachc3799992016-08-15 11:12:27 -040076#define KEY_FUNC_NONE (0) /*< sum = key */
77#define KEY_FUNC_POINTER_UWORD (1) /*< sum = *(uword *) key */
78#define KEY_FUNC_POINTER_U32 (2) /*< sum = *(u32 *) key */
79#define KEY_FUNC_STRING (3) /*< sum = string_key_sum, etc. */
Ole Troan73710c72018-06-04 22:27:49 +020080#define KEY_FUNC_MEM (4) /*< sum = mem_key_sum */
Ed Warnickecb9cada2015-12-08 15:45:58 -070081
82 /* key comparison function */
Dave Barachc3799992016-08-15 11:12:27 -040083 hash_key_equal_function_t *key_equal;
Ed Warnickecb9cada2015-12-08 15:45:58 -070084
85 /* Hook for user's data. Used to parameterize sum/equal functions. */
86 any user;
87
88 /* Format a (k,v) pair */
Dave Barachc3799992016-08-15 11:12:27 -040089 format_function_t *format_pair;
Ed Warnickecb9cada2015-12-08 15:45:58 -070090
91 /* Format function arg */
Dave Barachc3799992016-08-15 11:12:27 -040092 void *format_pair_arg;
Ed Warnickecb9cada2015-12-08 15:45:58 -070093
94 /* Bit i is set if pair i is a user object (as opposed to being
95 either zero or an indirect array of pairs). */
96 uword is_user[0];
97} hash_t;
98
99/* Hash header size in bytes */
Dave Barachc3799992016-08-15 11:12:27 -0400100always_inline uword
101hash_header_bytes (void *v)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102{
Dave Barachc3799992016-08-15 11:12:27 -0400103 hash_t *h;
104 uword is_user_bytes =
105 (sizeof (h->is_user[0]) * vec_len (v)) / BITS (h->is_user[0]);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700106 return sizeof (h[0]) + is_user_bytes;
107}
108
109/* Returns a pointer to the hash header given the vector pointer */
Dave Barachc3799992016-08-15 11:12:27 -0400110always_inline hash_t *
111hash_header (void *v)
112{
113 return vec_header (v, hash_header_bytes (v));
114}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700115
116/* Number of elements in the hash table */
Dave Barachc3799992016-08-15 11:12:27 -0400117always_inline uword
118hash_elts (void *v)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119{
Dave Barachc3799992016-08-15 11:12:27 -0400120 hash_t *h = hash_header (v);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700121 return v ? h->elts : 0;
122}
123
124/* Number of elements the hash table can hold */
Dave Barachc3799992016-08-15 11:12:27 -0400125always_inline uword
126hash_capacity (void *v)
127{
128 return vec_len (v);
129}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700130
131/* Returns 1 if the hash pair contains user data */
Dave Barachc3799992016-08-15 11:12:27 -0400132always_inline uword
133hash_is_user (void *v, uword i)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700134{
Dave Barachc3799992016-08-15 11:12:27 -0400135 hash_t *h = hash_header (v);
136 uword i0 = i / BITS (h->is_user[0]);
137 uword i1 = i % BITS (h->is_user[0]);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700138 return (h->is_user[i0] & ((uword) 1 << i1)) != 0;
139}
140
141/* Set the format function and format argument for a hash table */
142always_inline void
Dave Barachc3799992016-08-15 11:12:27 -0400143hash_set_pair_format (void *v,
144 format_function_t * format_pair, void *format_pair_arg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700145{
Dave Barachc3799992016-08-15 11:12:27 -0400146 hash_t *h = hash_header (v);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700147 h->format_pair = format_pair;
148 h->format_pair_arg = format_pair_arg;
149}
150
151/* Set hash table flags */
Dave Barachc3799992016-08-15 11:12:27 -0400152always_inline void
153hash_set_flags (void *v, uword flags)
154{
155 hash_header (v)->flags |= flags;
156}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157
158/* Key value pairs. */
Dave Barachc3799992016-08-15 11:12:27 -0400159typedef struct
160{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700161 /* The Key */
162 uword key;
163
164 /* The Value. Length is 2^log2_pair_size - 1. */
165 uword value[0];
166} hash_pair_t;
167
168/* The indirect pair structure
169
170 If log2_pair_size > 0 we overload hash pairs
171 with indirect pairs for buckets with more than one
172 pair. */
Dave Barachc3799992016-08-15 11:12:27 -0400173typedef struct
174{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700175 /* pair vector */
Dave Barachc3799992016-08-15 11:12:27 -0400176 hash_pair_t *pairs;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700177 /* padding */
Dave Barachc3799992016-08-15 11:12:27 -0400178 u8 pad[sizeof (uword) - sizeof (hash_pair_t *)];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179 /* allocated length */
180 uword alloc_len;
Dave Barachc3799992016-08-15 11:12:27 -0400181}
182hash_pair_indirect_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700183
184/* Direct / Indirect pair union */
Dave Barachc3799992016-08-15 11:12:27 -0400185typedef union
186{
187 hash_pair_t direct;
188 hash_pair_indirect_t indirect;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700189} hash_pair_union_t;
190
191#define LOG2_ALLOC_BITS (5)
192#define PAIR_BITS (BITS (uword) - LOG2_ALLOC_BITS)
193
194/* Log2 number of bytes allocated in pairs array. */
Dave Barachc3799992016-08-15 11:12:27 -0400195always_inline uword
196indirect_pair_get_log2_bytes (hash_pair_indirect_t * p)
197{
198 return p->alloc_len >> PAIR_BITS;
199}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700200
201/* Get the length of an indirect pair */
202always_inline uword
203indirect_pair_get_len (hash_pair_indirect_t * p)
204{
Dave Barachc3799992016-08-15 11:12:27 -0400205 if (!p->pairs)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700206 return 0;
207 else
208 return p->alloc_len & (((uword) 1 << PAIR_BITS) - 1);
209}
210
211/* Set the length of an indirect pair */
212always_inline void
Dave Barachc3799992016-08-15 11:12:27 -0400213indirect_pair_set (hash_pair_indirect_t * p, uword log2_alloc, uword len)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214{
215 ASSERT (len < ((uword) 1 << PAIR_BITS));
216 ASSERT (log2_alloc < ((uword) 1 << LOG2_ALLOC_BITS));
217 p->alloc_len = (log2_alloc << PAIR_BITS) | len;
218}
219
220/* internal routine to fetch value for given key */
Dave Barachc3799992016-08-15 11:12:27 -0400221uword *_hash_get (void *v, uword key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700222
223/* internal routine to fetch value (key, value) pair for given key */
Dave Barachc3799992016-08-15 11:12:27 -0400224hash_pair_t *_hash_get_pair (void *v, uword key);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700225
226/* internal routine to unset a (key, value) pair */
Dave Barachc3799992016-08-15 11:12:27 -0400227void *_hash_unset (void *v, uword key, void *old_value);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700228
229/* internal routine to set a (key, value) pair, return the old value */
Dave Barachc3799992016-08-15 11:12:27 -0400230void *_hash_set3 (void *v, uword key, void *value, void *old_value);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700231
232/* Resize a hash table */
Dave Barachc3799992016-08-15 11:12:27 -0400233void *hash_resize (void *old, uword new_size);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700234
235/* duplicate a hash table */
Dave Barachc3799992016-08-15 11:12:27 -0400236void *hash_dup (void *old);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700237
238/* Returns the number of bytes used by a hash table */
Dave Barachc3799992016-08-15 11:12:27 -0400239uword hash_bytes (void *v);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700240
241/* Public macro to set a (key, value) pair, return the old value */
242#define hash_set3(h,key,value,old_value) \
243({ \
244 uword _v = (uword) (value); \
245 (h) = _hash_set3 ((h), (uword) (key), (void *) &_v, (old_value)); \
246})
247
248/* Public macro to fetch value for given key */
249#define hash_get(h,key) _hash_get ((h), (uword) (key))
250
251/* Public macro to fetch value (key, value) pair for given key */
252#define hash_get_pair(h,key) _hash_get_pair ((h), (uword) (key))
253
254/* Public macro to set a (key, value) pair */
255#define hash_set(h,key,value) hash_set3(h,key,value,0)
256
257/* Public macro to set (key, 0) pair */
258#define hash_set1(h,key) (h) = _hash_set3(h,(uword) (key),0,0)
259
260/* Public macro to unset a (key, value) pair */
261#define hash_unset(h,key) ((h) = _hash_unset ((h), (uword) (key),0))
262
263/* Public macro to unset a (key, value) pair, return the old value */
264#define hash_unset3(h,key,old_value) ((h) = _hash_unset ((h), (uword) (key), (void *) (old_value)))
265
266/* get/set/unset for pointer keys. */
267
268/* Public macro to fetch value for given pointer key */
269#define hash_get_mem(h,key) _hash_get ((h), pointer_to_uword (key))
270
271/* Public macro to fetch (key, value) for given pointer key */
272#define hash_get_pair_mem(h,key) _hash_get_pair ((h), pointer_to_uword (key))
273
274/* Public macro to set (key, value) for pointer key */
275#define hash_set_mem(h,key,value) hash_set3 (h, pointer_to_uword (key), (value), 0)
276
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700277/* Public inline function allocate and copy key to use in hash for pointer key */
John Loe6bfeab2018-01-04 16:39:42 -0500278always_inline void
Neale Rannsc190cf02020-01-06 21:09:12 +0000279hash_set_mem_alloc (uword ** h, const void *key, uword v)
John Loe6bfeab2018-01-04 16:39:42 -0500280{
281 size_t ksz = hash_header (*h)->user;
282 void *copy = clib_mem_alloc (ksz);
Dave Barach178cf492018-11-13 16:34:13 -0500283 clib_memcpy_fast (copy, key, ksz);
John Loe6bfeab2018-01-04 16:39:42 -0500284 hash_set_mem (*h, copy, v);
285}
286
Ed Warnickecb9cada2015-12-08 15:45:58 -0700287/* Public macro to set (key, 0) for pointer key */
288#define hash_set1_mem(h,key) hash_set3 ((h), pointer_to_uword (key), 0, 0)
289
290/* Public macro to unset (key, value) for pointer key */
291#define hash_unset_mem(h,key) ((h) = _hash_unset ((h), pointer_to_uword (key),0))
292
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700293/* Public inline function to unset pointer key and then free the key memory */
John Loe6bfeab2018-01-04 16:39:42 -0500294always_inline void
Neale Rannsc190cf02020-01-06 21:09:12 +0000295hash_unset_mem_free (uword ** h, const void *key)
John Loe6bfeab2018-01-04 16:39:42 -0500296{
297 hash_pair_t *hp = hash_get_pair_mem (*h, key);
John Lo5957a142018-01-18 12:44:50 -0500298 if (PREDICT_TRUE (hp != NULL))
299 {
Neale Rannsc190cf02020-01-06 21:09:12 +0000300 void *_k = uword_to_pointer (hp->key, void *);
301 hash_unset_mem (*h, _k);
302 clib_mem_free (_k);
John Lo5957a142018-01-18 12:44:50 -0500303 }
John Loe6bfeab2018-01-04 16:39:42 -0500304}
305
Ed Warnickecb9cada2015-12-08 15:45:58 -0700306/* internal routine to free a hash table */
Dave Barachc3799992016-08-15 11:12:27 -0400307extern void *_hash_free (void *v);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700308
309/* Public macro to free a hash table */
310#define hash_free(h) (h) = _hash_free ((h))
311
Dave Barachc3799992016-08-15 11:12:27 -0400312clib_error_t *hash_validate (void *v);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700313
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700314/* Public inline function to get the number of value bytes for a hash table */
Dave Barachc3799992016-08-15 11:12:27 -0400315always_inline uword
316hash_value_bytes (hash_t * h)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700317{
Dave Barachc3799992016-08-15 11:12:27 -0400318 hash_pair_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700319 return (sizeof (p->value[0]) << h->log2_pair_size) - sizeof (p->key);
320}
321
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700322/* Public inline function to get log2(size of a (key,value) pair) */
Dave Barachc3799992016-08-15 11:12:27 -0400323always_inline uword
324hash_pair_log2_bytes (hash_t * h)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700325{
326 uword log2_bytes = h->log2_pair_size;
Dave Barachc3799992016-08-15 11:12:27 -0400327 ASSERT (BITS (hash_pair_t) == 32 || BITS (hash_pair_t) == 64);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700328 if (BITS (hash_pair_t) == 32)
329 log2_bytes += 2;
330 else if (BITS (hash_pair_t) == 64)
331 log2_bytes += 3;
332 return log2_bytes;
333}
334
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700335/* Public inline function to get size of a (key,value) pair */
Dave Barachc3799992016-08-15 11:12:27 -0400336always_inline uword
337hash_pair_bytes (hash_t * h)
338{
339 return (uword) 1 << hash_pair_log2_bytes (h);
340}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700341
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700342/* Public inline function to advance a pointer past one (key,value) pair */
Dave Barachc3799992016-08-15 11:12:27 -0400343always_inline void *
344hash_forward1 (hash_t * h, void *v)
345{
346 return (u8 *) v + hash_pair_bytes (h);
347}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700348
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700349/* Public inline function to advance a pointer past N (key,value) pairs */
Dave Barachc3799992016-08-15 11:12:27 -0400350always_inline void *
351hash_forward (hash_t * h, void *v, uword n)
352{
353 return (u8 *) v + ((n * sizeof (hash_pair_t)) << h->log2_pair_size);
354}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700355
Chris Luke5cdaf632016-07-30 15:05:07 -0400356/** Iterate over hash pairs.
357
358 @param p The current (key,value) pair. This should be of type
359 <code>(hash_pair_t *)</code>.
360 @param v The hash table to iterate.
361 @param body The operation to perform on each (key,value) pair.
362
363 Executes the expression or code block @c body with each active hash pair.
Ed Warnickecb9cada2015-12-08 15:45:58 -0700364*/
Chris Luke5cdaf632016-07-30 15:05:07 -0400365/* A previous version of this macro made use of the hash_pair_union_t
366 * structure; this version does not since that approach mightily upset
367 * the static analysis tool. In the rare chance someone is reading this
368 * code, pretend that _p below is of type hash_pair_union_t and that when
369 * used as an rvalue it's really using one of the union members as the
370 * rvalue. If you were confused before you might be marginally less
371 * confused after.
372 */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700373#define hash_foreach_pair(p,v,body) \
374do { \
375 __label__ _hash_foreach_done; \
376 hash_t * _h = hash_header (v); \
Chris Luke5cdaf632016-07-30 15:05:07 -0400377 void * _p; \
Ed Warnickecb9cada2015-12-08 15:45:58 -0700378 hash_pair_t * _q, * _q_end; \
379 uword _i, _i1, _id, _pair_increment; \
380 \
Chris Luke5cdaf632016-07-30 15:05:07 -0400381 _p = (v); \
Ed Warnickecb9cada2015-12-08 15:45:58 -0700382 _i = 0; \
383 _pair_increment = 1; \
384 if ((v)) \
385 _pair_increment = 1 << _h->log2_pair_size; \
386 while (_i < hash_capacity (v)) \
387 { \
388 _id = _h->is_user[_i / BITS (_h->is_user[0])]; \
389 _i1 = _i + BITS (_h->is_user[0]); \
390 \
391 do { \
392 if (_id & 1) \
393 { \
Chris Luke5cdaf632016-07-30 15:05:07 -0400394 _q = _p; \
Ed Warnickecb9cada2015-12-08 15:45:58 -0700395 _q_end = _q + _pair_increment; \
396 } \
397 else \
398 { \
Chris Luke5cdaf632016-07-30 15:05:07 -0400399 hash_pair_indirect_t * _pi = _p; \
Ed Warnickecb9cada2015-12-08 15:45:58 -0700400 _q = _pi->pairs; \
401 if (_h->log2_pair_size > 0) \
402 _q_end = hash_forward (_h, _q, indirect_pair_get_len (_pi)); \
403 else \
404 _q_end = vec_end (_q); \
405 } \
406 \
407 /* Loop through all elements in bucket. \
408 Bucket may have 0 1 or more (indirect case) pairs. */ \
409 while (_q < _q_end) \
410 { \
411 uword _break_in_body = 1; \
412 (p) = _q; \
413 do { \
414 body; \
415 _break_in_body = 0; \
416 } while (0); \
417 if (_break_in_body) \
418 goto _hash_foreach_done; \
419 _q += _pair_increment; \
420 } \
421 \
Chris Luke5cdaf632016-07-30 15:05:07 -0400422 _p = (hash_pair_t *)_p + _pair_increment; \
Ed Warnickecb9cada2015-12-08 15:45:58 -0700423 _id = _id / 2; \
424 _i++; \
425 } while (_i < _i1); \
426 } \
427 _hash_foreach_done: \
428 /* Be silent Mr. Compiler-Warning. */ \
429 ; \
430 } while (0)
431
432/* Iterate over key/value pairs
433
434 @param key_var the current key
435 @param value_var the current value
436 @param h the hash table to iterate across
Dave Barachc3799992016-08-15 11:12:27 -0400437 @param body the operation to perform on each (key_var,value_var) pair.
Ed Warnickecb9cada2015-12-08 15:45:58 -0700438
439 calls body with each active hash pair
440*/
Paul Vinciguerraec11b132018-09-24 05:25:00 -0700441/* Iterate over key/value pairs. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700442#define hash_foreach(key_var,value_var,h,body) \
443do { \
444 hash_pair_t * _r; \
445 hash_foreach_pair (_r, (h), { \
446 (key_var) = (__typeof__ (key_var)) _r->key; \
447 (value_var) = (__typeof__ (value_var)) _r->value[0]; \
448 do { body; } while (0); \
449 }); \
450} while (0)
451
452/* Iterate over key/value pairs for pointer key hash tables
453
454 @param key_var the current key
455 @param value_var the current value
456 @param h the hash table to iterate across
Dave Barachc3799992016-08-15 11:12:27 -0400457 @param body the operation to perform on each (key_var,value_var) pair.
Ed Warnickecb9cada2015-12-08 15:45:58 -0700458
459 calls body with each active hash pair
460*/
461#define hash_foreach_mem(key_var,value_var,h,body) \
462do { \
463 hash_pair_t * _r; \
464 hash_foreach_pair (_r, (h), { \
465 (key_var) = (__typeof__ (key_var)) uword_to_pointer (_r->key, void *); \
466 (value_var) = (__typeof__ (value_var)) _r->value[0]; \
467 do { body; } while (0); \
468 }); \
469} while (0)
470
471/* Support for iteration through hash table. */
472
473/* This struct saves iteration state for hash_next.
474 None of these fields are meant to be visible to the user.
475 Hence, the cryptic short-hand names. */
Dave Barachc3799992016-08-15 11:12:27 -0400476typedef struct
477{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700478 uword i, j, f;
479} hash_next_t;
480
Dave Barachc3799992016-08-15 11:12:27 -0400481hash_pair_t *hash_next (void *v, hash_next_t * hn);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700482
Dave Barachc3799992016-08-15 11:12:27 -0400483void *_hash_create (uword elts, hash_t * h);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700484
Dave Barachc3799992016-08-15 11:12:27 -0400485always_inline void
486hash_set_value_bytes (hash_t * h, uword value_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700487{
Dave Barachc3799992016-08-15 11:12:27 -0400488 hash_pair_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700489 h->log2_pair_size =
Dave Barachc3799992016-08-15 11:12:27 -0400490 max_log2 ((sizeof (p->key) + value_bytes + sizeof (p->key) -
491 1) / sizeof (p->key));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700492}
493
494#define hash_create2(_elts,_user,_value_bytes, \
495 _key_sum,_key_equal, \
496 _format_pair,_format_pair_arg) \
497({ \
498 hash_t _h; \
Dave Barachb7b92992018-10-17 10:38:51 -0400499 clib_memset (&_h, 0, sizeof (_h)); \
Ed Warnickecb9cada2015-12-08 15:45:58 -0700500 _h.user = (_user); \
501 _h.key_sum = (hash_key_sum_function_t *) (_key_sum); \
502 _h.key_equal = (_key_equal); \
503 hash_set_value_bytes (&_h, (_value_bytes)); \
504 _h.format_pair = (format_function_t *) (_format_pair); \
505 _h.format_pair_arg = (_format_pair_arg); \
506 _hash_create ((_elts), &_h); \
507})
508
509/* Hash function based on that of Bob Jenkins (bob_jenkins@compuserve.com).
510 Public domain per: http://www.burtleburtle.net/bob/hash/doobs.html
511 Thanks, Bob. */
512
513#define hash_mix_step(a,b,c,s0,s1,s2) \
514do { \
515 (a) -= (b) + (c); (a) ^= (c) >> (s0); \
516 (b) -= (c) + (a); (b) ^= (a) << (s1); \
517 (c) -= (a) + (b); (c) ^= (b) >> (s2); \
518} while (0)
519
520#define hash_mix32_step_1(a,b,c) hash_mix_step(a,b,c,13,8,13)
521#define hash_mix32_step_2(a,b,c) hash_mix_step(a,b,c,12,16,5)
522#define hash_mix32_step_3(a,b,c) hash_mix_step(a,b,c,3,10,15)
523
524#define hash_mix64_step_1(a,b,c) hash_mix_step(a,b,c,43,9,8)
525#define hash_mix64_step_2(a,b,c) hash_mix_step(a,b,c,38,23,5)
526#define hash_mix64_step_3(a,b,c) hash_mix_step(a,b,c,35,49,11)
527#define hash_mix64_step_4(a,b,c) hash_mix_step(a,b,c,12,18,22)
528
529/* Hash function based on that of Bob Jenkins (bob_jenkins@compuserve.com).
530 Thanks, Bob. */
531#define hash_mix64(a0,b0,c0) \
532do { \
533 hash_mix64_step_1 (a0, b0, c0); \
534 hash_mix64_step_2 (a0, b0, c0); \
535 hash_mix64_step_3 (a0, b0, c0); \
536 hash_mix64_step_4 (a0, b0, c0); \
537} while (0) \
538
539#define hash_mix32(a0,b0,c0) \
540do { \
541 hash_mix32_step_1 (a0, b0, c0); \
542 hash_mix32_step_2 (a0, b0, c0); \
543 hash_mix32_step_3 (a0, b0, c0); \
544} while (0) \
545
546/* Finalize from Bob Jenkins lookup3.c */
547
548always_inline uword
549hash32_rotate_left (u32 x, u32 i)
Dave Barachc3799992016-08-15 11:12:27 -0400550{
551 return (x << i) | (x >> (BITS (i) - i));
552}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700553
554#define hash_v3_mix32(a,b,c) \
555do { \
556 (a) -= (c); (a) ^= hash32_rotate_left ((c), 4); (c) += (b); \
557 (b) -= (a); (b) ^= hash32_rotate_left ((a), 6); (a) += (c); \
558 (c) -= (b); (c) ^= hash32_rotate_left ((b), 8); (b) += (a); \
559 (a) -= (c); (a) ^= hash32_rotate_left ((c),16); (c) += (b); \
560 (b) -= (a); (b) ^= hash32_rotate_left ((a),19); (a) += (c); \
561 (c) -= (b); (c) ^= hash32_rotate_left ((b), 4); (b) += (a); \
562} while (0)
563
564#define hash_v3_finalize32(a,b,c) \
565do { \
566 (c) ^= (b); (c) -= hash32_rotate_left ((b), 14); \
567 (a) ^= (c); (a) -= hash32_rotate_left ((c), 11); \
568 (b) ^= (a); (b) -= hash32_rotate_left ((a), 25); \
569 (c) ^= (b); (c) -= hash32_rotate_left ((b), 16); \
570 (a) ^= (c); (a) -= hash32_rotate_left ((c), 4); \
571 (b) ^= (a); (b) -= hash32_rotate_left ((a), 14); \
572 (c) ^= (b); (c) -= hash32_rotate_left ((b), 24); \
573} while (0)
574
575/* 32 bit mixing/finalize in steps. */
576
577#define hash_v3_mix32_step1(a,b,c) \
578do { \
579 (a) -= (c); (a) ^= hash32_rotate_left ((c), 4); (c) += (b); \
580 (b) -= (a); (b) ^= hash32_rotate_left ((a), 6); (a) += (c); \
581} while (0)
582
583#define hash_v3_mix32_step2(a,b,c) \
584do { \
585 (c) -= (b); (c) ^= hash32_rotate_left ((b), 8); (b) += (a); \
586 (a) -= (c); (a) ^= hash32_rotate_left ((c),16); (c) += (b); \
587} while (0)
588
589#define hash_v3_mix32_step3(a,b,c) \
590do { \
591 (b) -= (a); (b) ^= hash32_rotate_left ((a),19); (a) += (c); \
592 (c) -= (b); (c) ^= hash32_rotate_left ((b), 4); (b) += (a); \
593} while (0)
594
595#define hash_v3_finalize32_step1(a,b,c) \
596do { \
597 (c) ^= (b); (c) -= hash32_rotate_left ((b), 14); \
598 (a) ^= (c); (a) -= hash32_rotate_left ((c), 11); \
599} while (0)
600
601#define hash_v3_finalize32_step2(a,b,c) \
602do { \
603 (b) ^= (a); (b) -= hash32_rotate_left ((a), 25); \
604 (c) ^= (b); (c) -= hash32_rotate_left ((b), 16); \
605} while (0)
606
607#define hash_v3_finalize32_step3(a,b,c) \
608do { \
609 (a) ^= (c); (a) -= hash32_rotate_left ((c), 4); \
610 (b) ^= (a); (b) -= hash32_rotate_left ((a), 14); \
611 (c) ^= (b); (c) -= hash32_rotate_left ((b), 24); \
612} while (0)
613
614/* Vector v3 mixing/finalize. */
615#define hash_v3_mix_step_1_u32x(a,b,c) \
616do { \
617 (a) -= (c); (a) ^= u32x_irotate_left ((c), 4); (c) += (b); \
618 (b) -= (a); (b) ^= u32x_irotate_left ((a), 6); (a) += (c); \
619 (c) -= (b); (c) ^= u32x_irotate_left ((b), 8); (b) += (a); \
620} while (0)
621
622#define hash_v3_mix_step_2_u32x(a,b,c) \
623do { \
624 (a) -= (c); (a) ^= u32x_irotate_left ((c),16); (c) += (b); \
625 (b) -= (a); (b) ^= u32x_irotate_left ((a),19); (a) += (c); \
626 (c) -= (b); (c) ^= u32x_irotate_left ((b), 4); (b) += (a); \
627} while (0)
628
629#define hash_v3_finalize_step_1_u32x(a,b,c) \
630do { \
631 (c) ^= (b); (c) -= u32x_irotate_left ((b), 14); \
632 (a) ^= (c); (a) -= u32x_irotate_left ((c), 11); \
633 (b) ^= (a); (b) -= u32x_irotate_left ((a), 25); \
634} while (0)
635
636#define hash_v3_finalize_step_2_u32x(a,b,c) \
637do { \
638 (c) ^= (b); (c) -= u32x_irotate_left ((b), 16); \
639 (a) ^= (c); (a) -= u32x_irotate_left ((c), 4); \
640 (b) ^= (a); (b) -= u32x_irotate_left ((a), 14); \
641 (c) ^= (b); (c) -= u32x_irotate_left ((b), 24); \
642} while (0)
643
644#define hash_v3_mix_u32x(a,b,c) \
645do { \
646 hash_v3_mix_step_1_u32x(a,b,c); \
647 hash_v3_mix_step_2_u32x(a,b,c); \
648} while (0)
649
650#define hash_v3_finalize_u32x(a,b,c) \
651do { \
652 hash_v3_finalize_step_1_u32x(a,b,c); \
653 hash_v3_finalize_step_2_u32x(a,b,c); \
654} while (0)
655
Dave Barachc3799992016-08-15 11:12:27 -0400656extern uword hash_memory (void *p, word n_bytes, uword state);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700657
658extern uword mem_key_sum (hash_t * h, uword key);
659extern uword mem_key_equal (hash_t * h, uword key1, uword key2);
660
661#define hash_create_mem(elts,key_bytes,value_bytes) \
662 hash_create2((elts),(key_bytes),(value_bytes),mem_key_sum,mem_key_equal,0,0)
663
664extern uword vec_key_sum (hash_t * h, uword key);
665extern uword vec_key_equal (hash_t * h, uword key1, uword key2);
Dave Barachc3799992016-08-15 11:12:27 -0400666extern u8 *vec_key_format_pair (u8 * s, va_list * args);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700667
668#define hash_create_vec(elts,key_bytes,value_bytes) \
669 hash_create2((elts),(key_bytes),(value_bytes),\
670 vec_key_sum,vec_key_equal,vec_key_format_pair,0)
671
672extern uword string_key_sum (hash_t * h, uword key);
673extern uword string_key_equal (hash_t * h, uword key1, uword key2);
Dave Barachc3799992016-08-15 11:12:27 -0400674extern u8 *string_key_format_pair (u8 * s, va_list * args);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700675
Ole Troan73710c72018-06-04 22:27:49 +0200676/*
677 * Note: if you plan to put a hash into shared memory,
678 * the key sum and key equal functions MUST be set to magic constants!
679 * PIC means that whichever process sets up the hash won't have
680 * the actual key sum functions at the same place, leading to
681 * very hard-to-find bugs...
682 */
683
684#define hash_create_shmem(elts,key_bytes,value_bytes) \
685 hash_create2((elts),(key_bytes),(value_bytes), \
686 (hash_key_sum_function_t *) KEY_FUNC_MEM, \
687 (hash_key_equal_function_t *)KEY_FUNC_MEM, \
688 0, 0)
689
Ed Warnickecb9cada2015-12-08 15:45:58 -0700690#define hash_create_string(elts,value_bytes) \
691 hash_create2((elts),0,(value_bytes), \
692 (hash_key_sum_function_t *) KEY_FUNC_STRING, \
693 (hash_key_equal_function_t *)KEY_FUNC_STRING, \
694 0, 0)
695
696#define hash_create(elts,value_bytes) \
697 hash_create2((elts),0,(value_bytes), \
698 (hash_key_sum_function_t *) KEY_FUNC_NONE, \
699 (hash_key_equal_function_t *) KEY_FUNC_NONE, \
700 0,0)
701
702#define hash_create_uword(elts,value_bytes) \
703 hash_create2((elts),0,(value_bytes), \
704 (hash_key_sum_function_t *) KEY_FUNC_POINTER_UWORD, \
705 (hash_key_equal_function_t *) KEY_FUNC_POINTER_UWORD, \
706 0,0)
707
708#define hash_create_u32(elts,value_bytes) \
709 hash_create2((elts),0,(value_bytes), \
710 (hash_key_sum_function_t *) KEY_FUNC_POINTER_U32, \
711 (hash_key_equal_function_t *) KEY_FUNC_POINTER_U32, \
712 0,0)
713
Dave Barachc3799992016-08-15 11:12:27 -0400714u8 *format_hash (u8 * s, va_list * va);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700715
716/* Looks up input in hash table indexed by either vec string or
717 c string (null terminated). */
718unformat_function_t unformat_hash_vec_string;
719unformat_function_t unformat_hash_string;
720
Dave Barachc3799992016-08-15 11:12:27 -0400721/* Main test routine. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700722int test_hash_main (unformat_input_t * input);
723
724#endif /* included_hash_h */
Dave Barachc3799992016-08-15 11:12:27 -0400725
726/*
727 * fd.io coding-style-patch-verification: ON
728 *
729 * Local Variables:
730 * eval: (c-set-style "gnu")
731 * End:
732 */