hash: allow to store data in hash table
[dpdk.git] / lib / librte_hash / rte_cuckoo_hash.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <string.h>
35 #include <stdint.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <sys/queue.h>
40
41 #include <rte_common.h>
42 #include <rte_memory.h>         /* for definition of RTE_CACHE_LINE_SIZE */
43 #include <rte_log.h>
44 #include <rte_memcpy.h>
45 #include <rte_prefetch.h>
46 #include <rte_branch_prediction.h>
47 #include <rte_memzone.h>
48 #include <rte_malloc.h>
49 #include <rte_eal.h>
50 #include <rte_eal_memconfig.h>
51 #include <rte_per_lcore.h>
52 #include <rte_errno.h>
53 #include <rte_string_fns.h>
54 #include <rte_cpuflags.h>
55 #include <rte_log.h>
56 #include <rte_rwlock.h>
57 #include <rte_spinlock.h>
58 #include <rte_ring.h>
59 #include <rte_compat.h>
60
61 #include "rte_hash.h"
62
63 TAILQ_HEAD(rte_hash_list, rte_tailq_entry);
64
65 static struct rte_tailq_elem rte_hash_tailq = {
66         .name = "RTE_HASH",
67 };
68 EAL_REGISTER_TAILQ(rte_hash_tailq)
69
70 /* Macro to enable/disable run-time checking of function parameters */
71 #if defined(RTE_LIBRTE_HASH_DEBUG)
72 #define RETURN_IF_TRUE(cond, retval) do { \
73         if (cond) \
74                 return retval; \
75 } while (0)
76 #else
77 #define RETURN_IF_TRUE(cond, retval)
78 #endif
79
80 /* Hash function used if none is specified */
81 #ifdef RTE_MACHINE_CPUFLAG_SSE4_2
82 #include <rte_hash_crc.h>
83 #define DEFAULT_HASH_FUNC       rte_hash_crc
84 #else
85 #include <rte_jhash.h>
86 #define DEFAULT_HASH_FUNC       rte_jhash
87 #endif
88
89 /** Number of items per bucket. */
90 #define RTE_HASH_BUCKET_ENTRIES         4
91
92 #define NULL_SIGNATURE                  0
93
94 #define KEY_ALIGNMENT                   16
95
96 typedef int (*rte_hash_cmp_eq_t)(const void *key1, const void *key2, size_t key_len);
97 static int rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len);
98 static int rte_hash_k32_cmp_eq(const void *key1, const void *key2, size_t key_len);
99 static int rte_hash_k48_cmp_eq(const void *key1, const void *key2, size_t key_len);
100 static int rte_hash_k64_cmp_eq(const void *key1, const void *key2, size_t key_len);
101 static int rte_hash_k80_cmp_eq(const void *key1, const void *key2, size_t key_len);
102 static int rte_hash_k96_cmp_eq(const void *key1, const void *key2, size_t key_len);
103 static int rte_hash_k112_cmp_eq(const void *key1, const void *key2, size_t key_len);
104 static int rte_hash_k128_cmp_eq(const void *key1, const void *key2, size_t key_len);
105
106 /** A hash table structure. */
107 struct rte_hash {
108         char name[RTE_HASH_NAMESIZE];   /**< Name of the hash. */
109         uint32_t entries;               /**< Total table entries. */
110         uint32_t num_buckets;           /**< Number of buckets in table. */
111         uint32_t key_len;               /**< Length of hash key. */
112         rte_hash_function hash_func;    /**< Function used to calculate hash. */
113         rte_hash_cmp_eq_t rte_hash_cmp_eq; /**< Function used to compare keys. */
114         uint32_t hash_func_init_val;    /**< Init value used by hash_func. */
115         uint32_t bucket_bitmask;        /**< Bitmask for getting bucket index
116                                                 from hash signature. */
117         uint32_t key_entry_size;         /**< Size of each key entry. */
118
119         struct rte_ring *free_slots;    /**< Ring that stores all indexes
120                                                 of the free slots in the key table */
121         void *key_store;                /**< Table storing all keys and data */
122         struct rte_hash_bucket *buckets;        /**< Table with buckets storing all the
123                                                         hash values and key indexes
124                                                         to the key table*/
125 } __rte_cache_aligned;
126
127 /* Structure storing both primary and secondary hashes */
128 struct rte_hash_signatures {
129         union {
130                 struct {
131                         hash_sig_t current;
132                         hash_sig_t alt;
133                 };
134                 uint64_t sig;
135         };
136 };
137
138 /* Structure that stores key-value pair */
139 struct rte_hash_key {
140         union {
141                 uintptr_t idata;
142                 void *pdata;
143         };
144         /* Variable key size */
145         char key[];
146 } __attribute__((aligned(KEY_ALIGNMENT)));
147
148 /** Bucket structure */
149 struct rte_hash_bucket {
150         struct rte_hash_signatures signatures[RTE_HASH_BUCKET_ENTRIES];
151         /* Includes dummy key index that always contains index 0 */
152         uint32_t key_idx[RTE_HASH_BUCKET_ENTRIES + 1];
153         uint8_t flag[RTE_HASH_BUCKET_ENTRIES];
154 } __rte_cache_aligned;
155
156 struct rte_hash *
157 rte_hash_find_existing(const char *name)
158 {
159         struct rte_hash *h = NULL;
160         struct rte_tailq_entry *te;
161         struct rte_hash_list *hash_list;
162
163         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
164
165         rte_rwlock_read_lock(RTE_EAL_TAILQ_RWLOCK);
166         TAILQ_FOREACH(te, hash_list, next) {
167                 h = (struct rte_hash *) te->data;
168                 if (strncmp(name, h->name, RTE_HASH_NAMESIZE) == 0)
169                         break;
170         }
171         rte_rwlock_read_unlock(RTE_EAL_TAILQ_RWLOCK);
172
173         if (te == NULL) {
174                 rte_errno = ENOENT;
175                 return NULL;
176         }
177         return h;
178 }
179
180 struct rte_hash *
181 rte_hash_create(const struct rte_hash_parameters *params)
182 {
183         struct rte_hash *h = NULL;
184         struct rte_tailq_entry *te = NULL;
185         struct rte_hash_list *hash_list;
186         struct rte_ring *r = NULL;
187         char hash_name[RTE_HASH_NAMESIZE];
188         void *ptr, *k = NULL;
189         void *buckets = NULL;
190         char ring_name[RTE_RING_NAMESIZE];
191         unsigned i;
192
193         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
194
195         if (params == NULL) {
196                 RTE_LOG(ERR, HASH, "rte_hash_create has no parameters\n");
197                 return NULL;
198         }
199
200         /* Check for valid parameters */
201         if ((params->entries > RTE_HASH_ENTRIES_MAX) ||
202                         (params->entries < RTE_HASH_BUCKET_ENTRIES) ||
203                         !rte_is_power_of_2(RTE_HASH_BUCKET_ENTRIES) ||
204                         (params->key_len == 0)) {
205                 rte_errno = EINVAL;
206                 RTE_LOG(ERR, HASH, "rte_hash_create has invalid parameters\n");
207                 return NULL;
208         }
209
210         snprintf(hash_name, sizeof(hash_name), "HT_%s", params->name);
211
212         /* Guarantee there's no existing */
213         h = rte_hash_find_existing(params->name);
214         if (h != NULL)
215                 return h;
216
217         te = rte_zmalloc("HASH_TAILQ_ENTRY", sizeof(*te), 0);
218         if (te == NULL) {
219                 RTE_LOG(ERR, HASH, "tailq entry allocation failed\n");
220                 goto err;
221         }
222
223         h = (struct rte_hash *)rte_zmalloc_socket(hash_name, sizeof(struct rte_hash),
224                                         RTE_CACHE_LINE_SIZE, params->socket_id);
225
226         if (h == NULL) {
227                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
228                 goto err;
229         }
230
231         const uint32_t num_buckets = rte_align32pow2(params->entries)
232                                         / RTE_HASH_BUCKET_ENTRIES;
233
234         buckets = rte_zmalloc_socket(NULL,
235                                 num_buckets * sizeof(struct rte_hash_bucket),
236                                 RTE_CACHE_LINE_SIZE, params->socket_id);
237
238         if (buckets == NULL) {
239                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
240                 goto err;
241         }
242
243         const uint32_t key_entry_size = sizeof(struct rte_hash_key) + params->key_len;
244
245         /* Store all keys and leave the first entry as a dummy entry for lookup_bulk */
246         const uint64_t key_tbl_size = key_entry_size * (params->entries + 1);
247
248         k = rte_zmalloc_socket(NULL, key_tbl_size,
249                         RTE_CACHE_LINE_SIZE, params->socket_id);
250
251         if (k == NULL) {
252                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
253                 goto err;
254         }
255
256         /* Select function to compare keys */
257         switch (params->key_len) {
258         case 16:
259                 h->rte_hash_cmp_eq = rte_hash_k16_cmp_eq;
260                 break;
261         case 32:
262                 h->rte_hash_cmp_eq = rte_hash_k32_cmp_eq;
263                 break;
264         case 48:
265                 h->rte_hash_cmp_eq = rte_hash_k48_cmp_eq;
266                 break;
267         case 64:
268                 h->rte_hash_cmp_eq = rte_hash_k64_cmp_eq;
269                 break;
270         case 80:
271                 h->rte_hash_cmp_eq = rte_hash_k80_cmp_eq;
272                 break;
273         case 96:
274                 h->rte_hash_cmp_eq = rte_hash_k96_cmp_eq;
275                 break;
276         case 112:
277                 h->rte_hash_cmp_eq = rte_hash_k112_cmp_eq;
278                 break;
279         case 128:
280                 h->rte_hash_cmp_eq = rte_hash_k128_cmp_eq;
281                 break;
282         default:
283                 /* If key is not multiple of 16, use generic memcmp */
284                 h->rte_hash_cmp_eq = memcmp;
285         }
286
287         snprintf(ring_name, sizeof(ring_name), "HT_%s", params->name);
288         r = rte_ring_lookup(ring_name);
289         if (r != NULL) {
290                 /* clear the free ring */
291                 while (rte_ring_dequeue(r, &ptr) == 0)
292                         rte_pause();
293         } else
294                 r = rte_ring_create(ring_name, rte_align32pow2(params->entries + 1),
295                                 params->socket_id, 0);
296         if (r == NULL) {
297                 RTE_LOG(ERR, HASH, "memory allocation failed\n");
298                 goto err;
299         }
300
301         /* Setup hash context */
302         snprintf(h->name, sizeof(h->name), "%s", params->name);
303         h->entries = params->entries;
304         h->key_len = params->key_len;
305         h->key_entry_size = key_entry_size;
306         h->hash_func_init_val = params->hash_func_init_val;
307
308         h->num_buckets = num_buckets;
309         h->bucket_bitmask = h->num_buckets - 1;
310         h->buckets = buckets;
311         h->hash_func = (params->hash_func == NULL) ?
312                 DEFAULT_HASH_FUNC : params->hash_func;
313
314         h->key_store = k;
315         h->free_slots = r;
316
317         /* populate the free slots ring. Entry zero is reserved for key misses */
318         for (i = 1; i < params->entries + 1; i++)
319                 rte_ring_sp_enqueue(r, (void *)((uintptr_t) i));
320
321         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
322         te->data = (void *) h;
323         TAILQ_INSERT_TAIL(hash_list, te, next);
324         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
325
326         return h;
327 err:
328         rte_free(te);
329         rte_free(h);
330         rte_free(buckets);
331         rte_free(k);
332         return NULL;
333 }
334
335 void
336 rte_hash_free(struct rte_hash *h)
337 {
338         struct rte_tailq_entry *te;
339         struct rte_hash_list *hash_list;
340
341         if (h == NULL)
342                 return;
343
344         hash_list = RTE_TAILQ_CAST(rte_hash_tailq.head, rte_hash_list);
345
346         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
347
348         /* find out tailq entry */
349         TAILQ_FOREACH(te, hash_list, next) {
350                 if (te->data == (void *) h)
351                         break;
352         }
353
354         if (te == NULL) {
355                 rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
356                 return;
357         }
358
359         TAILQ_REMOVE(hash_list, te, next);
360
361         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
362
363         rte_free(h->key_store);
364         rte_free(h->buckets);
365         rte_free(h);
366         rte_free(te);
367 }
368
369 hash_sig_t
370 rte_hash_hash(const struct rte_hash *h, const void *key)
371 {
372         /* calc hash result by key */
373         return h->hash_func(key, h->key_len, h->hash_func_init_val);
374 }
375
376 /* Calc the secondary hash value from the primary hash value of a given key */
377 static inline hash_sig_t
378 rte_hash_secondary_hash(const hash_sig_t primary_hash)
379 {
380         static const unsigned all_bits_shift = 12;
381         static const unsigned alt_bits_xor = 0x5bd1e995;
382
383         uint32_t tag = primary_hash >> all_bits_shift;
384
385         return (primary_hash ^ ((tag + 1) * alt_bits_xor));
386 }
387
388 void
389 rte_hash_reset(struct rte_hash *h)
390 {
391         void *ptr;
392         unsigned i;
393
394         if (h == NULL)
395                 return;
396
397         memset(h->buckets, 0, h->num_buckets * sizeof(struct rte_hash_bucket));
398         memset(h->key_store, 0, h->key_entry_size * (h->entries + 1));
399
400         /* clear the free ring */
401         while (rte_ring_dequeue(h->free_slots, &ptr) == 0)
402                 rte_pause();
403
404         /* Repopulate the free slots ring. Entry zero is reserved for key misses */
405         for (i = 1; i < h->entries + 1; i++)
406                 rte_ring_sp_enqueue(h->free_slots, (void *)((uintptr_t) i));
407 }
408
409 /* Search for an entry that can be pushed to its alternative location */
410 static inline int
411 make_space_bucket(const struct rte_hash *h, struct rte_hash_bucket *bkt)
412 {
413         unsigned i, j;
414         int ret;
415         uint32_t next_bucket_idx;
416         struct rte_hash_bucket *next_bkt[RTE_HASH_BUCKET_ENTRIES];
417
418         /*
419          * Push existing item (search for bucket with space in
420          * alternative locations) to its alternative location
421          */
422         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
423                 /* Search for space in alternative locations */
424                 next_bucket_idx = bkt->signatures[i].alt & h->bucket_bitmask;
425                 next_bkt[i] = &h->buckets[next_bucket_idx];
426                 for (j = 0; j < RTE_HASH_BUCKET_ENTRIES; j++) {
427                         if (next_bkt[i]->signatures[j].sig == NULL_SIGNATURE)
428                                 break;
429                 }
430
431                 if (j != RTE_HASH_BUCKET_ENTRIES)
432                         break;
433         }
434
435         /* Alternative location has spare room (end of recursive function) */
436         if (i != RTE_HASH_BUCKET_ENTRIES) {
437                 next_bkt[i]->signatures[j].alt = bkt->signatures[i].current;
438                 next_bkt[i]->signatures[j].current = bkt->signatures[i].alt;
439                 next_bkt[i]->key_idx[j] = bkt->key_idx[i];
440                 return i;
441         }
442
443         /* Pick entry that has not been pushed yet */
444         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++)
445                 if (bkt->flag[i] == 0)
446                         break;
447
448         /* All entries have been pushed, so entry cannot be added */
449         if (i == RTE_HASH_BUCKET_ENTRIES) {
450                 /* Reset flag */
451                 bkt->flag[i] = 0;
452                 return -ENOSPC;
453         }
454
455         /* Set flag to indicate that this entry is going to be pushed */
456         bkt->flag[i] = 1;
457         /* Need room in alternative bucket to insert the pushed entry */
458         ret = make_space_bucket(h, next_bkt[i]);
459         /*
460          * After recursive function.
461          * Clear flags and insert the pushed entry
462          * in its alternative location if successful,
463          * or return error
464          */
465         bkt->flag[i] = 0;
466         if (ret >= 0) {
467                 next_bkt[i]->signatures[ret].alt = bkt->signatures[i].current;
468                 next_bkt[i]->signatures[ret].current = bkt->signatures[i].alt;
469                 next_bkt[i]->key_idx[ret] = bkt->key_idx[i];
470                 return i;
471         } else
472                 return ret;
473
474 }
475
476 static inline int32_t
477 __rte_hash_add_key_with_hash(const struct rte_hash *h, const void *key,
478                                                 hash_sig_t sig, void *data)
479 {
480         hash_sig_t alt_hash;
481         uint32_t prim_bucket_idx, sec_bucket_idx;
482         unsigned i;
483         struct rte_hash_bucket *prim_bkt, *sec_bkt;
484         struct rte_hash_key *new_k, *k, *keys = h->key_store;
485         void *slot_id;
486         uint32_t new_idx;
487         int ret;
488
489         prim_bucket_idx = sig & h->bucket_bitmask;
490         prim_bkt = &h->buckets[prim_bucket_idx];
491         rte_prefetch0(prim_bkt);
492
493         alt_hash = rte_hash_secondary_hash(sig);
494         sec_bucket_idx = alt_hash & h->bucket_bitmask;
495         sec_bkt = &h->buckets[sec_bucket_idx];
496         rte_prefetch0(sec_bkt);
497
498         /* Get a new slot for storing the new key */
499         if (rte_ring_sc_dequeue(h->free_slots, &slot_id) != 0)
500                 return -ENOSPC;
501         new_k = RTE_PTR_ADD(keys, (uintptr_t)slot_id * h->key_entry_size);
502         rte_prefetch0(new_k);
503         new_idx = (uint32_t)((uintptr_t) slot_id);
504
505         /* Check if key is already inserted in primary location */
506         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
507                 if (prim_bkt->signatures[i].current == sig &&
508                                 prim_bkt->signatures[i].alt == alt_hash)  {
509                         k = (struct rte_hash_key *) ((char *)keys +
510                                         prim_bkt->key_idx[i] * h->key_entry_size);
511                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
512                                 rte_ring_sp_enqueue(h->free_slots, &slot_id);
513                                 /* Update data */
514                                 k->pdata = data;
515                                 /*
516                                  * Return index where key is stored,
517                                  * substracting the first dummy index
518                                  */
519                                 return (prim_bkt->key_idx[i] - 1);
520                         }
521                 }
522         }
523
524         /* Check if key is already inserted in secondary location */
525         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
526                 if (sec_bkt->signatures[i].alt == sig &&
527                                 sec_bkt->signatures[i].current == alt_hash)  {
528                         k = (struct rte_hash_key *) ((char *)keys +
529                                         sec_bkt->key_idx[i] * h->key_entry_size);
530                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
531                                 rte_ring_sp_enqueue(h->free_slots, &slot_id);
532                                 /* Update data */
533                                 k->pdata = data;
534                                 /*
535                                  * Return index where key is stored,
536                                  * substracting the first dummy index
537                                  */
538                                 return (sec_bkt->key_idx[i] - 1);
539                         }
540                 }
541         }
542
543         /* Copy key */
544         rte_memcpy(new_k->key, key, h->key_len);
545         new_k->pdata = data;
546
547         /* Insert new entry is there is room in the primary bucket */
548         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
549                 /* Check if slot is available */
550                 if (likely(prim_bkt->signatures[i].sig == NULL_SIGNATURE)) {
551                         prim_bkt->signatures[i].current = sig;
552                         prim_bkt->signatures[i].alt = alt_hash;
553                         prim_bkt->key_idx[i] = new_idx;
554                         return new_idx - 1;
555                 }
556         }
557
558         /* Primary bucket is full, so we need to make space for new entry */
559         ret = make_space_bucket(h, prim_bkt);
560         /*
561          * After recursive function.
562          * Insert the new entry in the position of the pushed entry
563          * if successful or return error and
564          * store the new slot back in the ring
565          */
566         if (ret >= 0) {
567                 prim_bkt->signatures[ret].current = sig;
568                 prim_bkt->signatures[ret].alt = alt_hash;
569                 prim_bkt->key_idx[ret] = new_idx;
570                 return (new_idx - 1);
571         }
572
573         /* Error in addition, store new slot back in the ring and return error */
574         rte_ring_sp_enqueue(h->free_slots,
575                 (void *)((uintptr_t) new_idx));
576         return ret;
577
578 }
579
580 int32_t
581 rte_hash_add_key_with_hash(const struct rte_hash *h,
582                         const void *key, hash_sig_t sig)
583 {
584         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
585         return __rte_hash_add_key_with_hash(h, key, sig, 0);
586 }
587
588 int32_t
589 rte_hash_add_key(const struct rte_hash *h, const void *key)
590 {
591         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
592         return __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key), 0);
593 }
594
595 int
596 rte_hash_add_key_with_hash_data(const struct rte_hash *h,
597                         const void *key, hash_sig_t sig, void *data)
598 {
599         int ret;
600
601         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
602         ret = __rte_hash_add_key_with_hash(h, key, sig, data);
603         if (ret >= 0)
604                 return 0;
605         else
606                 return ret;
607 }
608
609 int
610 rte_hash_add_key_data(const struct rte_hash *h, const void *key, void *data)
611 {
612         int ret;
613
614         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
615
616         ret = __rte_hash_add_key_with_hash(h, key, rte_hash_hash(h, key), data);
617         if (ret >= 0)
618                 return 0;
619         else
620                 return ret;
621 }
622 static inline int32_t
623 __rte_hash_lookup_with_hash(const struct rte_hash *h, const void *key,
624                                         hash_sig_t sig, void **data)
625 {
626         uint32_t bucket_idx;
627         hash_sig_t alt_hash;
628         unsigned i;
629         struct rte_hash_bucket *bkt;
630         struct rte_hash_key *k, *keys = h->key_store;
631
632         bucket_idx = sig & h->bucket_bitmask;
633         bkt = &h->buckets[bucket_idx];
634
635         /* Check if key is in primary location */
636         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
637                 if (bkt->signatures[i].current == sig &&
638                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
639                         k = (struct rte_hash_key *) ((char *)keys +
640                                         bkt->key_idx[i] * h->key_entry_size);
641                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
642                                 if (data != NULL)
643                                         *data = k->pdata;
644                                 /*
645                                  * Return index where key is stored,
646                                  * substracting the first dummy index
647                                  */
648                                 return (bkt->key_idx[i] - 1);
649                         }
650                 }
651         }
652
653         /* Calculate secondary hash */
654         alt_hash = rte_hash_secondary_hash(sig);
655         bucket_idx = alt_hash & h->bucket_bitmask;
656         bkt = &h->buckets[bucket_idx];
657
658         /* Check if key is in secondary location */
659         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
660                 if (bkt->signatures[i].current == alt_hash &&
661                                 bkt->signatures[i].alt == sig) {
662                         k = (struct rte_hash_key *) ((char *)keys +
663                                         bkt->key_idx[i] * h->key_entry_size);
664                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
665                                 if (data != NULL)
666                                         *data = k->pdata;
667                                 /*
668                                  * Return index where key is stored,
669                                  * substracting the first dummy index
670                                  */
671                                 return (bkt->key_idx[i] - 1);
672                         }
673                 }
674         }
675
676         return -ENOENT;
677 }
678
679 int32_t
680 rte_hash_lookup_with_hash(const struct rte_hash *h,
681                         const void *key, hash_sig_t sig)
682 {
683         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
684         return __rte_hash_lookup_with_hash(h, key, sig, NULL);
685 }
686
687 int32_t
688 rte_hash_lookup(const struct rte_hash *h, const void *key)
689 {
690         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
691         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key), NULL);
692 }
693
694 int
695 rte_hash_lookup_with_hash_data(const struct rte_hash *h,
696                         const void *key, hash_sig_t sig, void **data)
697 {
698         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
699         return __rte_hash_lookup_with_hash(h, key, sig, data);
700 }
701
702 int
703 rte_hash_lookup_data(const struct rte_hash *h, const void *key, void **data)
704 {
705         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
706         return __rte_hash_lookup_with_hash(h, key, rte_hash_hash(h, key), data);
707 }
708
709 static inline int32_t
710 __rte_hash_del_key_with_hash(const struct rte_hash *h, const void *key,
711                                                 hash_sig_t sig)
712 {
713         uint32_t bucket_idx;
714         hash_sig_t alt_hash;
715         unsigned i;
716         struct rte_hash_bucket *bkt;
717         struct rte_hash_key *k, *keys = h->key_store;
718
719         bucket_idx = sig & h->bucket_bitmask;
720         bkt = &h->buckets[bucket_idx];
721
722         /* Check if key is in primary location */
723         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
724                 if (bkt->signatures[i].current == sig &&
725                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
726                         k = (struct rte_hash_key *) ((char *)keys +
727                                         bkt->key_idx[i] * h->key_entry_size);
728                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
729                                 bkt->signatures[i].sig = NULL_SIGNATURE;
730                                 rte_ring_sp_enqueue(h->free_slots,
731                                                 (void *)((uintptr_t)bkt->key_idx[i]));
732                                 /*
733                                  * Return index where key is stored,
734                                  * substracting the first dummy index
735                                  */
736                                 return (bkt->key_idx[i] - 1);
737                         }
738                 }
739         }
740
741         /* Calculate secondary hash */
742         alt_hash = rte_hash_secondary_hash(sig);
743         bucket_idx = alt_hash & h->bucket_bitmask;
744         bkt = &h->buckets[bucket_idx];
745
746         /* Check if key is in secondary location */
747         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
748                 if (bkt->signatures[i].current == alt_hash &&
749                                 bkt->signatures[i].sig != NULL_SIGNATURE) {
750                         k = (struct rte_hash_key *) ((char *)keys +
751                                         bkt->key_idx[i] * h->key_entry_size);
752                         if (h->rte_hash_cmp_eq(key, k->key, h->key_len) == 0) {
753                                 bkt->signatures[i].sig = NULL_SIGNATURE;
754                                 rte_ring_sp_enqueue(h->free_slots,
755                                                 (void *)((uintptr_t)bkt->key_idx[i]));
756                                 /*
757                                  * Return index where key is stored,
758                                  * substracting the first dummy index
759                                  */
760                                 return (bkt->key_idx[i] - 1);
761                         }
762                 }
763         }
764
765         return -ENOENT;
766 }
767
768 int32_t
769 rte_hash_del_key_with_hash(const struct rte_hash *h,
770                         const void *key, hash_sig_t sig)
771 {
772         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
773         return __rte_hash_del_key_with_hash(h, key, sig);
774 }
775
776 int32_t
777 rte_hash_del_key(const struct rte_hash *h, const void *key)
778 {
779         RETURN_IF_TRUE(((h == NULL) || (key == NULL)), -EINVAL);
780         return __rte_hash_del_key_with_hash(h, key, rte_hash_hash(h, key));
781 }
782
783 /* Lookup bulk stage 0: Prefetch input key */
784 static inline void
785 lookup_stage0(unsigned *idx, uint64_t *lookup_mask,
786                 const void * const *keys)
787 {
788         *idx = __builtin_ctzl(*lookup_mask);
789         if (*lookup_mask == 0)
790                 *idx = 0;
791
792         rte_prefetch0(keys[*idx]);
793         *lookup_mask &= ~(1llu << *idx);
794 }
795
796 /*
797  * Lookup bulk stage 1: Calculate primary/secondary hashes
798  * and prefetch primary/secondary buckets
799  */
800 static inline void
801 lookup_stage1(unsigned idx, hash_sig_t *prim_hash, hash_sig_t *sec_hash,
802                 const struct rte_hash_bucket **primary_bkt,
803                 const struct rte_hash_bucket **secondary_bkt,
804                 hash_sig_t *hash_vals, const void * const *keys,
805                 const struct rte_hash *h)
806 {
807         *prim_hash = rte_hash_hash(h, keys[idx]);
808         hash_vals[idx] = *prim_hash;
809         *sec_hash = rte_hash_secondary_hash(*prim_hash);
810
811         *primary_bkt = &h->buckets[*prim_hash & h->bucket_bitmask];
812         *secondary_bkt = &h->buckets[*sec_hash & h->bucket_bitmask];
813
814         rte_prefetch0(*primary_bkt);
815         rte_prefetch0(*secondary_bkt);
816 }
817
818 /*
819  * Lookup bulk stage 2:  Search for match hashes in primary/secondary locations
820  * and prefetch first key slot
821  */
822 static inline void
823 lookup_stage2(unsigned idx, hash_sig_t prim_hash, hash_sig_t sec_hash,
824                 const struct rte_hash_bucket *prim_bkt,
825                 const struct rte_hash_bucket *sec_bkt,
826                 const struct rte_hash_key **key_slot, int32_t *positions,
827                 uint64_t *extra_hits_mask, const void *keys,
828                 const struct rte_hash *h)
829 {
830         unsigned prim_hash_matches, sec_hash_matches, key_idx, i;
831         unsigned total_hash_matches;
832
833         prim_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
834         sec_hash_matches = 1 << RTE_HASH_BUCKET_ENTRIES;
835         for (i = 0; i < RTE_HASH_BUCKET_ENTRIES; i++) {
836                 prim_hash_matches |= ((prim_hash == prim_bkt->signatures[i].current) << i);
837                 sec_hash_matches |= ((sec_hash == sec_bkt->signatures[i].current) << i);
838         }
839
840         key_idx = prim_bkt->key_idx[__builtin_ctzl(prim_hash_matches)];
841         if (key_idx == 0)
842                 key_idx = sec_bkt->key_idx[__builtin_ctzl(sec_hash_matches)];
843
844         total_hash_matches = (prim_hash_matches |
845                                 (sec_hash_matches << (RTE_HASH_BUCKET_ENTRIES + 1)));
846         *key_slot = (const struct rte_hash_key *) ((const char *)keys +
847                                         key_idx * h->key_entry_size);
848
849         rte_prefetch0(*key_slot);
850         /*
851          * Return index where key is stored,
852          * substracting the first dummy index
853          */
854         positions[idx] = (key_idx - 1);
855
856         *extra_hits_mask |= (uint64_t)(__builtin_popcount(total_hash_matches) > 3) << idx;
857
858 }
859
860
861 /* Lookup bulk stage 3: Check if key matches, update hit mask and return data */
862 static inline void
863 lookup_stage3(unsigned idx, const struct rte_hash_key *key_slot, const void * const *keys,
864                 void *data[], uint64_t *hits, const struct rte_hash *h)
865 {
866         unsigned hit;
867
868         hit = !h->rte_hash_cmp_eq(key_slot->key, keys[idx], h->key_len);
869         if (data != NULL)
870                 data[idx] = key_slot->pdata;
871
872         *hits |= (uint64_t)(hit) << idx;
873 }
874
875 static inline void
876 __rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
877                         uint32_t num_keys, int32_t *positions,
878                         uint64_t *hit_mask, void *data[])
879 {
880         uint64_t hits = 0;
881         uint64_t extra_hits_mask = 0;
882         uint64_t lookup_mask, miss_mask;
883         unsigned idx;
884         const void *key_store = h->key_store;
885         int ret;
886         hash_sig_t hash_vals[RTE_HASH_LOOKUP_BULK_MAX];
887
888         unsigned idx00, idx01, idx10, idx11, idx20, idx21, idx30, idx31;
889         const struct rte_hash_bucket *primary_bkt10, *primary_bkt11;
890         const struct rte_hash_bucket *secondary_bkt10, *secondary_bkt11;
891         const struct rte_hash_bucket *primary_bkt20, *primary_bkt21;
892         const struct rte_hash_bucket *secondary_bkt20, *secondary_bkt21;
893         const struct rte_hash_key *k_slot20, *k_slot21, *k_slot30, *k_slot31;
894         hash_sig_t primary_hash10, primary_hash11;
895         hash_sig_t secondary_hash10, secondary_hash11;
896         hash_sig_t primary_hash20, primary_hash21;
897         hash_sig_t secondary_hash20, secondary_hash21;
898
899         lookup_mask = (uint64_t) -1 >> (64 - num_keys);
900         miss_mask = lookup_mask;
901
902         lookup_stage0(&idx00, &lookup_mask, keys);
903         lookup_stage0(&idx01, &lookup_mask, keys);
904
905         idx10 = idx00, idx11 = idx01;
906
907         lookup_stage0(&idx00, &lookup_mask, keys);
908         lookup_stage0(&idx01, &lookup_mask, keys);
909         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
910                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
911         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
912                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
913
914         primary_bkt20 = primary_bkt10;
915         primary_bkt21 = primary_bkt11;
916         secondary_bkt20 = secondary_bkt10;
917         secondary_bkt21 = secondary_bkt11;
918         primary_hash20 = primary_hash10;
919         primary_hash21 = primary_hash11;
920         secondary_hash20 = secondary_hash10;
921         secondary_hash21 = secondary_hash11;
922         idx20 = idx10, idx21 = idx11;
923         idx10 = idx00, idx11 = idx01;
924
925         lookup_stage0(&idx00, &lookup_mask, keys);
926         lookup_stage0(&idx01, &lookup_mask, keys);
927         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
928                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
929         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
930                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
931         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
932                         secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
933                         key_store, h);
934         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
935                         secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
936                         key_store, h);
937
938         while (lookup_mask) {
939                 k_slot30 = k_slot20, k_slot31 = k_slot21;
940                 idx30 = idx20, idx31 = idx21;
941                 primary_bkt20 = primary_bkt10;
942                 primary_bkt21 = primary_bkt11;
943                 secondary_bkt20 = secondary_bkt10;
944                 secondary_bkt21 = secondary_bkt11;
945                 primary_hash20 = primary_hash10;
946                 primary_hash21 = primary_hash11;
947                 secondary_hash20 = secondary_hash10;
948                 secondary_hash21 = secondary_hash11;
949                 idx20 = idx10, idx21 = idx11;
950                 idx10 = idx00, idx11 = idx01;
951
952                 lookup_stage0(&idx00, &lookup_mask, keys);
953                 lookup_stage0(&idx01, &lookup_mask, keys);
954                 lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
955                         &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
956                 lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
957                         &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
958                 lookup_stage2(idx20, primary_hash20, secondary_hash20,
959                         primary_bkt20, secondary_bkt20, &k_slot20, positions,
960                         &extra_hits_mask, key_store, h);
961                 lookup_stage2(idx21, primary_hash21, secondary_hash21,
962                         primary_bkt21, secondary_bkt21, &k_slot21, positions,
963                         &extra_hits_mask, key_store, h);
964                 lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
965                 lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
966         }
967
968         k_slot30 = k_slot20, k_slot31 = k_slot21;
969         idx30 = idx20, idx31 = idx21;
970         primary_bkt20 = primary_bkt10;
971         primary_bkt21 = primary_bkt11;
972         secondary_bkt20 = secondary_bkt10;
973         secondary_bkt21 = secondary_bkt11;
974         primary_hash20 = primary_hash10;
975         primary_hash21 = primary_hash11;
976         secondary_hash20 = secondary_hash10;
977         secondary_hash21 = secondary_hash11;
978         idx20 = idx10, idx21 = idx11;
979         idx10 = idx00, idx11 = idx01;
980
981         lookup_stage1(idx10, &primary_hash10, &secondary_hash10,
982                 &primary_bkt10, &secondary_bkt10, hash_vals, keys, h);
983         lookup_stage1(idx11, &primary_hash11, &secondary_hash11,
984                 &primary_bkt11, &secondary_bkt11, hash_vals, keys, h);
985         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
986                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
987                 key_store, h);
988         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
989                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
990                 key_store, h);
991         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
992         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
993
994         k_slot30 = k_slot20, k_slot31 = k_slot21;
995         idx30 = idx20, idx31 = idx21;
996         primary_bkt20 = primary_bkt10;
997         primary_bkt21 = primary_bkt11;
998         secondary_bkt20 = secondary_bkt10;
999         secondary_bkt21 = secondary_bkt11;
1000         primary_hash20 = primary_hash10;
1001         primary_hash21 = primary_hash11;
1002         secondary_hash20 = secondary_hash10;
1003         secondary_hash21 = secondary_hash11;
1004         idx20 = idx10, idx21 = idx11;
1005
1006         lookup_stage2(idx20, primary_hash20, secondary_hash20, primary_bkt20,
1007                 secondary_bkt20, &k_slot20, positions, &extra_hits_mask,
1008                 key_store, h);
1009         lookup_stage2(idx21, primary_hash21, secondary_hash21, primary_bkt21,
1010                 secondary_bkt21, &k_slot21, positions, &extra_hits_mask,
1011                 key_store, h);
1012         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1013         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1014
1015         k_slot30 = k_slot20, k_slot31 = k_slot21;
1016         idx30 = idx20, idx31 = idx21;
1017
1018         lookup_stage3(idx30, k_slot30, keys, data, &hits, h);
1019         lookup_stage3(idx31, k_slot31, keys, data, &hits, h);
1020
1021         /* ignore any items we have already found */
1022         extra_hits_mask &= ~hits;
1023
1024         if (unlikely(extra_hits_mask)) {
1025                 /* run a single search for each remaining item */
1026                 do {
1027                         idx = __builtin_ctzl(extra_hits_mask);
1028                         if (data != NULL) {
1029                                 ret = rte_hash_lookup_with_hash_data(h,
1030                                                 keys[idx], hash_vals[idx], &data[idx]);
1031                                 if (ret >= 0)
1032                                         hits |= 1ULL << idx;
1033                         } else {
1034                                 positions[idx] = rte_hash_lookup_with_hash(h,
1035                                                         keys[idx], hash_vals[idx]);
1036                                 if (positions[idx] >= 0)
1037                                         hits |= 1llu << idx;
1038                         }
1039                         extra_hits_mask &= ~(1llu << idx);
1040                 } while (extra_hits_mask);
1041         }
1042
1043         miss_mask &= ~hits;
1044         if (unlikely(miss_mask)) {
1045                 do {
1046                         idx = __builtin_ctzl(miss_mask);
1047                         positions[idx] = -ENOENT;
1048                         miss_mask &= ~(1llu << idx);
1049                 } while (miss_mask);
1050         }
1051
1052         if (hit_mask != NULL)
1053                 *hit_mask = hits;
1054 }
1055
1056 int
1057 rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys,
1058                       uint32_t num_keys, int32_t *positions)
1059 {
1060         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
1061                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
1062                         (positions == NULL)), -EINVAL);
1063
1064         __rte_hash_lookup_bulk(h, keys, num_keys, positions, NULL, NULL);
1065         return 0;
1066 }
1067
1068 int
1069 rte_hash_lookup_bulk_data(const struct rte_hash *h, const void **keys,
1070                       uint32_t num_keys, uint64_t *hit_mask, void *data[])
1071 {
1072         RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) ||
1073                         (num_keys > RTE_HASH_LOOKUP_BULK_MAX) ||
1074                         (hit_mask == NULL)), -EINVAL);
1075
1076         int32_t positions[num_keys];
1077
1078         __rte_hash_lookup_bulk(h, keys, num_keys, positions, hit_mask, data);
1079
1080         /* Return number of hits */
1081         return __builtin_popcountl(*hit_mask);
1082 }
1083
1084 /* Functions to compare multiple of 16 byte keys (up to 128 bytes) */
1085 static int
1086 rte_hash_k16_cmp_eq(const void *key1, const void *key2, size_t key_len __rte_unused)
1087 {
1088         const __m128i k1 = _mm_loadu_si128((const __m128i *) key1);
1089         const __m128i k2 = _mm_loadu_si128((const __m128i *) key2);
1090         const __m128i x = _mm_xor_si128(k1, k2);
1091
1092         return !_mm_test_all_zeros(x, x);
1093 }
1094
1095 static int
1096 rte_hash_k32_cmp_eq(const void *key1, const void *key2, size_t key_len)
1097 {
1098         return rte_hash_k16_cmp_eq(key1, key2, key_len) ||
1099                 rte_hash_k16_cmp_eq((const char *) key1 + 16,
1100                                 (const char *) key2 + 16, key_len);
1101 }
1102
1103 static int
1104 rte_hash_k48_cmp_eq(const void *key1, const void *key2, size_t key_len)
1105 {
1106         return rte_hash_k16_cmp_eq(key1, key2, key_len) ||
1107                 rte_hash_k16_cmp_eq((const char *) key1 + 16,
1108                                 (const char *) key2 + 16, key_len) ||
1109                 rte_hash_k16_cmp_eq((const char *) key1 + 32,
1110                                 (const char *) key2 + 32, key_len);
1111 }
1112
1113 static int
1114 rte_hash_k64_cmp_eq(const void *key1, const void *key2, size_t key_len)
1115 {
1116         return rte_hash_k32_cmp_eq(key1, key2, key_len) ||
1117                 rte_hash_k32_cmp_eq((const char *) key1 + 32,
1118                                 (const char *) key2 + 32, key_len);
1119 }
1120
1121 static int
1122 rte_hash_k80_cmp_eq(const void *key1, const void *key2, size_t key_len)
1123 {
1124         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1125                 rte_hash_k16_cmp_eq((const char *) key1 + 64,
1126                                 (const char *) key2 + 64, key_len);
1127 }
1128
1129 static int
1130 rte_hash_k96_cmp_eq(const void *key1, const void *key2, size_t key_len)
1131 {
1132         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1133                 rte_hash_k32_cmp_eq((const char *) key1 + 64,
1134                                 (const char *) key2 + 64, key_len);
1135 }
1136
1137 static int
1138 rte_hash_k112_cmp_eq(const void *key1, const void *key2, size_t key_len)
1139 {
1140         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1141                 rte_hash_k32_cmp_eq((const char *) key1 + 64,
1142                                 (const char *) key2 + 64, key_len) ||
1143                 rte_hash_k16_cmp_eq((const char *) key1 + 96,
1144                                 (const char *) key2 + 96, key_len);
1145 }
1146
1147 static int
1148 rte_hash_k128_cmp_eq(const void *key1, const void *key2, size_t key_len)
1149 {
1150         return rte_hash_k64_cmp_eq(key1, key2, key_len) ||
1151                 rte_hash_k64_cmp_eq((const char *) key1 + 64,
1152                                 (const char *) key2 + 64, key_len);
1153 }