DPDK  21.11.7-rc1
rte_fbk_hash.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #ifndef _RTE_FBK_HASH_H_
6 #define _RTE_FBK_HASH_H_
7 
18 #include <stdint.h>
19 #include <errno.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #include <string.h>
26 
27 #include <rte_config.h>
28 #include <rte_hash_crc.h>
29 #include <rte_jhash.h>
30 
31 #ifndef RTE_FBK_HASH_INIT_VAL_DEFAULT
32 
33 #define RTE_FBK_HASH_INIT_VAL_DEFAULT 0xFFFFFFFF
34 #endif
35 
37 #define RTE_FBK_HASH_ENTRIES_MAX (1 << 20)
38 
40 #define RTE_FBK_HASH_ENTRIES_PER_BUCKET_MAX 256
41 
43 #define RTE_FBK_HASH_NAMESIZE 32
44 
46 typedef uint32_t (*rte_fbk_hash_fn)(uint32_t key, uint32_t init_val);
47 
50  const char *name;
51  uint32_t entries;
52  uint32_t entries_per_bucket;
53  int socket_id;
55  uint32_t init_val;
56 };
57 
60  uint64_t whole_entry;
61  struct {
62  uint16_t is_entry;
63  uint16_t value;
64  uint32_t key;
65  } entry;
66 };
67 
68 
72  uint32_t entries;
73  uint32_t entries_per_bucket;
74  uint32_t used_entries;
75  uint32_t bucket_mask;
76  uint32_t bucket_shift;
78  uint32_t init_val;
81  union rte_fbk_hash_entry t[];
82 };
83 
94 static inline uint32_t
95 rte_fbk_hash_get_bucket(const struct rte_fbk_hash_table *ht, uint32_t key)
96 {
97  return (ht->hash_func(key, ht->init_val) & ht->bucket_mask) <<
98  ht->bucket_shift;
99 }
100 
117 static inline int
119  uint32_t key, uint16_t value, uint32_t bucket)
120 {
121  /*
122  * The writing of a new value to the hash table is done as a single
123  * 64bit operation. This should help prevent individual entries being
124  * corrupted due to race conditions, but it's still possible to
125  * overwrite entries that have just been made valid.
126  */
127  const uint64_t new_entry = ((uint64_t)(key) << 32) |
128  ((uint64_t)(value) << 16) |
129  1; /* 1 = is_entry bit. */
130  uint32_t i;
131 
132  for (i = 0; i < ht->entries_per_bucket; i++) {
133  /* Set entry if unused. */
134  if (! ht->t[bucket + i].entry.is_entry) {
135  ht->t[bucket + i].whole_entry = new_entry;
136  ht->used_entries++;
137  return 0;
138  }
139  /* Change value if key already exists. */
140  if (ht->t[bucket + i].entry.key == key) {
141  ht->t[bucket + i].entry.value = value;
142  return 0;
143  }
144  }
145 
146  return -ENOSPC; /* No space in bucket. */
147 }
148 
162 static inline int
164  uint32_t key, uint16_t value)
165 {
167  key, value, rte_fbk_hash_get_bucket(ht, key));
168 }
169 
184 static inline int
186  uint32_t key, uint32_t bucket)
187 {
188  uint32_t last_entry = ht->entries_per_bucket - 1;
189  uint32_t i, j;
190 
191  for (i = 0; i < ht->entries_per_bucket; i++) {
192  if (ht->t[bucket + i].entry.key == key) {
193  /* Find last key in bucket. */
194  for (j = ht->entries_per_bucket - 1; j > i; j-- ) {
195  if (! ht->t[bucket + j].entry.is_entry) {
196  last_entry = j - 1;
197  }
198  }
199  /*
200  * Move the last key to the deleted key's position, and
201  * delete the last key. lastEntry and i may be same but
202  * it doesn't matter.
203  */
204  ht->t[bucket + i].whole_entry =
205  ht->t[bucket + last_entry].whole_entry;
206  ht->t[bucket + last_entry].whole_entry = 0;
207 
208  ht->used_entries--;
209  return 0;
210  }
211  }
212 
213  return -ENOENT; /* Key didn't exist. */
214 }
215 
227 static inline int
229 {
231  key, rte_fbk_hash_get_bucket(ht, key));
232 }
233 
247 static inline int
249  uint32_t key, uint32_t bucket)
250 {
251  union rte_fbk_hash_entry current_entry;
252  uint32_t i;
253 
254  for (i = 0; i < ht->entries_per_bucket; i++) {
255  /* Single read of entry, which should be atomic. */
256  current_entry.whole_entry = ht->t[bucket + i].whole_entry;
257  if (! current_entry.entry.is_entry) {
258  return -ENOENT; /* Error once we hit an empty field. */
259  }
260  if (current_entry.entry.key == key) {
261  return current_entry.entry.value;
262  }
263  }
264  return -ENOENT; /* Key didn't exist. */
265 }
266 
277 static inline int
278 rte_fbk_hash_lookup(const struct rte_fbk_hash_table *ht, uint32_t key)
279 {
281  key, rte_fbk_hash_get_bucket(ht, key));
282 }
283 
291 static inline void
293 {
294  memset(ht->t, 0, sizeof(ht->t[0]) * ht->entries);
295  ht->used_entries = 0;
296 }
297 
306 static inline double
308 {
309  return (double)ht->used_entries / (double)ht->entries;
310 }
311 
325 
343 struct rte_fbk_hash_table * \
344 rte_fbk_hash_create(const struct rte_fbk_hash_params *params);
345 
353 void rte_fbk_hash_free(struct rte_fbk_hash_table *ht);
354 
355 #ifdef __cplusplus
356 }
357 #endif
358 
359 #endif /* _RTE_FBK_HASH_H_ */
uint16_t is_entry
Definition: rte_fbk_hash.h:62
union rte_fbk_hash_entry t[]
Definition: rte_fbk_hash.h:81
uint32_t used_entries
Definition: rte_fbk_hash.h:74
Definition: rte_fbk_hash.h:59
static int rte_fbk_hash_add_key_with_bucket(struct rte_fbk_hash_table *ht, uint32_t key, uint16_t value, uint32_t bucket)
Definition: rte_fbk_hash.h:118
static int rte_fbk_hash_delete_key(struct rte_fbk_hash_table *ht, uint32_t key)
Definition: rte_fbk_hash.h:228
rte_fbk_hash_fn hash_func
Definition: rte_fbk_hash.h:54
static double rte_fbk_hash_get_load_factor(struct rte_fbk_hash_table *ht)
Definition: rte_fbk_hash.h:307
uint32_t(* rte_fbk_hash_fn)(uint32_t key, uint32_t init_val)
Definition: rte_fbk_hash.h:46
void rte_fbk_hash_free(struct rte_fbk_hash_table *ht)
static void rte_fbk_hash_clear_all(struct rte_fbk_hash_table *ht)
Definition: rte_fbk_hash.h:292
static int rte_fbk_hash_lookup_with_bucket(const struct rte_fbk_hash_table *ht, uint32_t key, uint32_t bucket)
Definition: rte_fbk_hash.h:248
uint32_t entries_per_bucket
Definition: rte_fbk_hash.h:52
static uint32_t rte_fbk_hash_get_bucket(const struct rte_fbk_hash_table *ht, uint32_t key)
Definition: rte_fbk_hash.h:95
const char * name
Definition: rte_fbk_hash.h:50
uint32_t key
Definition: rte_fbk_hash.h:64
struct rte_fbk_hash_entry::@226 entry
uint32_t entries_per_bucket
Definition: rte_fbk_hash.h:73
static int rte_fbk_hash_add_key(struct rte_fbk_hash_table *ht, uint32_t key, uint16_t value)
Definition: rte_fbk_hash.h:163
static int rte_fbk_hash_lookup(const struct rte_fbk_hash_table *ht, uint32_t key)
Definition: rte_fbk_hash.h:278
uint32_t bucket_mask
Definition: rte_fbk_hash.h:75
uint64_t whole_entry
Definition: rte_fbk_hash.h:60
uint16_t value
Definition: rte_fbk_hash.h:63
#define RTE_FBK_HASH_NAMESIZE
Definition: rte_fbk_hash.h:43
static int rte_fbk_hash_delete_key_with_bucket(struct rte_fbk_hash_table *ht, uint32_t key, uint32_t bucket)
Definition: rte_fbk_hash.h:185
uint32_t bucket_shift
Definition: rte_fbk_hash.h:76
struct rte_fbk_hash_table * rte_fbk_hash_find_existing(const char *name)
rte_fbk_hash_fn hash_func
Definition: rte_fbk_hash.h:77