16 #ifndef __HICN_HASHTB_H__
17 #define __HICN_HASHTB_H__
20 #include <vppinfra/bihash_8_8.h>
21 #include <vppinfra/bihash_24_8.h>
76 #define HICN_HASH_INVALID_IDX ~0
82 #define HICN_HASH_WALK_CTX_INITIAL (~((u64) 0))
104 #define NODE_IDX_FROM_NODE(p, h) (u32) ((p) - ((h)->ht_nodes))
106 #define HICN_HASH_KEY_BYTES 20
112 u8 key[HICN_HASH_KEY_BYTES];
120 #define HICN_HASHTB_KEY_RATIO 8
136 #define HICN_HASH_NODE_APP_DATA_SIZE 64
139 typedef struct __attribute__ ((packed)) hicn_hash_node_s
161 u8 hn_data[HICN_HASH_NODE_APP_DATA_SIZE];
165 #define HICN_HASH_NODE_FLAGS_DEFAULT 0x00
166 #define HICN_HASH_NODE_CS_FLAGS 0x01
167 #define HICN_HASH_NODE_OVERFLOW_BUCKET 0x02
177 typedef struct __attribute__ ((packed)) hicn_hash_entry_s
206 STATIC_ASSERT (
sizeof (index_t) <= 4,
"sizeof index_t is greater than 4B");
208 #define HICN_HASH_ENTRY_FLAGS_DEFAULT 0x00
211 #define HICN_HASH_ENTRY_FLAG_CS_ENTRY 0x01
218 #define HICN_HASH_ENTRY_FLAG_OVERFLOW 0x04
221 #define HICN_HASH_ENTRY_FLAG_DELETED 0x08
224 #define HICN_HASH_ENTRY_FLAG_FAST_TIMEOUT 0x10
236 #define HICN_HASHTB_BUCKET_ENTRIES 5
238 typedef struct __attribute__ ((packed))
240 hicn_hash_entry_t hb_entries[HICN_HASHTB_BUCKET_ENTRIES];
244 } hicn_hash_bucket_t;
247 #define HICN_HASHTB_FILL_FACTOR 4
249 #define HICN_HASHTB_MIN_ENTRIES (1 << 4) // includes dummy node 0 entry
250 #define HICN_HASHTB_MAX_ENTRIES (1 << 24)
252 #define HICN_HASHTB_MIN_BUCKETS (1 << 10)
267 hicn_hash_bucket_t *ht_buckets;
270 hicn_hash_bucket_t *ht_overflow_buckets;
273 hicn_hash_node_t *ht_nodes;
282 u32 ht_overflow_bucket_count;
283 u32 ht_overflow_buckets_used;
299 extern u32 ht_node_data_offset_aligned;
303 #define HICN_HASHTB_FLAGS_DEFAULT 0x00
311 #define HICN_HASHTB_FLAG_USE_SEVEN 0x04
312 #define HICN_HASHTB_FLAG_KEY_FMT_PFX 0x08
313 #define HICN_HASHTB_FLAG_KEY_FMT_NAME 0x10
319 #define HICN_HASHTB_MAX_NAME_COMPS HICN_PARAM_FIB_ENTRY_PFX_COMPS_MAX
327 hicn_hashtb_node_idx_from_node (
hicn_hashtb_h h, hicn_hash_node_t *p)
329 return (p - h->ht_nodes);
333 static inline hicn_hash_node_t *
336 return (pool_elt_at_index (h->ht_nodes, idx));
340 int hicn_hashtb_alloc (
hicn_hashtb_h *ph, u32 max_elems,
size_t app_data_size);
346 u64 hicn_hashtb_hash_bytestring (
const u8 *key, u32 keylen);
348 always_inline hicn_hash_entry_t *
349 hicn_hashtb_get_entry (
hicn_hashtb_h h, u32 entry_idx, u32 bucket_id,
352 hicn_hash_bucket_t *bucket;
354 bucket = pool_elt_at_index (h->ht_overflow_buckets, bucket_id);
356 bucket = (hicn_hash_bucket_t *) (h->ht_buckets + bucket_id);
358 return &(bucket->hb_entries[entry_idx]);
363 hicn_hashtb_hash_name (
const u8 *key, u16 keylen)
365 if (key != NULL && keylen == HICN_V4_NAME_LEN)
367 clib_bihash_kv_8_8_t kv;
368 kv.key = ((u64 *) key)[0];
369 return clib_bihash_hash_8_8 (&kv);
371 else if (key != NULL && keylen == HICN_V6_NAME_LEN)
373 clib_bihash_kv_24_8_t kv;
374 kv.key[0] = ((u64 *) key)[0];
375 kv.key[1] = ((u64 *) key)[1];
376 kv.key[2] = ((u32 *) key)[4];
377 return clib_bihash_hash_24_8 (&kv);
390 void hicn_hashtb_init_node (
hicn_hashtb_h h, hicn_hash_node_t *node,
391 const u8 *key, u32 keylen);
398 int hicn_hashtb_insert (
hicn_hashtb_h h, hicn_hash_node_t *node,
399 hicn_hash_entry_t **hash_entry, u64 hash, u32 *node_id,
400 index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs,
401 u8 *hash_entry_id, u32 *bucket_id,
402 u8 *bucket_is_overflow);
411 int hicn_hashtb_lookup_node (
hicn_hashtb_h h,
const u8 *key, u32 keylen,
412 u64 hashval, u8 is_data, u32 *node_id,
413 index_t *dpo_ctx_id, u8 *vft_id, u8 *is_cs,
414 u8 *hash_entry_id, u32 *bucket_id,
415 u8 *bucket_is_overflow);
427 int hicn_hashtb_lookup_node_ex (
hicn_hashtb_h h,
const u8 *key, u32 keylen,
428 u64 hashval, u8 is_data,
int include_deleted_p,
429 u32 *node_id, index_t *dpo_ctx_id, u8 *vft_id,
430 u8 *is_cs, u8 *hash_entry_id, u32 *bucket_id,
431 u8 *bucket_is_overflow);
447 void hicn_hashtb_remove_node (
hicn_hashtb_h h, hicn_hash_node_t *node,
454 void hicn_hashtb_delete (
hicn_hashtb_h h, hicn_hash_node_t **pnode,
461 void hicn_hashtb_init_entry (hicn_hash_entry_t *entry, u32 nodeidx,
462 u64 hashval, u32 locks);
470 hicn_hashtb_node_data (hicn_hash_node_t *node)
472 return ((u8 *) (node) + ht_node_data_offset_aligned);
482 return ((u32) (hashval & (h->ht_bucket_count - 1)));
489 static inline hicn_hash_node_t *
492 hicn_hash_node_t *p = NULL;
494 if (h->ht_nodes_used < h->ht_node_count)
496 pool_get_aligned (h->ht_nodes, p, 8);
505 void hicn_hashtb_free_node (
hicn_hashtb_h h, hicn_hash_node_t *node);
513 int hicn_hashtb_next_node (
hicn_hashtb_h h, hicn_hash_node_t **pnode,
516 int hicn_hashtb_key_to_str (
hicn_hashtb_h h,
const hicn_hash_node_t *node,
517 char *buf,
int bufsize,
int must_fit);
524 hicn_hashtb_fullhash (
const u8 *name, u16 namelen, u64 *name_hash)
526 *name_hash = hicn_hashtb_hash_name (name, namelen);
527 return (*name_hash != (-1LL) ? HICN_ERROR_NONE : HICN_ERROR_HASHTB_INVAL);