|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
28 #ifndef __included_cuckoo_template_h__
29 #define __included_cuckoo_template_h__
39 #ifndef CLIB_CUCKOO_TYPE
40 #error CLIB_CUCKOO_TYPE not defined
43 #ifndef CLIB_CUCKOO_BFS_MAX_STEPS
44 #error CLIB_CUCKOO_BFS_MAX_STEPS not defined
47 #ifndef CLIB_CUCKOO_KVP_PER_BUCKET
48 #error CLIB_CUCKOO_KVP_PER_BUCKET not defined
51 #ifndef CLIB_CUCKOO_LOG2_KVP_PER_BUCKET
52 #error CLIB_CUCKOO_LOG2_KVP_PER_BUCKET not defined
55 #ifndef CLIB_CUCKOO_BFS_MAX_PATH_LENGTH
56 #error CLIB_CUCKOO_BFS_MAX_PATH_LENGTH not defined
61 "CLIB_CUCKOO_KVP_PER_BUCKET != (1 << CLIB_CUCKOO_LOG2_KVP_PER_BUCKET");
63 #define _cv(a, b) a##b
64 #define __cv(a, b) _cv (a, b)
65 #define CV(a) __cv (a, CLIB_CUCKOO_TYPE)
67 #define _cvt(a, b) a##b##_t
68 #define __cvt(a, b) _cvt (a, b)
69 #define CVT(a) __cvt (a, CLIB_CUCKOO_TYPE)
73 #define CLIB_CUCKOO_USE_COUNT_BIT_WIDTH (1 + CLIB_CUCKOO_LOG2_KVP_PER_BUCKET)
85 return (aux >> 1) & use_count_mask;
98 (use_count << 1) + writer_flag;
127 #define PATH_BITS_REQ \
128 (CLIB_CUCKOO_BFS_MAX_PATH_LENGTH * CLIB_CUCKOO_LOG2_KVP_PER_BUCKET)
130 #if PATH_BITS_REQ <= 8
132 #elif PATH_BITS_REQ <= 16
134 #elif PATH_BITS_REQ <= 32
136 #elif PATH_BITS_REQ <= 64
139 #error no suitable datatype for path storage...
166 }
CVT (clib_cuckoo_bucket);
168 #define clib_cuckoo_bucket_foreach_idx(var) \
169 for (var = 0; var < CLIB_CUCKOO_KVP_PER_BUCKET; var++)
171 #if CLIB_CUCKOO_OPTIMIZE_UNROLL
172 #if CLIB_CUCKOO_KVP_PER_BUCKET == 2
173 #define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
182 #elif CLIB_CUCKOO_KVP_PER_BUCKET == 4
183 #define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
196 #elif CLIB_CUCKOO_KVP_PER_BUCKET == 8
197 #define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
219 #define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
220 clib_cuckoo_bucket_foreach_idx (var) \
226 #define clib_cuckoo_bucket_foreach_idx_unrolled(var, body) \
227 clib_cuckoo_bucket_foreach_idx (var) \
233 #define clib_cuckoo_bucket_foreach_elt_index(var, bucket) \
234 for (var = 0; var < CLIB_CUCKOO_KVP_PER_BUCKET; ++i)
236 #define clib_cuckoo_foreach_bucket(var, h, body) \
239 CVT (clib_cuckoo_bucket) *__buckets = h->buckets; \
240 vec_foreach (var, __buckets) \
247 typedef struct CV (clib_cuckoo)
250 CVT (clib_cuckoo_bucket) *
volatile buckets;
253 CVT (clib_cuckoo_bucket) * *to_be_freed;
265 uword *bfs_search_queue;
280 void (*garbage_callback) (
struct CV (clib_cuckoo) *
h,
void *garbage_ctx);
282 #if CLIB_CUCKOO_DEBUG_COUNTERS
284 u64 bfs_queue_emptied;
294 void (*garbage_callback) (
CVT (clib_cuckoo) *,
303 CVT (clib_cuckoo_kv) * add_v,
int is_add,
306 CVT (clib_cuckoo_kv) * search_v,
307 CVT (clib_cuckoo_kv) * return_v);
310 void *callback,
void *arg);
320 u32 v32 = ((
u32) hash) ^ ((
u32) (hash >> 32));
321 u16 v16 = ((
u16) v32) ^ ((
u16) (v32 >> 16));
322 u8 v8 = ((
u8) v16) ^ ((
u8) (v16 >> 8));
330 return (bucket ^ ((reduced_hash + 1) * 0xc6a4a7935bd1e995)) &
mask;
340 #if CLIB_CUCKOO_OPTIMIZE_PREFETCH
342 sizeof (*buckets), LOAD);
347 #if CLIB_CUCKOO_OPTIMIZE_PREFETCH
349 sizeof (*buckets), LOAD);
351 lookup.reduced_hash = reduced_hash;
362 CVT (clib_cuckoo_kv) * kvp,
375 #if CLIB_CUCKOO_OPTIMIZE_USE_COUNT_LIMITS_SEARCH
380 #if CLIB_CUCKOO_OPTIMIZE_USE_COUNT_LIMITS_SEARCH
386 if (
CV (clib_cuckoo_key_compare) (kvp->key,
b->elts[
i].key))
388 kvp->value = b->elts[i].value;
389 clib_cuckoo_bucket_aux_t bucket_aux2 = b->aux;
390 if (PREDICT_TRUE (clib_cuckoo_bucket_aux_get_version (bucket_aux) ==
391 clib_cuckoo_bucket_aux_get_version (bucket_aux2)))
394 return CLIB_CUCKOO_ERROR_SUCCESS;
399 return CLIB_CUCKOO_ERROR_AGAIN;
404 return CLIB_CUCKOO_ERROR_NOT_FOUND;
409 CVT (clib_cuckoo_kv) * kvp)
411 CVT (clib_cuckoo_bucket) * buckets =
h->buckets;
412 uword bucket1, bucket2;
418 bucket1 = hash &
mask;
425 if (
rv == CLIB_CUCKOO_ERROR_SUCCESS)
426 return CLIB_CUCKOO_ERROR_SUCCESS;
444 CVT (clib_cuckoo_kv) * kvp)
446 u64 hash =
CV (clib_cuckoo_hash) (kvp);
u64 clib_cuckoo_bucket_aux_t
static u64 clib_cuckoo_get_other_bucket(u64 nbuckets, u64 bucket, u8 reduced_hash)
void CV() clib_cuckoo_garbage_collect(CVT(clib_cuckoo) *h)
perform garbage collection
u64 start
bucket where this path begins
static int clib_cuckoo_bucket_aux_get_writer_flag(clib_cuckoo_bucket_aux_t aux)
u8 length
length of the path
#define CLIB_CACHE_LINE_ALIGN_MARK(mark)
path_data_t data
holds compressed offsets in buckets along path
static hash_pair_t * lookup(void *v, uword key, enum lookup_opcode op, void *new_value, void *old_value)
#define CLIB_CUCKOO_KVP_PER_BUCKET
u64 bucket
bucket at end of path
STATIC_ASSERT(CLIB_CUCKOO_KVP_PER_BUCKET==(1<< CLIB_CUCKOO_LOG2_KVP_PER_BUCKET), "CLIB_CUCKOO_KVP_PER_BUCKET != (1 << CLIB_CUCKOO_LOG2_KVP_PER_BUCKET")
void CV() clib_cuckoo_free(CVT(clib_cuckoo) *h)
#define clib_cuckoo_bucket_foreach_idx_unrolled(var, body)
static clib_cuckoo_bucket_aux_t clib_cuckoo_bucket_aux_pack(u64 version, int use_count, int writer_flag)
static clib_cuckoo_lookup_info_t CV() clib_cuckoo_calc_lookup(CVT(clib_cuckoo_bucket) *buckets, u64 hash)
#define CLIB_CUCKOO_USE_COUNT_BIT_WIDTH
static int CV() clib_cuckoo_bucket_search(CVT(clib_cuckoo_bucket) *b, CVT(clib_cuckoo_kv) *kvp, u8 reduced_hash)
search for key within bucket
void CV() clib_cuckoo_init(CVT(clib_cuckoo) *h, const char *name, uword nbuckets, void(*garbage_callback)(CVT(clib_cuckoo) *, void *), void *garbage_ctx)
#define CLIB_PREFETCH(addr, size, type)
static int clib_cuckoo_bucket_aux_get_use_count(clib_cuckoo_bucket_aux_t aux)
#define CLIB_CUCKOO_LOG2_KVP_PER_BUCKET
static u8 clib_cuckoo_reduce_hash(u64 hash)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void CV() clib_cuckoo_foreach_key_value_pair(CVT(clib_cuckoo) *h, void *callback, void *arg)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Fixed length block allocator. Pools are built from clib vectors and bitmaps. Use pools when repeatedl...
sll srl srl sll sra u16x4 i
static u64 clib_cuckoo_bucket_aux_get_version(clib_cuckoo_bucket_aux_t aux)
volatile clib_cuckoo_bucket_aux_t aux
auxiliary data - version, writer flag and used count
static clib_cuckoo_bucket_aux_t clib_cuckoo_bucket_aux_set_writer_flag(clib_cuckoo_bucket_aux_t aux, int writer_flag)
static clib_cuckoo_bucket_aux_t clib_cuckoo_bucket_aux_set_version(clib_cuckoo_bucket_aux_t aux, u64 version)
float CV() clib_cuckoo_calc_load(CVT(clib_cuckoo) *h)
static int CV() clib_cuckoo_search_inline_with_hash(CVT(clib_cuckoo) *h, u64 hash, CVT(clib_cuckoo_kv) *kvp)
static int CV() clib_cuckoo_search_inline(CVT(clib_cuckoo) *h, CVT(clib_cuckoo_kv) *kvp)
static clib_cuckoo_bucket_aux_t clib_cuckoo_bucket_aux_set_use_count(clib_cuckoo_bucket_aux_t aux, int use_count)
u8 *CV() format_cuckoo(u8 *s, va_list *args)
int CV() clib_cuckoo_search(CVT(clib_cuckoo) *h, CVT(clib_cuckoo_kv) *search_v, CVT(clib_cuckoo_kv) *return_v)
int CV() clib_cuckoo_add_del(CVT(clib_cuckoo) *h, CVT(clib_cuckoo_kv) *add_v, int is_add, int dont_overwrite)