4ebab94e18913c2e2dc51e2f5df094101534b0c3
[samplevnf.git] / VNFs / DPPD-PROX / hash_utils.c
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #include <string.h>
18 #include <rte_hash_crc.h>
19 #include <rte_table_hash.h>
20 #include <rte_version.h>
21
22 #include "hash_utils.h"
23
24 /* These opaque structure definitions were copied from DPDK lib/librte_table/rte_table_hash_key8.c */
25
26 struct rte_bucket_4_8 {
27         /* Cache line 0 */
28         uint64_t signature;
29         uint64_t lru_list;
30         struct rte_bucket_4_8 *next;
31         uint64_t next_valid;
32
33         uint64_t key[4];
34
35         /* Cache line 1 */
36         uint8_t data[0];
37 };
38
39 struct rte_table_hash_key8 {
40 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
41         struct rte_table_stats stats;
42 #endif
43         /* Input parameters */
44         uint32_t n_buckets;
45         uint32_t n_entries_per_bucket;
46         uint32_t key_size;
47         uint32_t entry_size;
48         uint32_t bucket_size;
49         uint32_t signature_offset;
50         uint32_t key_offset;
51 #if RTE_VERSION >= RTE_VERSION_NUM(2,2,0,0)
52         uint64_t key_mask;
53 #endif
54         rte_table_hash_op_hash f_hash;
55         uint64_t seed;
56
57         /* Extendible buckets */
58         uint32_t n_buckets_ext;
59         uint32_t stack_pos;
60         uint32_t *stack;
61
62         /* Lookup table */
63         uint8_t memory[0] __rte_cache_aligned;
64 };
65
66 /* These opaque structure definitions were copied from DPDK lib/librte_table/rte_table_hash_ext.c */
67
68 struct bucket {
69         union {
70                 uintptr_t next;
71                 uint64_t lru_list;
72         };
73         uint16_t sig[4];
74         uint32_t key_pos[4];
75 };
76
77 #define BUCKET_NEXT(bucket)                                             \
78         ((void *) ((bucket)->next & (~1LU)))
79
80 struct grinder {
81         struct bucket *bkt;
82         uint64_t sig;
83         uint64_t match;
84         uint32_t key_index;
85 };
86
87 struct rte_table_hash_ext {
88 #if RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0)
89         struct rte_table_stats stats;
90 #endif
91         /* Input parameters */
92         uint32_t key_size;
93         uint32_t entry_size;
94         uint32_t n_keys;
95         uint32_t n_buckets;
96         uint32_t n_buckets_ext;
97         rte_table_hash_op_hash f_hash;
98         uint64_t seed;
99         uint32_t signature_offset;
100         uint32_t key_offset;
101
102         /* Internal */
103         uint64_t bucket_mask;
104         uint32_t key_size_shl;
105         uint32_t data_size_shl;
106         uint32_t key_stack_tos;
107         uint32_t bkt_ext_stack_tos;
108
109         /* Grinder */
110         struct grinder grinders[64];
111
112         /* Tables */
113         struct bucket *buckets;
114         struct bucket *buckets_ext;
115         uint8_t *key_mem;
116         uint8_t *data_mem;
117         uint32_t *key_stack;
118         uint32_t *bkt_ext_stack;
119
120         /* Table memory */
121         uint8_t memory[0] __rte_cache_aligned;
122 };
123
124 uint64_t get_bucket(void* table, uint32_t bucket_idx, void** key, void** entries)
125 {
126         struct rte_table_hash_ext *t = (struct rte_table_hash_ext *) table;
127         struct bucket *bkt0, *bkt, *bkt_prev;
128         uint64_t sig;
129         uint32_t bkt_index, i;
130         uint8_t n = 0;
131         bkt_index = bucket_idx & t->bucket_mask;
132         bkt0 = &t->buckets[bkt_index];
133         sig = (bucket_idx >> 16) | 1LLU;
134
135         /* Key is present in the bucket */
136         for (bkt = bkt0; bkt != NULL; bkt = BUCKET_NEXT(bkt)) {
137                 for (i = 0; i < 4; i++) {
138                         uint64_t bkt_sig = (uint64_t) bkt->sig[i];
139                         uint32_t bkt_key_index = bkt->key_pos[i];
140                         uint8_t *bkt_key =
141                                 &t->key_mem[bkt_key_index << t->key_size_shl];
142
143                         if (sig == bkt_sig) {
144                                 key[n] = bkt_key;
145                                 entries[n++] = &t->data_mem[bkt_key_index << t->data_size_shl];
146                                 /* Assume no more than 4 entries in total (including extended state) */
147                                 if (n == 4)
148                                         return t->n_buckets;
149                         }
150                 }
151         }
152         return t->n_buckets;
153 }
154
155 uint64_t get_bucket_key8(void* table, uint32_t bucket_idx, void** key, void** entries)
156 {
157         struct rte_bucket_4_8 *bucket, *bucket0;
158         struct rte_table_hash_key8* f = table;
159         uint8_t n = 0;
160
161         bucket0 = (struct rte_bucket_4_8 *) &f->memory[bucket_idx * f->bucket_size];
162         for (bucket = bucket0; bucket != NULL; bucket = bucket->next) {
163                 uint64_t mask;
164
165                 for (uint8_t i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
166                         uint64_t bucket_signature = bucket->signature;
167
168                         if (bucket_signature & mask) {
169                                 key[n] = &bucket->key[i];
170                                 entries[n++] = &bucket->data[i *f->entry_size];
171                                 /* Assume no more than 4 entries
172                                    in total (including extended state) */
173                                 if (n == 4)
174                                         return f->n_buckets;
175                         }
176                 }
177         }
178         return f->n_buckets;
179 }
180
181 uint64_t hash_crc32(void* key, uint32_t key_size, uint64_t seed)
182 {
183         return rte_hash_crc(key, key_size, seed);
184 }