17 #ifndef included_clib_pfhash_h 18 #define included_clib_pfhash_h 25 #if defined(CLIB_HAVE_VEC128) && ! defined (__ALTIVEC__) 73 pfhash_kv_8v8_t kv8v8;
80 #define PFHASH_BUCKET_OVERFLOW (u32)~0 86 uword * overflow_hash;
96 u32 nitems_in_overflow;
99 void pfhash_init (pfhash_t * p,
char * name,
u32 key_size,
u32 value_size,
101 void pfhash_free (pfhash_t * p);
102 u64 pfhash_get (pfhash_t * p,
u32 bucket,
void * key);
103 void pfhash_set (pfhash_t * p,
u32 bucket,
void * key,
void * value);
104 void pfhash_unset (pfhash_t * p,
u32 bucket,
void * key);
108 static inline void pfhash_prefetch_bucket (pfhash_t * p,
u32 bucket)
111 static inline u32 pfhash_read_bucket_prefetch_kv (pfhash_t * p,
u32 bucket)
113 u32 bucket_contents = p->buckets[bucket];
114 if (
PREDICT_TRUE ((bucket_contents & PFHASH_BUCKET_OVERFLOW) == 0))
116 return bucket_contents;
128 static inline u32 pfhash_search_kv_16 (pfhash_t * p,
u32 bucket_contents,
131 u32x4 diff0, diff1, diff2;
132 u32 is_equal0, is_equal1, is_equal2;
137 if (
PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW))
146 kv = &p->kvp[bucket_contents].kv16;
148 diff0 = u32x4_sub (kv->kb.k_u32x4[0], key[0]);
149 diff1 = u32x4_sub (kv->kb.k_u32x4[1], key[0]);
150 diff2 = u32x4_sub (kv->kb.k_u32x4[2], key[0]);
154 no_match |= is_equal1;
156 no_match |= is_equal2;
158 no_match = ~no_match;
160 rv = (is_equal0 & kv->values[0])
161 |(is_equal1 & kv->values[1])
162 | (is_equal2 & kv->values[2])
168 static inline u32 pfhash_search_kv_8 (pfhash_t * p,
u32 bucket_contents,
174 if (
PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW))
183 kv = &p->kvp[bucket_contents].kv8;
185 rv = (kv->kb.k_u64[0] == key[0]) ? kv->values[0] : rv;
186 rv = (kv->kb.k_u64[1] == key[0]) ? kv->values[1] : rv;
187 rv = (kv->kb.k_u64[2] == key[0]) ? kv->values[2] : rv;
188 rv = (kv->kb.k_u64[3] == key[0]) ? kv->values[3] : rv;
189 rv = (kv->kb.k_u64[4] == key[0]) ? kv->values[4] : rv;
194 static inline u64 pfhash_search_kv_8v8 (pfhash_t * p,
u32 bucket_contents,
200 if (
PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW))
209 kv = &p->kvp[bucket_contents].kv8v8;
211 rv = (kv->kb.k_u64[0] == key[0]) ? kv->values[0] : rv;
212 rv = (kv->kb.k_u64[1] == key[0]) ? kv->values[1] : rv;
213 rv = (kv->kb.k_u64[2] == key[0]) ? kv->values[2] : rv;
214 rv = (kv->kb.k_u64[3] == key[0]) ? kv->values[3] : rv;
219 static inline u32 pfhash_search_kv_4 (pfhash_t * p,
u32 bucket_contents,
224 u32 zbm[2], winner_index;
227 if (
PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW))
236 kv = &p->kvp[bucket_contents].kv4;
248 winner_index =
min_log2 (zbm[0])>>2;
249 winner_index = zbm[1] ? (4 + (
min_log2 (zbm[1])>>2)) : winner_index;
251 return kv->values[winner_index];
always_inline u32x4 u32x4_is_equal(u32x4 x, u32x4 y)
always_inline u32 u32x4_zero_byte_mask(u32x4 x)
always_inline u32x4 u32x4_splat(u32 a)
#define CLIB_PREFETCH(addr, size, type)
#define hash_get_mem(h, key)
always_inline uword min_log2(uword x)
#define CLIB_CACHE_LINE_BYTES