38 #ifndef included_hash_h 39 #define included_hash_h 62 #define HASH_FLAG_NO_AUTO_GROW (1 << 0) 64 #define HASH_FLAG_NO_AUTO_SHRINK (1 << 1) 66 #define HASH_FLAG_HASH_NEXT_IN_PROGRESS (1 << 2) 76 #define KEY_FUNC_NONE (0) 77 #define KEY_FUNC_POINTER_UWORD (1) 78 #define KEY_FUNC_POINTER_U32 (2) 79 #define KEY_FUNC_STRING (3) 103 uword is_user_bytes =
105 return sizeof (h[0]) + is_user_bytes;
120 return v ? h->
elts : 0;
190 #define LOG2_ALLOC_BITS (5) 191 #define PAIR_BITS (BITS (uword) - LOG2_ALLOC_BITS) 226 void *_hash_unset (
void *v,
uword key,
void *old_value);
229 void *_hash_set3 (
void *v,
uword key,
void *value,
void *old_value);
241 #define hash_set3(h,key,value,old_value) \ 243 uword _v = (uword) (value); \ 244 (h) = _hash_set3 ((h), (uword) (key), (void *) &_v, (old_value)); \ 248 #define hash_get(h,key) _hash_get ((h), (uword) (key)) 251 #define hash_get_pair(h,key) _hash_get_pair ((h), (uword) (key)) 254 #define hash_set(h,key,value) hash_set3(h,key,value,0) 257 #define hash_set1(h,key) (h) = _hash_set3(h,(uword) (key),0,0) 260 #define hash_unset(h,key) ((h) = _hash_unset ((h), (uword) (key),0)) 263 #define hash_unset3(h,key,old_value) ((h) = _hash_unset ((h), (uword) (key), (void *) (old_value))) 268 #define hash_get_mem(h,key) _hash_get ((h), pointer_to_uword (key)) 271 #define hash_get_pair_mem(h,key) _hash_get_pair ((h), pointer_to_uword (key)) 274 #define hash_set_mem(h,key,value) hash_set3 (h, pointer_to_uword (key), (value), 0) 287 #define hash_set1_mem(h,key) hash_set3 ((h), pointer_to_uword (key), 0, 0) 290 #define hash_unset_mem(h,key) ((h) = _hash_unset ((h), pointer_to_uword (key),0)) 306 extern void *_hash_free (
void *v);
309 #define hash_free(h) (h) = _hash_free ((h)) 372 #define hash_foreach_pair(p,v,body) \ 374 __label__ _hash_foreach_done; \ 375 hash_t * _h = hash_header (v); \ 377 hash_pair_t * _q, * _q_end; \ 378 uword _i, _i1, _id, _pair_increment; \ 382 _pair_increment = 1; \ 384 _pair_increment = 1 << _h->log2_pair_size; \ 385 while (_i < hash_capacity (v)) \ 387 _id = _h->is_user[_i / BITS (_h->is_user[0])]; \ 388 _i1 = _i + BITS (_h->is_user[0]); \ 394 _q_end = _q + _pair_increment; \ 398 hash_pair_indirect_t * _pi = _p; \ 400 if (_h->log2_pair_size > 0) \ 401 _q_end = hash_forward (_h, _q, indirect_pair_get_len (_pi)); \ 403 _q_end = vec_end (_q); \ 408 while (_q < _q_end) \ 410 uword _break_in_body = 1; \ 414 _break_in_body = 0; \ 416 if (_break_in_body) \ 417 goto _hash_foreach_done; \ 418 _q += _pair_increment; \ 421 _p = (hash_pair_t *)_p + _pair_increment; \ 424 } while (_i < _i1); \ 426 _hash_foreach_done: \ 441 #define hash_foreach(key_var,value_var,h,body) \ 444 hash_foreach_pair (_r, (h), { \ 445 (key_var) = (__typeof__ (key_var)) _r->key; \ 446 (value_var) = (__typeof__ (value_var)) _r->value[0]; \ 447 do { body; } while (0); \ 460 #define hash_foreach_mem(key_var,value_var,h,body) \ 463 hash_foreach_pair (_r, (h), { \ 464 (key_var) = (__typeof__ (key_var)) uword_to_pointer (_r->key, void *); \ 465 (value_var) = (__typeof__ (value_var)) _r->value[0]; \ 466 do { body; } while (0); \ 490 1) / sizeof (p->
key));
493 #define hash_create2(_elts,_user,_value_bytes, \ 494 _key_sum,_key_equal, \ 495 _format_pair,_format_pair_arg) \ 498 memset (&_h, 0, sizeof (_h)); \ 500 _h.key_sum = (hash_key_sum_function_t *) (_key_sum); \ 501 _h.key_equal = (_key_equal); \ 502 hash_set_value_bytes (&_h, (_value_bytes)); \ 503 _h.format_pair = (format_function_t *) (_format_pair); \ 504 _h.format_pair_arg = (_format_pair_arg); \ 505 _hash_create ((_elts), &_h); \ 512 #define hash_mix_step(a,b,c,s0,s1,s2) \ 514 (a) -= (b) + (c); (a) ^= (c) >> (s0); \ 515 (b) -= (c) + (a); (b) ^= (a) << (s1); \ 516 (c) -= (a) + (b); (c) ^= (b) >> (s2); \ 519 #define hash_mix32_step_1(a,b,c) hash_mix_step(a,b,c,13,8,13) 520 #define hash_mix32_step_2(a,b,c) hash_mix_step(a,b,c,12,16,5) 521 #define hash_mix32_step_3(a,b,c) hash_mix_step(a,b,c,3,10,15) 523 #define hash_mix64_step_1(a,b,c) hash_mix_step(a,b,c,43,9,8) 524 #define hash_mix64_step_2(a,b,c) hash_mix_step(a,b,c,38,23,5) 525 #define hash_mix64_step_3(a,b,c) hash_mix_step(a,b,c,35,49,11) 526 #define hash_mix64_step_4(a,b,c) hash_mix_step(a,b,c,12,18,22) 530 #define hash_mix64(a0,b0,c0) \ 532 hash_mix64_step_1 (a0, b0, c0); \ 533 hash_mix64_step_2 (a0, b0, c0); \ 534 hash_mix64_step_3 (a0, b0, c0); \ 535 hash_mix64_step_4 (a0, b0, c0); \ 538 #define hash_mix32(a0,b0,c0) \ 540 hash_mix32_step_1 (a0, b0, c0); \ 541 hash_mix32_step_2 (a0, b0, c0); \ 542 hash_mix32_step_3 (a0, b0, c0); \ 550 return (x << i) | (x >> (
BITS (i) -
i));
553 #define hash_v3_mix32(a,b,c) \ 555 (a) -= (c); (a) ^= hash32_rotate_left ((c), 4); (c) += (b); \ 556 (b) -= (a); (b) ^= hash32_rotate_left ((a), 6); (a) += (c); \ 557 (c) -= (b); (c) ^= hash32_rotate_left ((b), 8); (b) += (a); \ 558 (a) -= (c); (a) ^= hash32_rotate_left ((c),16); (c) += (b); \ 559 (b) -= (a); (b) ^= hash32_rotate_left ((a),19); (a) += (c); \ 560 (c) -= (b); (c) ^= hash32_rotate_left ((b), 4); (b) += (a); \ 563 #define hash_v3_finalize32(a,b,c) \ 565 (c) ^= (b); (c) -= hash32_rotate_left ((b), 14); \ 566 (a) ^= (c); (a) -= hash32_rotate_left ((c), 11); \ 567 (b) ^= (a); (b) -= hash32_rotate_left ((a), 25); \ 568 (c) ^= (b); (c) -= hash32_rotate_left ((b), 16); \ 569 (a) ^= (c); (a) -= hash32_rotate_left ((c), 4); \ 570 (b) ^= (a); (b) -= hash32_rotate_left ((a), 14); \ 571 (c) ^= (b); (c) -= hash32_rotate_left ((b), 24); \ 576 #define hash_v3_mix32_step1(a,b,c) \ 578 (a) -= (c); (a) ^= hash32_rotate_left ((c), 4); (c) += (b); \ 579 (b) -= (a); (b) ^= hash32_rotate_left ((a), 6); (a) += (c); \ 582 #define hash_v3_mix32_step2(a,b,c) \ 584 (c) -= (b); (c) ^= hash32_rotate_left ((b), 8); (b) += (a); \ 585 (a) -= (c); (a) ^= hash32_rotate_left ((c),16); (c) += (b); \ 588 #define hash_v3_mix32_step3(a,b,c) \ 590 (b) -= (a); (b) ^= hash32_rotate_left ((a),19); (a) += (c); \ 591 (c) -= (b); (c) ^= hash32_rotate_left ((b), 4); (b) += (a); \ 594 #define hash_v3_finalize32_step1(a,b,c) \ 596 (c) ^= (b); (c) -= hash32_rotate_left ((b), 14); \ 597 (a) ^= (c); (a) -= hash32_rotate_left ((c), 11); \ 600 #define hash_v3_finalize32_step2(a,b,c) \ 602 (b) ^= (a); (b) -= hash32_rotate_left ((a), 25); \ 603 (c) ^= (b); (c) -= hash32_rotate_left ((b), 16); \ 606 #define hash_v3_finalize32_step3(a,b,c) \ 608 (a) ^= (c); (a) -= hash32_rotate_left ((c), 4); \ 609 (b) ^= (a); (b) -= hash32_rotate_left ((a), 14); \ 610 (c) ^= (b); (c) -= hash32_rotate_left ((b), 24); \ 614 #define hash_v3_mix_step_1_u32x(a,b,c) \ 616 (a) -= (c); (a) ^= u32x_irotate_left ((c), 4); (c) += (b); \ 617 (b) -= (a); (b) ^= u32x_irotate_left ((a), 6); (a) += (c); \ 618 (c) -= (b); (c) ^= u32x_irotate_left ((b), 8); (b) += (a); \ 621 #define hash_v3_mix_step_2_u32x(a,b,c) \ 623 (a) -= (c); (a) ^= u32x_irotate_left ((c),16); (c) += (b); \ 624 (b) -= (a); (b) ^= u32x_irotate_left ((a),19); (a) += (c); \ 625 (c) -= (b); (c) ^= u32x_irotate_left ((b), 4); (b) += (a); \ 628 #define hash_v3_finalize_step_1_u32x(a,b,c) \ 630 (c) ^= (b); (c) -= u32x_irotate_left ((b), 14); \ 631 (a) ^= (c); (a) -= u32x_irotate_left ((c), 11); \ 632 (b) ^= (a); (b) -= u32x_irotate_left ((a), 25); \ 635 #define hash_v3_finalize_step_2_u32x(a,b,c) \ 637 (c) ^= (b); (c) -= u32x_irotate_left ((b), 16); \ 638 (a) ^= (c); (a) -= u32x_irotate_left ((c), 4); \ 639 (b) ^= (a); (b) -= u32x_irotate_left ((a), 14); \ 640 (c) ^= (b); (c) -= u32x_irotate_left ((b), 24); \ 643 #define hash_v3_mix_u32x(a,b,c) \ 645 hash_v3_mix_step_1_u32x(a,b,c); \ 646 hash_v3_mix_step_2_u32x(a,b,c); \ 649 #define hash_v3_finalize_u32x(a,b,c) \ 651 hash_v3_finalize_step_1_u32x(a,b,c); \ 652 hash_v3_finalize_step_2_u32x(a,b,c); \ 660 #define hash_create_mem(elts,key_bytes,value_bytes) \ 661 hash_create2((elts),(key_bytes),(value_bytes),mem_key_sum,mem_key_equal,0,0) 667 #define hash_create_vec(elts,key_bytes,value_bytes) \ 668 hash_create2((elts),(key_bytes),(value_bytes),\ 669 vec_key_sum,vec_key_equal,vec_key_format_pair,0) 675 #define hash_create_string(elts,value_bytes) \ 676 hash_create2((elts),0,(value_bytes), \ 677 (hash_key_sum_function_t *) KEY_FUNC_STRING, \ 678 (hash_key_equal_function_t *)KEY_FUNC_STRING, \ 681 #define hash_create(elts,value_bytes) \ 682 hash_create2((elts),0,(value_bytes), \ 683 (hash_key_sum_function_t *) KEY_FUNC_NONE, \ 684 (hash_key_equal_function_t *) KEY_FUNC_NONE, \ 687 #define hash_create_uword(elts,value_bytes) \ 688 hash_create2((elts),0,(value_bytes), \ 689 (hash_key_sum_function_t *) KEY_FUNC_POINTER_UWORD, \ 690 (hash_key_equal_function_t *) KEY_FUNC_POINTER_UWORD, \ 693 #define hash_create_u32(elts,value_bytes) \ 694 hash_create2((elts),0,(value_bytes), \ 695 (hash_key_sum_function_t *) KEY_FUNC_POINTER_U32, \ 696 (hash_key_equal_function_t *) KEY_FUNC_POINTER_U32, \
clib_error_t * hash_validate(void *v)
u8 pad[3]
log2 (size of the packing page block)
uword hash_bytes(void *v)
static uword indirect_pair_get_len(hash_pair_indirect_t *p)
unformat_function_t unformat_hash_string
uword hash_memory(void *p, word n_bytes, uword state)
u8 * format_hash(u8 *s, va_list *va)
uword mem_key_sum(hash_t *h, uword key)
static void hash_set_value_bytes(hash_t *h, uword value_bytes)
int test_hash_main(unformat_input_t *input)
static void indirect_pair_set(hash_pair_indirect_t *p, uword log2_alloc, uword len)
#define hash_set_mem(h, key, value)
uword vec_key_equal(hash_t *h, uword key1, uword key2)
#define hash_get_pair_mem(h, key)
uword( hash_key_equal_function_t)(struct hash_header *, uword key1, uword key2)
static uword hash_header_bytes(void *v)
static void hash_set_flags(void *v, uword flags)
static uword hash_value_bytes(hash_t *h)
static hash_t * hash_header(void *v)
#define hash_unset_mem(h, key)
static uword hash_capacity(void *v)
void * hash_dup(void *old)
static uword hash_is_user(void *v, uword i)
static uword hash_pair_bytes(hash_t *h)
uword string_key_equal(hash_t *h, uword key1, uword key2)
void * hash_resize(void *old, uword new_size)
unformat_function_t unformat_hash_vec_string
#define uword_to_pointer(u, type)
static uword hash_pair_log2_bytes(hash_t *h)
hash_pair_indirect_t indirect
static void * hash_forward1(hash_t *h, void *v)
static void hash_set_pair_format(void *v, format_function_t *format_pair, void *format_pair_arg)
#define clib_memcpy(a, b, c)
static uword hash32_rotate_left(u32 x, u32 i)
u8 * string_key_format_pair(u8 *s, va_list *args)
uword mem_key_equal(hash_t *h, uword key1, uword key2)
static uword indirect_pair_get_log2_bytes(hash_pair_indirect_t *p)
static uword hash_elts(void *v)
static void * hash_forward(hash_t *h, void *v, uword n)
vhost_vring_state_t state
static void clib_mem_free(void *p)
static void * clib_mem_alloc(uword size)
hash_pair_t * hash_next(void *v, hash_next_t *hn)
uword( hash_key_sum_function_t)(struct hash_header *, uword key)
u8 * vec_key_format_pair(u8 *s, va_list *args)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
struct hash_header hash_t
static uword max_log2(uword x)
static void hash_set_mem_alloc(uword **h, void *key, uword v)
static void hash_unset_mem_free(uword **h, void *key)
static void * vec_header(void *v, uword header_bytes)
Find a user vector header.
uword string_key_sum(hash_t *h, uword key)
uword vec_key_sum(hash_t *h, uword key)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".