77 #define _(n) (((u64) 1 << (u64) (8*(n))) - (u64) 1) 78 static u64 masks_little_endian[] = {
79 0, _(1), _(2), _(3), _(4), _(5), _(6), _(7),
81 static u64 masks_big_endian[] = {
82 0, ~_(7), ~_(6), ~_(5), ~_(4), ~_(3), ~_(2), ~_(1),
86 return x & masks_big_endian[n];
88 return x & masks_little_endian[n];
96 a = b = 0x9e3779b97f4a7c13LL;
100 while (n >= 3 *
sizeof(
u64))
111 switch (n /
sizeof (
u64))
116 if (n %
sizeof (
u64))
118 n %
sizeof (
u64)) << 8;
123 if (n %
sizeof (
u64))
129 if (n %
sizeof (
u64))
144 #define _(n) (((u32) 1 << (u32) (8*(n))) - (u32) 1) 145 static u32 masks_little_endian[] = {
148 static u32 masks_big_endian[] = {
149 0, ~_(3), ~_(2), ~_(1),
153 return x & masks_big_endian[n];
155 return x & masks_little_endian[n];
167 while (n >= 3 *
sizeof(
u32))
178 switch (n /
sizeof (
u32))
183 if (n %
sizeof (
u32))
185 n %
sizeof (
u32)) << 8;
190 if (n %
sizeof (
u32))
196 if (n %
sizeof (
u32))
213 return hash_memory64 (q, n_bytes, state);
224 a = b = 0x9e3779b97f4a7c13LL;
303 uword e = key1 == key2;
304 if (CLIB_DEBUG > 0 && key1 == key2)
342 uword log2_bytes = 0;
385 uword len, new_len, log2_bytes;
394 1 << (log2_bytes + 1),
450 _vec_len (pi->
pairs) -= 1;
465 void * new_value,
void * old_value)
475 i =
key_sum (h, key) & (_vec_len (v) - 1);
517 if (found_key && op ==
UNSET)
531 if (op ==
SET && p != 0)
534 if (old_value && found_key)
540 h->
elts += !found_key;
542 h->
elts -= found_key;
554 if (! v || h->
elts == 0)
576 if (hn->
i == 0 && hn->
j == 0)
591 memset (hn, 0,
sizeof (hn[0]));
623 void * _hash_unset (
void * v,
uword key,
void * old_value)
646 uword log2_pair_size;
685 void * _hash_free (
void * v)
720 new = _hash_create (new_size, h);
722 new = _hash_set3 (
new, p->
key, &p->
value[0], 0);
737 void * _hash_set3 (
void * v,
uword key,
void * value,
void * old_value)
769 return l1 == l2 && 0 == memcmp (v1, v2, l1 * h->
user);
774 void *
CLIB_UNUSED (user_arg) = va_arg (*args,
void *);
775 void * v = va_arg (*args,
void *);
789 for (i = 0; i <
vec_len (w); i++)
790 s =
format (s,
"0x%x, ", w[i]);
797 for (i = 0; i <
vec_len (w); i++)
798 s =
format (s,
"0x%x, ", w[i]);
805 for (i = 0; i <
vec_len (w); i++)
806 s =
format (s,
"0x%Lx, ", w[i]);
831 return v1 && v2 && 0 == memcmp (v1, v2, h->
user);
844 return v1 && v2 && 0 == strcmp (v1, v2);
849 void *
CLIB_UNUSED (user_arg) = va_arg (*args,
void *);
850 void * v = va_arg (*args,
void *);
865 void *
CLIB_UNUSED (user_arg) = va_arg (*args,
void *);
866 void * v = va_arg (*args,
void *);
902 void * v = va_arg (*va,
void *);
903 int verbose = va_arg (*va,
int);
908 s =
format (s,
"hash %p, %wd elts, capacity %wd, %wd bytes used,\n",
913 uword * occupancy = 0;
937 s =
format (s,
" profile ");
938 for (i = 0; i <
vec_len (occupancy); i++)
939 s =
format (s,
"%wd%c", occupancy[i],
940 i + 1 == vec_len (occupancy) ?
'\n' :
' ');
942 s =
format (s,
" lookup # of compares: ");
943 for (i = 1; i <
vec_len (occupancy); i++)
944 s =
format (s,
"%wd: .%03d%c", i,
945 (1000 * i * occupancy[i]) /
hash_elts (v),
946 i + 1 ==
vec_len (occupancy) ?
'\n' :
' ');
967 int * result = va_arg (*va,
int *);
971 if (!
unformat (input, is_vec ?
"%v%_" :
"%s%_", &
string))
997 #define CHECK(x) if ((error = ERROR_ASSERT (x))) goto done; 1021 for (j = 0; j <
vec_len (keys); j++)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u8 * string_key_format_pair(u8 *s, va_list *args)
sll srl srl sll sra u16x4 i
always_inline void set_is_user(void *v, uword i, uword is_user)
static void unset_indirect(void *v, uword i, hash_pair_t *q)
uword mem_key_equal(hash_t *h, uword key1, uword key2)
void * hash_resize(void *old, uword new_size)
static void(BVT(clib_bihash)*h, BVT(clib_bihash_value)*v)
always_inline void clib_mem_free(void *p)
#define KEY_FUNC_POINTER_UWORD
always_inline void indirect_pair_set(hash_pair_indirect_t *p, uword log2_alloc, uword len)
always_inline hash_t * hash_header(void *v)
#define HASH_FLAG_NO_AUTO_GROW
#define vec_free_header(h)
Free vector user header (syntactic sugar)
always_inline uword key_sum(hash_t *h, uword key)
static hash_pair_union_t * get_indirect(void *v, hash_pair_indirect_t *pi, uword key)
always_inline uword hash_header_bytes(void *v)
always_inline void zero_pair(hash_t *h, hash_pair_t *p)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
always_inline uword max_log2(uword x)
always_inline void * clib_mem_realloc(void *p, uword new_size, uword old_size)
always_inline uword hash_uword(uword x)
always_inline void * hash_forward(hash_t *h, void *v, uword n)
always_inline uword hash_capacity(void *v)
static u32 zap32(u32 x, word n)
always_inline uword hash_is_user(void *v, uword i)
#define KEY_FUNC_POINTER_U32
#define vec_new(T, N)
Create new vector of given type and length (unspecified alignment, no header).
uword vec_key_sum(hash_t *h, uword key)
u8 * format_hash(u8 *s, va_list *va)
static uword pointer_to_uword(const void *p)
u8 * vec_key_format_pair(u8 *s, va_list *args)
static hash_pair_union_t * set_indirect(void *v, hash_pair_indirect_t *pi, uword key, uword *found_key)
clib_error_t * hash_validate(void *v)
always_inline void init_pair(hash_t *h, hash_pair_t *p)
static u8 * hash_format_pair_default(u8 *s, va_list *args)
uword hash_bytes(void *v)
always_inline uword hash_pair_log2_bytes(hash_t *h)
#define uword_to_pointer(u, type)
hash_pair_t * hash_next(void *v, hash_next_t *hn)
static void * hash_resize_internal(void *old, uword new_size, uword free_old)
static hash_pair_t * lookup(void *v, uword key, enum lookup_opcode op, void *new_value, void *old_value)
hash_pair_indirect_t indirect
#define clib_arch_is_big_endian
#define hash_mix64(a0, b0, c0)
always_inline void * clib_mem_alloc(uword size)
#define vec_free(V)
Free vector's memory (no header).
always_inline uword hash_pair_bytes(hash_t *h)
#define clib_memcpy(a, b, c)
#define hash_mix32(a0, b0, c0)
#define HASH_FLAG_HASH_NEXT_IN_PROGRESS
#define vec_capacity(v, b)
Total number of bytes that can fit in vector with current allocation.
always_inline uword hash_elts(void *v)
always_inline uword indirect_pair_get_len(hash_pair_indirect_t *p)
static uword unformat_hash_string_internal(unformat_input_t *input, va_list *va, int is_vec)
void * hash_dup(void *old)
always_inline hash_pair_union_t * get_pair(void *v, uword i)
#define hash_create(elts, value_bytes)
static hash_pair_union_t * set_indirect_is_user(void *v, uword i, hash_pair_union_t *p, uword key)
uword string_key_sum(hash_t *h, uword key)
uword hash_memory(void *p, word n_bytes, uword state)
always_inline uword indirect_pair_get_log2_bytes(hash_pair_indirect_t *p)
vhost_vring_state_t state
uword unformat_hash_string(unformat_input_t *input, va_list *va)
always_inline uword key_equal(hash_t *h, uword key1, uword key2)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define hash_foreach_pair(p, v, body)
always_inline void * hash_forward1(hash_t *h, void *v)
always_inline uword hash_value_bytes(hash_t *h)
#define clib_mem_unaligned(pointer, type)
#define hash_get_mem(h, key)
uword string_key_equal(hash_t *h, uword key1, uword key2)
uword unformat_hash_vec_string(unformat_input_t *input, va_list *va)
always_inline uword key_equal1(hash_t *h, uword key1, uword key2, uword e)
uword mem_key_sum(hash_t *h, uword key)
#define HASH_FLAG_NO_AUTO_SHRINK
uword vec_key_equal(hash_t *h, uword key1, uword key2)
static u32 hash_memory32(void *p, word n_bytes, u32 state)