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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 Copyright (c) 2001-2005 Eliot Dresselhaus
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:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
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.
38 #include <vppinfra/hash.h>
39 #include <vppinfra/error.h>
40 #include <vppinfra/mem.h>
41 #include <vppinfra/byte_order.h> /* for clib_arch_is_big_endian */
44 zero_pair (hash_t * h, hash_pair_t * p)
46 memset (p, 0, hash_pair_bytes (h));
50 init_pair (hash_t * h, hash_pair_t * p)
52 memset (p->value, ~0, hash_value_bytes (h));
55 always_inline hash_pair_union_t *
56 get_pair (void *v, uword i)
58 hash_t *h = hash_header (v);
60 ASSERT (i < vec_len (v));
62 p += i << h->log2_pair_size;
63 return (hash_pair_union_t *) p;
67 set_is_user (void *v, uword i, uword is_user)
69 hash_t *h = hash_header (v);
70 uword i0 = i / BITS (h->is_user[0]);
71 uword i1 = (uword) 1 << (i % BITS (h->is_user[0]));
75 h->is_user[i0] &= ~i1;
78 static u8 *hash_format_pair_default (u8 * s, va_list * args);
83 get_unaligned_as_u64 (void const *data, int n)
87 u8 const *p = (u8 const *) data;
89 if (clib_arch_is_big_endian)
91 for (i = 0; i < n; i++)
92 r |= ((u64) ((*(p + i)) << (u8) (1 << (8 - i))));
96 for (i = 0; i < n; i++)
97 r |= ((u64) ((*(p + i)) << (u8) (1 << i)));
104 hash_memory64 (void *p, word n_bytes, u64 state)
109 a = b = 0x9e3779b97f4a7c13LL;
113 while (n >= 3 * sizeof (u64))
115 a += clib_mem_unaligned (q + 0, u64);
116 b += clib_mem_unaligned (q + 1, u64);
117 c += clib_mem_unaligned (q + 2, u64);
118 hash_mix64 (a, b, c);
119 n -= 3 * sizeof (u64);
124 switch (n / sizeof (u64))
127 a += clib_mem_unaligned (q + 0, u64);
128 b += clib_mem_unaligned (q + 1, u64);
129 c += get_unaligned_as_u64 (q + 2, n % sizeof (u64)) << 8;
133 a += clib_mem_unaligned (q + 0, u64);
134 b += get_unaligned_as_u64 (q + 1, n % sizeof (u64));
138 a += get_unaligned_as_u64 (q + 0, n % sizeof (u64));
142 hash_mix64 (a, b, c);
147 #else /* if uword_bits == 64 */
150 zap32 (u32 x, word n)
152 #define _(n) (((u32) 1 << (u32) (8*(n))) - (u32) 1)
153 static u32 masks_little_endian[] = {
156 static u32 masks_big_endian[] = {
157 0, ~_(3), ~_(2), ~_(1),
160 if (clib_arch_is_big_endian)
161 return x & masks_big_endian[n];
163 return x & masks_little_endian[n];
167 hash_memory32 (void *p, word n_bytes, u32 state)
176 while (n >= 3 * sizeof (u32))
178 a += clib_mem_unaligned (q + 0, u32);
179 b += clib_mem_unaligned (q + 1, u32);
180 c += clib_mem_unaligned (q + 2, u32);
181 hash_mix32 (a, b, c);
182 n -= 3 * sizeof (u32);
187 switch (n / sizeof (u32))
190 a += clib_mem_unaligned (q + 0, u32);
191 b += clib_mem_unaligned (q + 1, u32);
192 if (n % sizeof (u32))
193 c += zap32 (clib_mem_unaligned (q + 2, u32), n % sizeof (u32)) << 8;
197 a += clib_mem_unaligned (q + 0, u32);
198 if (n % sizeof (u32))
199 b += zap32 (clib_mem_unaligned (q + 1, u32), n % sizeof (u32));
203 if (n % sizeof (u32))
204 a += zap32 (clib_mem_unaligned (q + 0, u32), n % sizeof (u32));
208 hash_mix32 (a, b, c);
215 hash_memory (void *p, word n_bytes, uword state)
220 return hash_memory64 (q, n_bytes, state);
222 return hash_memory32 (q, n_bytes, state);
232 a = b = 0x9e3779b97f4a7c13LL;
235 hash_mix64 (a, b, c);
247 hash_mix32 (a, b, c);
252 /* Call sum function. Hash code will be sum function value
253 modulo the prime length of the hash table. */
255 key_sum (hash_t * h, uword key)
258 switch (pointer_to_uword ((void *) h->key_sum))
261 sum = hash_uword (key);
264 case KEY_FUNC_POINTER_UWORD:
265 sum = hash_uword (*uword_to_pointer (key, uword *));
268 case KEY_FUNC_POINTER_U32:
269 sum = hash_uword (*uword_to_pointer (key, u32 *));
272 case KEY_FUNC_STRING:
273 sum = string_key_sum (h, key);
277 sum = h->key_sum (h, key);
285 key_equal1 (hash_t * h, uword key1, uword key2, uword e)
287 switch (pointer_to_uword ((void *) h->key_equal))
292 case KEY_FUNC_POINTER_UWORD:
294 *uword_to_pointer (key1, uword *) == *uword_to_pointer (key2,
298 case KEY_FUNC_POINTER_U32:
299 e = *uword_to_pointer (key1, u32 *) == *uword_to_pointer (key2, u32 *);
302 case KEY_FUNC_STRING:
303 e = string_key_equal (h, key1, key2);
307 e = h->key_equal (h, key1, key2);
313 /* Compares two keys: returns 1 if equal, 0 if not. */
315 key_equal (hash_t * h, uword key1, uword key2)
317 uword e = key1 == key2;
318 if (CLIB_DEBUG > 0 && key1 == key2)
319 ASSERT (key_equal1 (h, key1, key2, e));
321 e = key_equal1 (h, key1, key2, e);
325 static hash_pair_union_t *
326 get_indirect (void *v, hash_pair_indirect_t * pi, uword key)
328 hash_t *h = hash_header (v);
329 hash_pair_t *p0, *p1;
332 if (h->log2_pair_size > 0)
333 p1 = hash_forward (h, p0, indirect_pair_get_len (pi));
339 if (key_equal (h, p0->key, key))
340 return (hash_pair_union_t *) p0;
341 p0 = hash_forward1 (h, p0);
344 return (hash_pair_union_t *) 0;
347 static hash_pair_union_t *
348 set_indirect_is_user (void *v, uword i, hash_pair_union_t * p, uword key)
350 hash_t *h = hash_header (v);
352 hash_pair_indirect_t *pi = &p->indirect;
353 uword log2_bytes = 0;
355 if (h->log2_pair_size == 0)
356 q = vec_new (hash_pair_t, 2);
359 log2_bytes = 1 + hash_pair_log2_bytes (h);
360 q = clib_mem_alloc (1ULL << log2_bytes);
362 clib_memcpy (q, &p->direct, hash_pair_bytes (h));
365 if (h->log2_pair_size > 0)
366 indirect_pair_set (pi, log2_bytes, 2);
368 set_is_user (v, i, 0);
370 /* First element is used by existing pair, second will be used by caller. */
371 q = hash_forward1 (h, q);
374 return (hash_pair_union_t *) q;
377 static hash_pair_union_t *
378 set_indirect (void *v, hash_pair_indirect_t * pi, uword key,
381 hash_t *h = hash_header (v);
382 hash_pair_t *new_pair;
383 hash_pair_union_t *q;
385 q = get_indirect (v, pi, key);
392 if (h->log2_pair_size == 0)
393 vec_add2 (pi->pairs, new_pair, 1);
396 uword len, new_len, log2_bytes;
398 len = indirect_pair_get_len (pi);
399 log2_bytes = indirect_pair_get_log2_bytes (pi);
402 if (new_len * hash_pair_bytes (h) > (1ULL << log2_bytes))
404 pi->pairs = clib_mem_realloc (pi->pairs,
405 1ULL << (log2_bytes + 1),
410 indirect_pair_set (pi, log2_bytes, new_len);
411 new_pair = pi->pairs + (len << h->log2_pair_size);
414 init_pair (h, new_pair);
416 return (hash_pair_union_t *) new_pair;
420 unset_indirect (void *v, uword i, hash_pair_t * q)
422 hash_t *h = hash_header (v);
423 hash_pair_union_t *p = get_pair (v, i);
425 hash_pair_indirect_t *pi = &p->indirect;
428 is_vec = h->log2_pair_size == 0;
430 ASSERT (!hash_is_user (v, i));
431 len = is_vec ? vec_len (pi->pairs) : indirect_pair_get_len (pi);
432 e = hash_forward (h, pi->pairs, len - 1);
433 ASSERT (q >= pi->pairs && q <= e);
435 /* We have two or fewer pairs and we are delete one pair.
436 Make indirect pointer direct and free indirect memory. */
439 hash_pair_t *r = pi->pairs;
443 clib_memcpy (p, q == r ? hash_forward1 (h, r) : r,
444 hash_pair_bytes (h));
445 set_is_user (v, i, 1);
448 zero_pair (h, &p->direct);
457 /* If deleting a pair we need to keep non-null pairs together. */
459 clib_memcpy (q, e, hash_pair_bytes (h));
463 _vec_len (pi->pairs) -= 1;
465 indirect_pair_set (pi, indirect_pair_get_log2_bytes (pi), len - 1);
477 lookup (void *v, uword key, enum lookup_opcode op,
478 void *new_value, void *old_value)
480 hash_t *h = hash_header (v);
481 hash_pair_union_t *p = 0;
488 i = key_sum (h, key) & (_vec_len (v) - 1);
491 if (hash_is_user (v, i))
493 found_key = key_equal (h, p->direct.key, key);
498 set_is_user (v, i, 0);
500 clib_memcpy (old_value, p->direct.value,
501 hash_value_bytes (h));
502 zero_pair (h, &p->direct);
508 p = set_indirect_is_user (v, i, p, key);
515 hash_pair_indirect_t *pi = &p->indirect;
522 set_is_user (v, i, 1);
525 p = set_indirect (v, pi, key, &found_key);
529 p = get_indirect (v, pi, key);
531 if (found_key && op == UNSET)
534 clib_memcpy (old_value, &p->direct.value,
535 hash_value_bytes (h));
537 unset_indirect (v, i, &p->direct);
539 /* Nullify p (since it's just been deleted).
540 Otherwise we might be tempted to play with it. */
546 if (op == SET && p != 0)
548 /* Save away old value for caller. */
549 if (old_value && found_key)
550 clib_memcpy (old_value, &p->direct.value, hash_value_bytes (h));
551 clib_memcpy (&p->direct.value, new_value, hash_value_bytes (h));
555 h->elts += !found_key;
557 h->elts -= found_key;
562 /* Fetch value of key. */
564 _hash_get (void *v, uword key)
566 hash_t *h = hash_header (v);
569 /* Don't even search table if its empty. */
570 if (!v || h->elts == 0)
573 p = lookup (v, key, GET, 0, 0);
576 if (h->log2_pair_size == 0)
583 _hash_get_pair (void *v, uword key)
585 return lookup (v, key, GET, 0, 0);
589 hash_next (void *v, hash_next_t * hn)
591 hash_t *h = hash_header (v);
596 if (hn->i == 0 && hn->j == 0)
601 /* Prevent others from re-sizing hash table. */
603 (HASH_FLAG_NO_AUTO_GROW
604 | HASH_FLAG_NO_AUTO_SHRINK | HASH_FLAG_HASH_NEXT_IN_PROGRESS);
606 else if (hn->i >= hash_capacity (v))
610 memset (hn, 0, sizeof (hn[0]));
614 p = hash_forward (h, v, hn->i);
615 if (hash_is_user (v, hn->i))
622 hash_pair_indirect_t *pi = (void *) p;
625 if (h->log2_pair_size > 0)
626 n = indirect_pair_get_len (pi);
628 n = vec_len (pi->pairs);
636 return hash_forward (h, pi->pairs, hn->j++);
641 /* Remove key from table. */
643 _hash_unset (void *v, uword key, void *old_value)
650 (void) lookup (v, key, UNSET, 0, old_value);
653 if (!(h->flags & HASH_FLAG_NO_AUTO_SHRINK))
655 /* Resize when 1/4 full. */
656 if (h->elts > 32 && 4 * (h->elts + 1) < vec_len (v))
657 v = hash_resize (v, vec_len (v) / 2);
664 _hash_create (uword elts, hash_t * h_user)
667 uword log2_pair_size;
670 /* Size of hash is power of 2 >= ELTS and larger than
671 number of bits in is_user bitmap elements. */
672 elts = clib_max (elts, BITS (h->is_user[0]));
673 elts = 1ULL << max_log2 (elts);
677 log2_pair_size = h_user->log2_pair_size;
682 (elts << log2_pair_size) * sizeof (hash_pair_t),
685 (elts / BITS (h->is_user[0])) * sizeof (h->is_user[0]),
686 /* alignment */ sizeof (hash_pair_t));
692 h->log2_pair_size = log2_pair_size;
695 /* Default flags to never shrinking hash tables.
696 Shrinking tables can cause "jackpot" cases. */
698 h->flags = HASH_FLAG_NO_AUTO_SHRINK;
702 h->format_pair = hash_format_pair_default;
703 h->format_pair_arg = 0;
712 hash_t *h = hash_header (v);
713 hash_pair_union_t *p;
719 /* We zero all freed memory in case user would be tempted to use it. */
720 for (i = 0; i < hash_capacity (v); i++)
722 if (hash_is_user (v, i))
725 if (h->log2_pair_size == 0)
726 vec_free (p->indirect.pairs);
727 else if (p->indirect.pairs)
728 clib_mem_free (p->indirect.pairs);
737 hash_resize_internal (void *old, uword new_size, uword free_old)
745 hash_t *h = old ? hash_header (old) : 0;
746 new = _hash_create (new_size, h);
748 hash_foreach_pair (p, old, {
749 new = _hash_set3 (new, p->key, &p->value[0], 0);
760 hash_resize (void *old, uword new_size)
762 return hash_resize_internal (old, new_size, 1);
768 return hash_resize_internal (old, vec_len (old), 0);
772 _hash_set3 (void *v, uword key, void *value, void *old_value)
777 v = hash_create (0, sizeof (uword));
780 (void) lookup (v, key, SET, value, old_value);
782 if (!(h->flags & HASH_FLAG_NO_AUTO_GROW))
784 /* Resize when 3/4 full. */
785 if (4 * (h->elts + 1) > 3 * vec_len (v))
786 v = hash_resize (v, 2 * vec_len (v));
793 vec_key_sum (hash_t * h, uword key)
795 void *v = uword_to_pointer (key, void *);
796 return hash_memory (v, vec_len (v) * h->user, 0);
800 vec_key_equal (hash_t * h, uword key1, uword key2)
802 void *v1 = uword_to_pointer (key1, void *);
803 void *v2 = uword_to_pointer (key2, void *);
804 uword l1 = vec_len (v1);
805 uword l2 = vec_len (v2);
806 return l1 == l2 && 0 == memcmp (v1, v2, l1 * h->user);
810 vec_key_format_pair (u8 * s, va_list * args)
812 void *CLIB_UNUSED (user_arg) = va_arg (*args, void *);
813 void *v = va_arg (*args, void *);
814 hash_pair_t *p = va_arg (*args, hash_pair_t *);
815 hash_t *h = hash_header (v);
816 void *u = uword_to_pointer (p->key, void *);
822 s = format (s, "%v", u);
828 for (i = 0; i < vec_len (w); i++)
829 s = format (s, "0x%x, ", w[i]);
836 for (i = 0; i < vec_len (w); i++)
837 s = format (s, "0x%x, ", w[i]);
844 for (i = 0; i < vec_len (w); i++)
845 s = format (s, "0x%Lx, ", w[i]);
850 s = format (s, "0x%U", format_hex_bytes, u, vec_len (u) * h->user);
854 if (hash_value_bytes (h) > 0)
855 s = format (s, " -> 0x%wx", p->value[0]);
861 mem_key_sum (hash_t * h, uword key)
863 uword *v = uword_to_pointer (key, void *);
864 return hash_memory (v, h->user, 0);
868 mem_key_equal (hash_t * h, uword key1, uword key2)
870 void *v1 = uword_to_pointer (key1, void *);
871 void *v2 = uword_to_pointer (key2, void *);
872 return v1 && v2 && 0 == memcmp (v1, v2, h->user);
876 string_key_sum (hash_t * h, uword key)
878 char *v = uword_to_pointer (key, char *);
879 return hash_memory (v, strlen (v), 0);
883 string_key_equal (hash_t * h, uword key1, uword key2)
885 void *v1 = uword_to_pointer (key1, void *);
886 void *v2 = uword_to_pointer (key2, void *);
887 return v1 && v2 && 0 == strcmp (v1, v2);
891 string_key_format_pair (u8 * s, va_list * args)
893 void *CLIB_UNUSED (user_arg) = va_arg (*args, void *);
894 void *v = va_arg (*args, void *);
895 hash_pair_t *p = va_arg (*args, hash_pair_t *);
896 hash_t *h = hash_header (v);
897 void *u = uword_to_pointer (p->key, void *);
899 s = format (s, "%s", u);
901 if (hash_value_bytes (h) > 0)
903 format (s, " -> 0x%8U", format_hex_bytes, &p->value[0],
904 hash_value_bytes (h));
910 hash_format_pair_default (u8 * s, va_list * args)
912 void *CLIB_UNUSED (user_arg) = va_arg (*args, void *);
913 void *v = va_arg (*args, void *);
914 hash_pair_t *p = va_arg (*args, hash_pair_t *);
915 hash_t *h = hash_header (v);
917 s = format (s, "0x%08x", p->key);
918 if (hash_value_bytes (h) > 0)
920 format (s, " -> 0x%8U", format_hex_bytes, &p->value[0],
921 hash_value_bytes (h));
929 hash_t *h = hash_header (v);
934 bytes = vec_capacity (v, hash_header_bytes (v));
936 for (i = 0; i < hash_capacity (v); i++)
938 if (!hash_is_user (v, i))
940 hash_pair_union_t *p = get_pair (v, i);
941 if (h->log2_pair_size > 0)
942 bytes += 1 << indirect_pair_get_log2_bytes (&p->indirect);
944 bytes += vec_capacity (p->indirect.pairs, 0);
951 format_hash (u8 * s, va_list * va)
953 void *v = va_arg (*va, void *);
954 int verbose = va_arg (*va, int);
956 hash_t *h = hash_header (v);
959 s = format (s, "hash %p, %wd elts, capacity %wd, %wd bytes used,\n",
960 v, hash_elts (v), hash_capacity (v), hash_bytes (v));
963 uword *occupancy = 0;
965 /* Count number of buckets with each occupancy. */
966 for (i = 0; i < hash_capacity (v); i++)
970 if (hash_is_user (v, i))
976 hash_pair_union_t *p = get_pair (v, i);
977 if (h->log2_pair_size > 0)
978 j = indirect_pair_get_len (&p->indirect);
980 j = vec_len (p->indirect.pairs);
983 vec_validate (occupancy, j);
987 s = format (s, " profile ");
988 for (i = 0; i < vec_len (occupancy); i++)
989 s = format (s, "%wd%c", occupancy[i],
990 i + 1 == vec_len (occupancy) ? '\n' : ' ');
992 s = format (s, " lookup # of compares: ");
993 for (i = 1; i < vec_len (occupancy); i++)
994 s = format (s, "%wd: .%03d%c", i,
995 (1000 * i * occupancy[i]) / hash_elts (v),
996 i + 1 == vec_len (occupancy) ? '\n' : ' ');
998 vec_free (occupancy);
1004 hash_foreach_pair (p, v, {
1005 s = format (s, " %U\n", h->format_pair, h->format_pair_arg, v, p);
1014 unformat_hash_string_internal (unformat_input_t * input,
1015 va_list * va, int is_vec)
1017 uword *hash = va_arg (*va, uword *);
1018 int *result = va_arg (*va, int *);
1022 if (!unformat (input, is_vec ? "%v%_" : "%s%_", &string))
1025 p = hash_get_mem (hash, string);
1034 unformat_hash_vec_string (unformat_input_t * input, va_list * va)
1036 return unformat_hash_string_internal (input, va, /* is_vec */ 1);
1040 unformat_hash_string (unformat_input_t * input, va_list * va)
1042 return unformat_hash_string_internal (input, va, /* is_vec */ 0);
1046 hash_validate (void *v)
1048 hash_t *h = hash_header (v);
1051 clib_error_t *error = 0;
1053 #define CHECK(x) if ((error = ERROR_ASSERT (x))) goto done;
1055 for (i = 0; i < hash_capacity (v); i++)
1057 hash_pair_union_t *pu = get_pair (v, i);
1059 if (hash_is_user (v, i))
1061 CHECK (pu->direct.key != 0);
1062 vec_add1 (keys, pu->direct.key);
1067 hash_pair_indirect_t *pi = &pu->indirect;
1070 n = h->log2_pair_size > 0
1071 ? indirect_pair_get_len (pi) : vec_len (pi->pairs);
1073 for (p = pi->pairs; n-- > 0; p = hash_forward1 (h, p))
1075 /* Assert key uniqueness. */
1076 for (j = 0; j < vec_len (keys); j++)
1077 CHECK (keys[j] != p->key);
1078 vec_add1 (keys, p->key);
1083 CHECK (vec_len (keys) == h->elts);
1091 * fd.io coding-style-patch-verification: ON
1094 * eval: (c-set-style "gnu")