Mstdlib-1.24.0
m_hash_u64u64.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2017 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_U64U64_H__
25#define __M_HASH_U64U64_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_u64u64 Hashtable - uint64/uint64
37 * \ingroup m_hashtable
38 *
39 * Hashtable, meant for storing uint64 keys and uint64 values.
40 * This is useful for using an enum value as a key with an
41 * integer value.
42 *
43 * References to the data will always be read-only.
44 * All keys and values will be duplicated by the hashtable.
45 *
46 * @{
47 */
48
49struct M_hash_u64u64;
50/* Currently a direct map to M_hashtable private opaque type,
51 * simply using casting to prevent the 'wrap' overhead of mallocing when it
52 * is not necessary.
53 */
54typedef struct M_hash_u64u64 M_hash_u64u64_t;
55
56struct M_hash_u64u64_enum;
57/* Used for enumerating a M_hash_u64bin. */
58typedef struct M_hash_u64u64_enum M_hash_u64u64_enum_t;
59
60
61/*! Flags for controlling the behavior of the hashtable */
62typedef enum {
63 M_HASH_U64U64_NONE = 0, /*!< Case sensitive single value (new values replace). */
64 M_HASH_U64U64_KEYS_ORDERED = 1 << 0, /*!< Keys should be ordered. Default is insertion order unless the
65 sorted option is specified. */
66 M_HASH_U64U64_KEYS_SORTASC = 1 << 1, /*!< When the keys are ordered sort them using the key_equality function. */
67 M_HASH_U64U64_KEYS_SORTDESC = 1 << 2, /*!< When the keys are ordered sort them using the key_equality function. */
68 M_HASH_U64U64_MULTI_VALUE = 1 << 3, /*!< Allow keys to contain multiple values.
69 Sorted in insertion order another sorting is specified. */
70 M_HASH_U64U64_MULTI_SORTASC = 1 << 4, /*!< Allow keys to contain multiple values sorted in ascending order */
71 M_HASH_U64U64_MULTI_SORTDESC = 1 << 5, /*!< Allow keys to contain multiple values sorted in descending order */
72 M_HASH_U64U64_MULTI_GETLAST = 1 << 6, /*!< When using get and get_direct function get the last value from the list
73 when allowing multiple values. The default is to get the first value. */
74 M_HASH_U64U64_STATIC_SEED = 1 << 7 /*!< Use a static seed for hash function initialization. This greatly reduces
75 the security of the hashtable and removes collision attack protections.
76 This should only be used as a performance optimization when creating
77 millions of hashtables with static data specifically for quick look up.
78 DO _NOT_ use this flag with any hashtable that could store user
79 generated data! Be very careful about duplicating a hashtable that
80 was created with this flag. All duplicates will use the static seed. */
82
83
84/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
85
86/*! Create a new hashtable.
87 *
88 * The hashtable will pre-allocate an array of buckets based on the rounded up size specified. Any hash collisions
89 * will result in those collisions being chained together via a linked list. The hashtable will auto-expand by a
90 * power of 2 when the fill percentage specified is reached. All key entries are compared in a case-insensitive
91 * fashion, and are duplicated internally. Values are duplicated. Case is preserved for both keys and values.
92 *
93 * \param[in] size Size of the hash table. If not specified as a power of 2, will
94 * be rounded up to the nearest power of 2.
95 * \param[in] fillpct The maximum fill percentage before the hash table is expanded. If
96 * 0 is specified, the hashtable will never expand, otherwise the
97 * value must be between 1 and 99 (recommended: 75).
98 * \param[in] flags M_hash_u64u64_flags_t flags for modifying behavior.
99 *
100 * \return Allocated hashtable.
101 *
102 * \see M_hash_u64u64_destroy
103 */
104M_API M_hash_u64u64_t *M_hash_u64u64_create(size_t size, M_uint8 fillpct, M_uint32 flags) M_MALLOC;
105
106
107/*! Destroy the hashtable.
108 *
109 * \param[in] h Hashtable to destroy
110 */
111M_API void M_hash_u64u64_destroy(M_hash_u64u64_t *h) M_FREE(1);
112
113
114/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
115
116/*! Insert an entry into the hashtable.
117 *
118 * \param[in,out] h Hashtable being referenced.
119 * \param[in] key Key to insert.
120 * \param[in] value Value to insert into hashtable. Value will be duplicated,
121 * and case will be preserved. May be NULL.
122 *
123 * \return M_TRUE on success, or M_FALSE on failure.
124 */
125M_API M_bool M_hash_u64u64_insert(M_hash_u64u64_t *h, M_uint64 key, M_uint64 value);
126
127
128/*! Remove an entry from the hashtable.
129 *
130 * \param[in,out] h Hashtable being referenced.
131 * \param[in] key Key to remove from the hashtable.
132 *
133 * \return M_TRUE on success, or M_FALSE if key does not exist.
134 */
135M_API M_bool M_hash_u64u64_remove(M_hash_u64u64_t *h, M_uint64 key);
136
137
138/*! Retrieve the value for a key from the hashtable.
139 *
140 * \param[in] h Hashtable being referenced.
141 * \param[in] key Key for value.
142 * \param[out] value Pointer to value stored in the hashtable. Optional, pass NULL if not needed.
143 *
144 * \return M_TRUE if value retrieved, M_FALSE if key does not exist.
145 */
146M_API M_bool M_hash_u64u64_get(const M_hash_u64u64_t *h, M_uint64 key, M_uint64 *value);
147
148
149/*! Retrieve the value for a key from the hashtable, and return it directly as the return value.
150 *
151 * This cannot be used if you need to differentiate between a key that doesn't exist vs a key with a NULL value.
152 *
153 * \param[in] h Hashtable being referenced.
154 * \param[in] key Key for value to retrieve from the hashtable.
155 *
156 * \return NULL if key doesn't exist or NULL value on file, otherwise the value.
157 */
158M_API M_uint64 M_hash_u64u64_get_direct(const M_hash_u64u64_t *h, M_uint64 key);
159
160
161/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
162
163/*! Wether the hashtable a multi value table.
164 *
165 * \param[in] h Hashtable being referenced.
166 *
167 * \return M_TRUE if a multi value hashtable.
168 */
170
171
172/*! Get the number of values for a given key.
173 *
174 * \param[in] h Hashtable being referenced.
175 * \param[in] key Key for value to retrieve.
176 * \param[out] len The number of values.
177 *
178 * \return M_TRUE if length is retrieved, M_FALSE if key does not exist.
179 */
180M_API M_bool M_hash_u64u64_multi_len(const M_hash_u64u64_t *h, M_uint64 key, size_t *len);
181
182
183/*! Retrieve the value for a key from the given index when supporting muli-values.
184 *
185 * \param[in] h Hashtable being referenced.
186 * \param[in] key Key for value to retrieve.
187 * \param[in] idx The index the value resides at.
188 * \param[out] value Pointer to value stored. Optional, pass NULL if not needed.
189 *
190 * \return M_TRUE if value retrieved, M_FALSE if key does not exist
191 */
192M_API M_bool M_hash_u64u64_multi_get(const M_hash_u64u64_t *h, M_uint64 key, size_t idx, M_uint64 *value);
193
194
195/*! Retrieve the value for a key from the given index when supporting muli-values.
196 *
197 * \param[in] h Hashtable being referenced.
198 * \param[in] key Key for value to retrieve.
199 * \param[in] idx The index the value resides at.
200 *
201 * \return M_TRUE if value retrieved, M_FALSE if key does not exist.
202 */
203M_API M_uint64 M_hash_u64u64_multi_get_direct(const M_hash_u64u64_t *h, M_uint64 key, size_t idx);
204
205
206/*! Remove a value from the hashtable when supporting muli-values.
207 *
208 * If all values have been removed then the key will be removed.
209 *
210 * \param[in,out] h Hashtable being referenced
211 * \param[in] key Key for value to retrieve.
212 * \param[in] idx The index the value resides at.
213 *
214 * \return M_TRUE if the value was removed, M_FALSE if key does not exist.
215 */
216M_API M_bool M_hash_u64u64_multi_remove(M_hash_u64u64_t *h, M_uint64 key, size_t idx);
217
218
219/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
220
221/*! Retrieve the current size (number of buckets/slots, not necessarily used).
222 *
223 * \param[in] h Hashtable being referenced.
224 *
225 * \return Size of the hashtable.
226 */
227M_API M_uint32 M_hash_u64u64_size(const M_hash_u64u64_t *h);
228
229
230/*! Retrieve the number of collisions for hashtable entries that has occurred since creation.
231 *
232 * \param[in] h Hashtable being referenced.
233 *
234 * \return Number of collisions.
235 */
237
238
239/*! Retrieve the number of expansions/rehashes since creation.
240 *
241 * \param[in] h Hashtable being referenced.
242 *
243 * \return number of expansions/rehashes.
244 */
246
247
248/*! Retrieve the number of entries in the hashtable.
249 *
250 * This is the number of keys stored.
251 *
252 * \param[in] h Hashtable being referenced.
253 *
254 * \return number of entries in the hashtable.
255 */
257
258
259/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
260
261/*! Start an enumeration of the keys within the hashtable.
262 *
263 * \param[in] h Hashtable being referenced.
264 * \param[out] hashenum Outputs an initialized state variable for starting an enumeration.
265 *
266 * \return Number of values in the hashtable.
267 *
268 * \see M_hash_u64u64_enumerate_free
269 */
271
272
273/*! Retrieve the next item from a hashtable enumeration.
274 *
275 * If multi-value, keys will appear multiple times as each value will be
276 * retrieved individually.
277 *
278 * \param[in] h Hashtable being referenced.
279 * \param[in,out] hashenum State variable for tracking the enumeration process.
280 * \param[out] key Value of next enumerated key. Optional, pass NULL if not needed.
281 * \param[out] value Value of next enumerated value. Optional, pass NULL if not needed.
282 *
283 * \return M_TRUE if enumeration succeeded, M_FALSE if no more keys.
284 */
285M_API M_bool M_hash_u64u64_enumerate_next(const M_hash_u64u64_t *h, M_hash_u64u64_enum_t *hashenum, M_uint64 *key, M_uint64 *value);
286
287
288/*! Destroy an enumeration state.
289 *
290 * \param[in] hashenum Enumeration to destroy.
291 */
293
294
295/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
296
297/*! Merge two hashtables together.
298 *
299 * The second (src) hashtable will be destroyed automatically upon completion of this function. Any key/value
300 * pointers for the hashtable will be directly copied over to the destination hashtable, they will not be
301 * duplicated. Any keys which exist in 'dest' that also exist in 'src' will be overwritten by the 'src' value.
302 *
303 * If dest and src are multi-value, all values from src will be copied into dest and the values from
304 * dest will not be removed. If dest is not multi-value and src is, then only the last value in src will
305 * be present in dest. If dest is multi-value and src is not, then the value from src will be added to dest.
306 *
307 * \param[in,out] dest Pointer by reference to the hashtable receiving the key/value pairs.
308 * if dest is NULL, the src address will simply be copied to dest.
309 * \param[in,out] src Pointer to the hashtable giving up its key/value pairs.
310 */
311M_API void M_hash_u64u64_merge(M_hash_u64u64_t **dest, M_hash_u64u64_t *src) M_FREE(2);
312
313/*! Duplicate an existing hashtable.
314 *
315 * Copying all keys and values.
316 *
317 * \param[in] h Hashtable to be copied.
318 *
319 * \return Duplicated hashtable.
320 */
322
323/*! @} */
324
325__END_DECLS
326
327#endif /* __M_HASH_U64U64_H__ */
M_hash_u64u64_t * M_hash_u64u64_duplicate(const M_hash_u64u64_t *h) M_MALLOC
M_uint64 M_hash_u64u64_multi_get_direct(const M_hash_u64u64_t *h, M_uint64 key, size_t idx)
M_bool M_hash_u64u64_multi_len(const M_hash_u64u64_t *h, M_uint64 key, size_t *len)
M_hash_u64u64_t * M_hash_u64u64_create(size_t size, M_uint8 fillpct, M_uint32 flags) M_MALLOC
size_t M_hash_u64u64_num_collisions(const M_hash_u64u64_t *h)
M_uint64 M_hash_u64u64_get_direct(const M_hash_u64u64_t *h, M_uint64 key)
M_bool M_hash_u64u64_insert(M_hash_u64u64_t *h, M_uint64 key, M_uint64 value)
M_hash_u64u64_flags_t
Definition: m_hash_u64u64.h:62
struct M_hash_u64u64_enum M_hash_u64u64_enum_t
Definition: m_hash_u64u64.h:58
void M_hash_u64u64_merge(M_hash_u64u64_t **dest, M_hash_u64u64_t *src) M_FREE(2)
M_bool M_hash_u64u64_is_multi(const M_hash_u64u64_t *h)
struct M_hash_u64u64 M_hash_u64u64_t
Definition: m_hash_u64u64.h:54
M_bool M_hash_u64u64_multi_get(const M_hash_u64u64_t *h, M_uint64 key, size_t idx, M_uint64 *value)
size_t M_hash_u64u64_num_keys(const M_hash_u64u64_t *h)
size_t M_hash_u64u64_enumerate(const M_hash_u64u64_t *h, M_hash_u64u64_enum_t **hashenum)
void M_hash_u64u64_enumerate_free(M_hash_u64u64_enum_t *hashenum)
M_bool M_hash_u64u64_remove(M_hash_u64u64_t *h, M_uint64 key)
M_bool M_hash_u64u64_enumerate_next(const M_hash_u64u64_t *h, M_hash_u64u64_enum_t *hashenum, M_uint64 *key, M_uint64 *value)
M_bool M_hash_u64u64_multi_remove(M_hash_u64u64_t *h, M_uint64 key, size_t idx)
M_bool M_hash_u64u64_get(const M_hash_u64u64_t *h, M_uint64 key, M_uint64 *value)
size_t M_hash_u64u64_num_expansions(const M_hash_u64u64_t *h)
M_uint32 M_hash_u64u64_size(const M_hash_u64u64_t *h)
void M_hash_u64u64_destroy(M_hash_u64u64_t *h) M_FREE(1)
@ M_HASH_U64U64_MULTI_GETLAST
Definition: m_hash_u64u64.h:72
@ M_HASH_U64U64_NONE
Definition: m_hash_u64u64.h:63
@ M_HASH_U64U64_KEYS_SORTDESC
Definition: m_hash_u64u64.h:67
@ M_HASH_U64U64_KEYS_ORDERED
Definition: m_hash_u64u64.h:64
@ M_HASH_U64U64_MULTI_SORTASC
Definition: m_hash_u64u64.h:70
@ M_HASH_U64U64_MULTI_SORTDESC
Definition: m_hash_u64u64.h:71
@ M_HASH_U64U64_MULTI_VALUE
Definition: m_hash_u64u64.h:68
@ M_HASH_U64U64_KEYS_SORTASC
Definition: m_hash_u64u64.h:66
@ M_HASH_U64U64_STATIC_SEED
Definition: m_hash_u64u64.h:74