summaryrefslogtreecommitdiff
path: root/lib/librte_hash/rte_hash.h
blob: cd630e79ea8d4c35ad70af4a185c907252911841 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*-
 *   BSD LICENSE
 * 
 *   Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
 *   All rights reserved.
 * 
 *   Redistribution and use in source and binary forms, with or without 
 *   modification, are permitted provided that the following conditions 
 *   are met:
 * 
 *     * Redistributions of source code must retain the above copyright 
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright 
 *       notice, this list of conditions and the following disclaimer in 
 *       the documentation and/or other materials provided with the 
 *       distribution.
 *     * Neither the name of Intel Corporation nor the names of its 
 *       contributors may be used to endorse or promote products derived 
 *       from this software without specific prior written permission.
 * 
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

#ifndef _RTE_HASH_H_
#define _RTE_HASH_H_

/**
 * @file
 *
 * RTE Hash Table
 */

#include <stdint.h>
#include <sys/queue.h>

#ifdef __cplusplus
extern "C" {
#endif

/** Maximum size of hash table that can be created. */
#define RTE_HASH_ENTRIES_MAX			(1 << 26)

/** Maximum bucket size that can be created. */
#define RTE_HASH_BUCKET_ENTRIES_MAX		16

/** Maximum length of key that can be used. */
#define RTE_HASH_KEY_LENGTH_MAX			64

/** Max number of keys that can be searched for using rte_hash_lookup_multi. */
#define RTE_HASH_LOOKUP_MULTI_MAX		16

/** Max number of characters in hash name.*/
#define RTE_HASH_NAMESIZE			32

/** Signature of key that is stored internally. */
typedef uint32_t hash_sig_t;

/** Type of function that can be used for calculating the hash value. */
typedef uint32_t (*rte_hash_function)(const void *key, uint32_t key_len,
				      uint32_t init_val);

/**
 * Parameters used when creating the hash table. The total table entries and
 * bucket entries must be a power of 2.
 */
struct rte_hash_parameters {
	const char *name;		/**< Name of the hash. */
	uint32_t entries;		/**< Total hash table entries. */
	uint32_t bucket_entries;	/**< Bucket entries. */
	uint32_t key_len;		/**< Length of hash key. */
	rte_hash_function hash_func;	/**< Function used to calculate hash. */
	uint32_t hash_func_init_val;	/**< Init value used by hash_func. */
	int socket_id;			/**< NUMA Socket ID for memory. */
};

/** A hash table structure. */
struct rte_hash {
	TAILQ_ENTRY(rte_hash) next;/**< Next in list. */

	char name[RTE_HASH_NAMESIZE];	/**< Name of the hash. */
	uint32_t entries;		/**< Total table entries. */
	uint32_t bucket_entries;	/**< Bucket entries. */
	uint32_t key_len;		/**< Length of hash key. */
	rte_hash_function hash_func;	/**< Function used to calculate hash. */
	uint32_t hash_func_init_val;	/**< Init value used by hash_func. */
	uint32_t num_buckets;		/**< Number of buckets in table. */
	uint32_t bucket_bitmask;	/**< Bitmask for getting bucket index
							from hash signature. */
	hash_sig_t sig_msb;	/**< MSB is always set in valid signatures. */
	uint8_t *sig_tbl;	/**< Flat array of hash signature buckets. */
	uint32_t sig_tbl_bucket_size;	/**< Signature buckets may be padded for
					   alignment reasons, and this is the
					   bucket size used by sig_tbl. */
	uint8_t *key_tbl;	/**< Flat array of key value buckets. */
	uint32_t key_tbl_key_size;	/**< Keys may be padded for alignment
					   reasons, and this is the key size
					   used	by key_tbl. */
};

/**
 * Create a new hash table. If RTE_LIBRTE_HASH_USE_MEMZONE is defined, then
 * the hash table is allocated in a memzone on a specific NUMA socket ID,
 * otherwise it is allocated in the heap.
 *
 * @param params
 *   Parameters used to create and initialise the hash table.
 * @return
 *   Pointer to hash table structure that is used in future hash table
 *   operations, or NULL on error, with error code set in rte_errno.
 *   Possible rte_errno errors include:
 *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
 *    - E_RTE_SECONDARY - function was called from a secondary process instance
 *    - E_RTE_NO_TAILQ - no tailq list could be got for the hash table list
 *    - ENOENT - missing entry
 *    - EINVAL - invalid parameter passed to function
 *    - ENOSPC - the maximum number of memzones has already been allocated
 *    - EEXIST - a memzone with the same name already exists
 *    - ENOMEM - no appropriate memory area found in which to create memzone
 */
struct rte_hash *
rte_hash_create(const struct rte_hash_parameters *params);


/**
 * Find an existing hash table object and return a pointer to it.
 *
 * @param name
 *   Name of the hash table as passed to rte_hash_create()
 * @return
 *   Pointer to hash table or NULL if object not found
 *   with rte_errno set appropriately. Possible rte_errno values include:
 *    - ENOENT - value not available for return
 */
struct rte_hash *
rte_hash_find_existing(const char *name);

/**
 * De-allocate all memory used by hash table. If RTE_LIBRTE_HASH_USE_MEMZONE
 * is defined, then this has no effect.
 * @param h
 *   Hash table to free
 */
void
rte_hash_free(struct rte_hash *h);

/**
 * Add a key to an existing hash table. This operation is not multi-thread safe
 * and should only be called from one thread.
 *
 * @param h
 *   Hash table to add the key to.
 * @param key
 *   Key to add to the hash table.
 * @return
 *   - -EINVAL if the parameters are invalid.
 *   - -ENOSPC if there is no space in the hash for this key.
 *   - A positive value that can be used by the caller as an offset into an
 *     array of user data. This value is unique for this key.
 */
int32_t
rte_hash_add_key(const struct rte_hash *h, const void *key);

/**
 * Remove a key from an existing hash table. This operation is not multi-thread
 * safe and should only be called from one thread.
 *
 * @param h
 *   Hash table to remove the key from.
 * @param key
 *   Key to remove from the hash table.
 * @return
 *   - -EINVAL if the parameters are invalid.
 *   - -ENOENT if the key is not found.
 *   - A positive value that can be used by the caller as an offset into an
 *     array of user data. This value is unique for this key, and is the same
 *     value that was returned when the key was added.
 */
int32_t
rte_hash_del_key(const struct rte_hash *h, const void *key);

/**
 * Find a key in the hash table. This operation is multi-thread safe.
 *
 * @param h
 *   Hash table to look in.
 * @param key
 *   Key to find.
 * @return
 *   - -EINVAL if the parameters are invalid.
 *   - -ENOENT if the key is not found.
 *   - A positive value that can be used by the caller as an offset into an
 *     array of user data. This value is unique for this key, and is the same
 *     value that was returned when the key was added.
 */
int32_t
rte_hash_lookup(const struct rte_hash *h, const void *key);

/**
 * Find multiple keys in the hash table. This operation is multi-thread safe.
 *
 * @param h
 *   Hash table to look in.
 * @param keys
 *   A pointer to a list of keys to look for.
 * @param num_keys
 *   How many keys are in the keys list (less than RTE_HASH_LOOKUP_MULTI_MAX).
 * @param positions
 *   Output containing a list of values, corresponding to the list of keys that
 *   can be used by the caller as an offset into an array of user data. These
 *   values are unique for each key, and are the same values that were returned
 *   when each key was added. If a key in the list was not found, then -ENOENT
 *   will be the value.
 * @return
 *   -EINVAL if there's an error, otherwise 0.
 */
int
rte_hash_lookup_multi(const struct rte_hash *h, const void **keys,
		      uint32_t num_keys, int32_t *positions);

#ifdef __cplusplus
}
#endif

#endif /* _RTE_HASH_H_ */