Mstdlib-1.24.0
m_hash_u64vp.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_HASH_U64VP_H__
25#define __M_HASH_U64VP_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31
32/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
33
34__BEGIN_DECLS
35
36/*! \addtogroup m_hash_u64vp Hashtable - uint64/Void Pointer
37 * \ingroup m_hashtable
38 *
39 * Hashtable, meant for storing uint64 keys and void pointer values.
40 *
41 * References to the data will always be read-only.
42 * All keys will be duplicated by the hashtable.
43 * Values will not be duplicated.
44 *
45 * @{
46 */
47
48struct M_hash_u64vp;
49/* Currently a direct map to M_hashtable private opaque type,
50 * simply using casting to prevent the 'wrap' overhead of mallocing when it
51 * is not necessary.
52 */
53typedef struct M_hash_u64vp M_hash_u64vp_t;
54
55struct M_hash_u64vp_enum;
56/* Used for enumerating a M_hash_strvp. */
57typedef struct M_hash_u64vp_enum M_hash_u64vp_enum_t;
58
59
60/*! Flags for controlling the behavior of the hash */
61typedef enum {
62 M_HASH_U64VP_NONE = 0, /*!< Case sensitive single value (new values replace). */
63 M_HASH_U64VP_KEYS_ORDERED = 1 << 0, /*!< Keys should be ordered. Default is insertion order unless the
64 sorted option is specified. */
65 M_HASH_U64VP_KEYS_SORTASC = 1 << 1, /*!< When the keys are ordered sort them using the key_equality function. */
66 M_HASH_U64VP_KEYS_SORTDESC = 1 << 2, /*!< When the keys are ordered sort them using the key_equality function. */
67 M_HASH_U64VP_MULTI_VALUE = 1 << 3, /*!< Allow keys to contain multiple values.
68 Sorted in insertion order another sorting is specified. */
69 M_HASH_U64VP_MULTI_GETLAST = 1 << 4, /*!< When using get and get_direct function get the last value from the list
70 when allowing multiple values. The default is to get the first value. */
71 M_HASH_U64VP_STATIC_SEED = 1 << 5 /*!< Use a static seed for hash function initialization. This greatly reduces
72 the security of the hashtable and removes collision attack protections.
73 This should only be used as a performance optimization when creating
74 millions of hashtables with static data specifically for quick look up.
75 DO _NOT_ use this flag with any hashtable that could store user
76 generated data! Be very careful about duplicating a hashtable that
77 was created with this flag. All duplicates will use the static seed. */
79
80
81/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
82
83/*! Create a new hashtable.
84 *
85 * The hashtable will pre-allocate an array of buckets based on the rounded up size specified. Any hash collisions
86 * will result in those collisions being chained together via a linked list. The hashtable will auto-expand by a
87 * power of 2 when the fill percentage specified is reached. All key entries are compared in a case-insensitive
88 * fashion, and are duplicated internally. Values are duplicated. Case is preserved for both keys and values.
89 *
90 * \param[in] size Size of the hash table. If not specified as a power of 2, will
91 * be rounded up to the nearest power of 2.
92 * \param[in] fillpct The maximum fill percentage before the hash table is expanded. If
93 * 0 is specified, the hashtable will never expand, otherwise the
94 * value must be between 1 and 99 (recommended: 75).
95 * \param[in] flags M_hash_strvp_flags_t flags for modifying behavior.
96 * \param[in] destroy_func The function to be called to destroy value when the hashtable
97 * itself is destroyed. Can be NULL.
98 *
99 * \return Allocated hashtable.
100 *
101 * \see M_hash_u64vp_destroy
102 */
103M_API M_hash_u64vp_t *M_hash_u64vp_create(size_t size, M_uint8 fillpct, M_uint32 flags, void (*destroy_func)(void *)) M_MALLOC_ALIASED;
104
105
106/*! Destroy the hashtable.
107 *
108 * \param[in] h Hashtable to destroy
109 * \param[in] destroy_vals M_TRUE if the values held by the hashtable should be destroyed.
110 * This will almost always be M_TRUE. This should only be set to M_FALSE
111 * when all values held by the hashtable are being managed externally.
112 */
113M_API void M_hash_u64vp_destroy(M_hash_u64vp_t *h, M_bool destroy_vals) M_FREE(1);
114
115
116/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
117
118/*! Insert an entry into the hashtable.
119 *
120 * \param[in,out] h Hashtable being referenced.
121 * \param[in] key Key to insert.
122 * \param[in] value Value to insert into hashtable. Value will not be duplicated.
123 * The hashtable will take ownership of the value. Maybe NULL.
124 *
125 * \return M_TRUE on success, or M_FALSE on failure.
126 */
127M_API M_bool M_hash_u64vp_insert(M_hash_u64vp_t *h, M_uint64 key, void *value);
128
129
130/*! Remove an entry from the hashtable.
131 *
132 * \param[in,out] h Hashtable being referenced.
133 * \param[in] key Key to remove from the hashtable.
134 * \param[in] destroy_vals M_TRUE if the value held by the hashtable should be destroyed.
135 * This will almost always be M_TRUE. This should only be set to M_FALSE
136 * when the value held by the hashtable is being managed externally.
137 *
138 * \return M_TRUE on success, or M_FALSE if key does not exist.
139 */
140M_API M_bool M_hash_u64vp_remove(M_hash_u64vp_t *h, M_uint64 key, M_bool destroy_vals);
141
142
143/*! Retrieve the value for a key from the hashtable.
144 *
145 * \param[in] h Hashtable being referenced.
146 * \param[in] key Key for value.
147 * \param[out] value Pointer to value stored in the hashtable. Optional, pass NULL if not needed.
148 *
149 * \return M_TRUE if value retrieved, M_FALSE if key does not exist.
150 */
151M_API M_bool M_hash_u64vp_get(const M_hash_u64vp_t *h, M_uint64 key, void **value);
152
153
154/*! Retrieve the value for a key from the hashtable, and return it directly as the return value.
155 *
156 * This cannot be used if you need to differentiate between a key that doesn't exist vs a key with a NULL value.
157 *
158 * \param[in] h Hashtable being referenced.
159 * \param[in] key Key for value to retrieve from the hashtable.
160 *
161 * \return NULL if key doesn't exist or NULL value on file, otherwise the value.
162 */
163M_API void *M_hash_u64vp_get_direct(const M_hash_u64vp_t *h, M_uint64 key);
164
165
166/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
167
168/*! Wether the hashtable a multi value table.
169 *
170 * \param[in] h Hashtable being referenced.
171 *
172 * \return M_TRUE if a multi value hashtable.
173 */
175
176
177/*! Get the number of values for a given key.
178 *
179 * \param[in] h Hashtable being referenced.
180 * \param[in] key Key for value to retrieve.
181 * \param[out] len The number of values.
182 *
183 * \return M_TRUE if length is retrieved, M_FALSE if key does not exist.
184 */
185M_API M_bool M_hash_u64vp_multi_len(const M_hash_u64vp_t *h, M_uint64 key, size_t *len);
186
187
188/*! Retrieve the value for a key from the given index when supporting muli-values.
189 *
190 * \param[in] h Hashtable being referenced.
191 * \param[in] key Key for value to retrieve.
192 * \param[in] idx The index the value resides at.
193 * \param[out] value Pointer to value stored. Optional, pass NULL if not needed.
194 *
195 * \return M_TRUE if value retrieved, M_FALSE if key does not exist
196 */
197M_API M_bool M_hash_u64vp_multi_get(const M_hash_u64vp_t *h, M_uint64 key, size_t idx, void **value);
198
199
200/*! Retrieve the value for a key from the given index when supporting muli-values.
201 *
202 * \param[in] h Hashtable being referenced.
203 * \param[in] key Key for value to retrieve.
204 * \param[in] idx The index the value resides at.
205 *
206 * \return M_TRUE if value retrieved, M_FALSE if key does not exist.
207 */
208M_API void *M_hash_u64vp_multi_get_direct(const M_hash_u64vp_t *h, M_uint64 key, size_t idx);
209
210
211/*! Remove a value from the hashtable when supporting muli-values.
212 *
213 * If all values have been removed then the key will be removed.
214 *
215 * \param[in,out] h Hashtable being referenced
216 * \param[in] key Key for value to retrieve.
217 * \param[in] idx The index the value resides at.
218 * \param[in] destroy_vals M_TRUE if the value held by the hashtable should be destroyed.
219 * This will almost always be M_TRUE. This should only be set to M_FALSE
220 * when the value held by the hashtable is being managed externally.
221 *
222 * \return M_TRUE if the value was removed, M_FALSE if key does not exist.
223 */
224M_API M_bool M_hash_u64vp_multi_remove(M_hash_u64vp_t *h, M_uint64 key, size_t idx, M_bool destroy_vals);
225
226
227/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
228
229/*! Retrieve the current size (number of buckets/slots, not necessarily used).
230 *
231 * \param[in] h Hashtable being referenced.
232 *
233 * \return Size of the hashtable
234 */
235M_API M_uint32 M_hash_u64vp_size(const M_hash_u64vp_t *h);
236
237/*! Retrieve the number of collisions for hashtable entries that has occurred since creation.
238 *
239 * \param[in] h Hashtable being referenced.
240 *
241 * \return Number of collisions.
242 */
244
245
246/*! Retrieve the number of expansions/rehashes since creation.
247 *
248 * \param[in] h Hashtable being referenced.
249 *
250 * \return number of expansions/rehashes.
251 */
253
254
255/*! Retrieve the number of entries in the hashtable.
256 *
257 * This is the number of keys stored.
258 *
259 * \param[in] h Hashtable being referenced.
260 *
261 * \return number of entries in the hashtable.
262 */
264
265
266/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
267
268/*! Start an enumeration of the keys within a hashtable.
269 *
270 * \param[in] h Hashtable being referenced.
271 * \param[out] hashenum Outputs an initialized state variable for starting an enumeration.
272 *
273 * \return Number of items in the hashtable
274 *
275 * \see M_hash_strvp_enumerate_free
276 */
278
279
280/*! Retrieve the next item from a hashtable enumeration.
281 *
282 * If multi-value, keys will appear multiple times as each value will be
283 * retrieved individually.
284 *
285 * \param[in] h Hashtable being referenced.
286 * \param[in,out] hashenum State variable for tracking the enumeration process.
287 * \param[out] key Value of next enumerated key. Optional, pass NULL if not needed.
288 * \param[out] value Value of next enumerated value. Optional, pass NULL if not needed.
289 *
290 * \return M_TRUE if enumeration succeeded, M_FALSE if no more keys.
291 */
292M_API M_bool M_hash_u64vp_enumerate_next(const M_hash_u64vp_t *h, M_hash_u64vp_enum_t *hashenum, M_uint64 *key, void **value);
293
294
295/*! Destroy an enumeration state.
296 *
297 * \param[in] hashenum Enumeration to destroy.
298 */
300
301
302/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
303
304/*! Merge two hashtables together.
305 *
306 * The second (src) hashtable will be destroyed automatically upon completion of this function. Any key/value
307 * pointers for the hashtable will be directly copied over to the destination hashtable, they will not be
308 * duplicated. Any keys which exist in 'dest' that also exist in 'src' will be overwritten by the 'src' value.
309 *
310 * If dest and src are multi-value, all values from src will be copied into dest and the values from
311 * dest will not be removed. If dest is not multi-value and src is, then only the last value in src will
312 * be present in dest. If dest is multi-value and src is not, then the value from src will be added to dest.
313 *
314 * \param[in,out] dest Pointer by reference to the hashtable receiving the key/value pairs.
315 * if dest is NULL, the src address will simply be copied to dest.
316 * \param[in,out] src Pointer to the hashtable giving up its key/value pairs.
317 */
318M_API void M_hash_u64vp_merge(M_hash_u64vp_t **dest, M_hash_u64vp_t *src) M_FREE(2);
319
320/*! @} */
321
322__END_DECLS
323
324#endif /* __M_HASH_U64VP_H__ */
M_bool M_hash_u64vp_is_multi(const M_hash_u64vp_t *h)
M_bool M_hash_u64vp_multi_get(const M_hash_u64vp_t *h, M_uint64 key, size_t idx, void **value)
void M_hash_u64vp_merge(M_hash_u64vp_t **dest, M_hash_u64vp_t *src) M_FREE(2)
M_hash_u64vp_flags_t
Definition: m_hash_u64vp.h:61
M_hash_u64vp_t * M_hash_u64vp_create(size_t size, M_uint8 fillpct, M_uint32 flags, void(*destroy_func)(void *)) M_MALLOC_ALIASED
void * M_hash_u64vp_multi_get_direct(const M_hash_u64vp_t *h, M_uint64 key, size_t idx)
M_bool M_hash_u64vp_get(const M_hash_u64vp_t *h, M_uint64 key, void **value)
void M_hash_u64vp_enumerate_free(M_hash_u64vp_enum_t *hashenum)
size_t M_hash_u64vp_num_expansions(const M_hash_u64vp_t *h)
size_t M_hash_u64vp_num_keys(const M_hash_u64vp_t *h)
size_t M_hash_u64vp_enumerate(const M_hash_u64vp_t *h, M_hash_u64vp_enum_t **hashenum)
struct M_hash_u64vp M_hash_u64vp_t
Definition: m_hash_u64vp.h:53
M_bool M_hash_u64vp_multi_remove(M_hash_u64vp_t *h, M_uint64 key, size_t idx, M_bool destroy_vals)
M_bool M_hash_u64vp_insert(M_hash_u64vp_t *h, M_uint64 key, void *value)
size_t M_hash_u64vp_num_collisions(const M_hash_u64vp_t *h)
M_bool M_hash_u64vp_enumerate_next(const M_hash_u64vp_t *h, M_hash_u64vp_enum_t *hashenum, M_uint64 *key, void **value)
void M_hash_u64vp_destroy(M_hash_u64vp_t *h, M_bool destroy_vals) M_FREE(1)
M_bool M_hash_u64vp_multi_len(const M_hash_u64vp_t *h, M_uint64 key, size_t *len)
void * M_hash_u64vp_get_direct(const M_hash_u64vp_t *h, M_uint64 key)
M_bool M_hash_u64vp_remove(M_hash_u64vp_t *h, M_uint64 key, M_bool destroy_vals)
struct M_hash_u64vp_enum M_hash_u64vp_enum_t
Definition: m_hash_u64vp.h:57
M_uint32 M_hash_u64vp_size(const M_hash_u64vp_t *h)
@ M_HASH_U64VP_STATIC_SEED
Definition: m_hash_u64vp.h:71
@ M_HASH_U64VP_MULTI_GETLAST
Definition: m_hash_u64vp.h:69
@ M_HASH_U64VP_KEYS_SORTDESC
Definition: m_hash_u64vp.h:66
@ M_HASH_U64VP_KEYS_ORDERED
Definition: m_hash_u64vp.h:63
@ M_HASH_U64VP_NONE
Definition: m_hash_u64vp.h:62
@ M_HASH_U64VP_MULTI_VALUE
Definition: m_hash_u64vp.h:67
@ M_HASH_U64VP_KEYS_SORTASC
Definition: m_hash_u64vp.h:65