tommyhashlin.h
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-2-Clause
2// Copyright (C) 2010 Andrea Mazzoleni
3
161#ifndef TOMMY_HASHLIN_H
162#define TOMMY_HASHLIN_H
163
164#include "tommyhash.h"
165#include "tommylist.h"
166
167/******************************************************************************/
168/* hashlin */
169
174#define TOMMY_HASHLIN_BIT 6
175
181
186typedef struct tommy_hashlin_struct {
187 tommy_hashlin_node** bucket[TOMMY_SIZE_BIT];
197
202TOMMY_API void tommy_hashlin_init(tommy_hashlin* hashlin);
203
211TOMMY_API void tommy_hashlin_done(tommy_hashlin* hashlin);
212
222tommy_inline void tommy_hashlin_swap(tommy_hashlin* first, tommy_hashlin* second)
223{
224 tommy_hashlin tmp = *first;
225 *first = *second;
226 *second = tmp;
227}
228
244TOMMY_API void tommy_hashlin_clear(tommy_hashlin* hashlin);
245
253TOMMY_API void tommy_hashlin_insert(tommy_hashlin* hashlin, tommy_hashlin_node* node, void* data, tommy_hash_t hash);
254
271TOMMY_API void* tommy_hashlin_insert_unique(tommy_hashlin* hashlin, tommy_hashlin_node* node, void* data, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash);
272
285TOMMY_API void* tommy_hashlin_remove(tommy_hashlin* hashlin, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash);
286
290tommy_inline tommy_hashlin_node** tommy_hashlin_pos(tommy_hashlin* hashlin, tommy_hash_t pos)
291{
292 tommy_uint_t bsr;
293
294 /* get the highest bit set, in case of all 0, return 0 */
295 bsr = tommy_ilog2(pos | 1);
296
297 return &hashlin->bucket[bsr][pos];
298}
299
303tommy_inline tommy_hashlin_node** tommy_hashlin_bucket_ref(tommy_hashlin* hashlin, tommy_hash_t hash)
304{
305 tommy_size_t pos = hash & hashlin->low_mask;
306 tommy_size_t high_pos = hash & hashlin->bucket_mask;
307
308 /* if this position is already allocated in the high half */
309 if (pos < hashlin->split) {
310 /* the following assignment is expected to be implemented */
311 /* with a conditional move instruction */
312 /* that results in a little better and constant performance */
313 /* regardless of the split position. */
314 /* this affects mostly the worst case, when the split value */
315 /* is near at its half, resulting in a totally unpredictable */
316 /* condition by the CPU. */
317 /* in such case, the use of the conditional move is generally faster. */
318
319 /* use also the high bit */
320 pos = high_pos;
321 }
322
323 return tommy_hashlin_pos(hashlin, pos);
324}
325
336{
337 return *tommy_hashlin_bucket_ref(hashlin, hash);
338}
339
351tommy_inline tommy_hashlin_node* tommy_hashlin_find(tommy_hashlin* hashlin, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
352{
353 tommy_hashlin_node* i = tommy_hashlin_bucket(hashlin, hash);
354
355 while (i) {
356 /* we first check if the hash matches, as in the same bucket we may have multiple hash values */
357 if (i->index == hash && cmp(cmp_arg, i->data) == 0)
358 return i;
359 i = i->next;
360 }
361 return 0;
362}
363
375tommy_inline void* tommy_hashlin_search(tommy_hashlin* hashlin, tommy_search_func* cmp, const void* cmp_arg, tommy_hash_t hash)
376{
377 tommy_hashlin_node* node = tommy_hashlin_find(hashlin, cmp, cmp_arg, hash);
378
379 return node ? node->data : 0;
380}
381
390
402
414
427
440
458
497
507TOMMY_API void tommy_hashlin_foreach_arg(tommy_hashlin* hashlin, tommy_foreach_arg_func* func, void* arg);
508
516{
517 return hashlin->count;
518}
519
527{
528 return hashlin->count == 0;
529}
530
539{
540 return hashlin->low_max + hashlin->split;
541}
542
550
592TOMMY_API void tommy_hashlin_to_list(tommy_hashlin* hashlin, tommy_list* list);
593
594#endif
595
Hashtable container type.
Definition: tommyhashlin.h:186
tommy_uint_t bucket_bit
Bits used in the bit mask.
Definition: tommyhashlin.h:194
tommy_size_t bucket_mask
Bit mask to access the buckets.
Definition: tommyhashlin.h:189
tommy_size_t low_max
Low order max value.
Definition: tommyhashlin.h:190
tommy_size_t low_mask
Low order mask value.
Definition: tommyhashlin.h:191
tommy_size_t split
Split position.
Definition: tommyhashlin.h:192
tommy_size_t bucket_max
Number of buckets.
Definition: tommyhashlin.h:188
tommy_hashlin_node ** bucket[TOMMY_SIZE_BIT]
Dynamic array of hash buckets.
Definition: tommyhashlin.h:187
tommy_size_t count
Number of elements.
Definition: tommyhashlin.h:193
tommy_uint_t state
Reallocation state.
Definition: tommyhashlin.h:195
Data structure node.
Definition: tommytypes.h:242
tommy_size_t index
Index of the node.
Definition: tommytypes.h:269
struct tommy_node_struct * next
Next node.
Definition: tommytypes.h:247
void * data
Pointer to the element containing the node.
Definition: tommytypes.h:260
Hash functions for use with tommy_hashtable, tommy_hashdyn and tommy_hashlin.
void tommy_hashlin_swap(tommy_hashlin *first, tommy_hashlin *second)
Exchanges the complete state of two initialized hashtables, including bucket allocations and progress...
Definition: tommyhashlin.h:222
tommy_hashlin_node * tommy_hashlin_bucket(tommy_hashlin *hashlin, tommy_hash_t hash)
Gets the bucket of the specified hash.
Definition: tommyhashlin.h:335
struct tommy_hashlin_struct tommy_hashlin
Hashtable container type.
tommy_hashlin_node * tommy_hashlin_find(tommy_hashlin *hashlin, tommy_search_func *cmp, const void *cmp_arg, tommy_hash_t hash)
Finds a node in the hashtable.
Definition: tommyhashlin.h:351
TOMMY_API tommy_hashlin_node * tommy_hashlin_prev(tommy_hashlin *hashlin, tommy_hashlin_node *node)
Gets the preceding node in iteration order, or 0 for the head.
TOMMY_API void tommy_hashlin_foreach_arg(tommy_hashlin *hashlin, tommy_foreach_arg_func *func, void *arg)
Calls the specified function with an argument for each element in the hashtable.
TOMMY_API tommy_hashlin_node * tommy_hashlin_head(tommy_hashlin *hashlin)
Gets the first node in iteration order, or 0 if empty.
TOMMY_API void tommy_hashlin_insert(tommy_hashlin *hashlin, tommy_hashlin_node *node, void *data, tommy_hash_t hash)
Inserts an element in the hashtable.
TOMMY_API tommy_size_t tommy_hashlin_memory_usage(const tommy_hashlin *hashlin)
Gets the size of allocated memory.
TOMMY_API void tommy_hashlin_clear(tommy_hashlin *hashlin)
Removes all elements and resets the hashtable to its initial state.
TOMMY_API void * tommy_hashlin_remove(tommy_hashlin *hashlin, tommy_search_func *cmp, const void *cmp_arg, tommy_hash_t hash)
Searches and removes an element from the hashtable.
TOMMY_API void tommy_hashlin_rehash_existing(tommy_hashlin *hashlin, tommy_hashlin_node *node, tommy_hash_t hash)
Updates the hash of an element already contained in the hashtable.
TOMMY_API void tommy_hashlin_foreach(tommy_hashlin *hashlin, tommy_foreach_func *func)
Calls the specified function for each element in the hashtable.
tommy_node tommy_hashlin_node
Hashtable node.
Definition: tommyhashlin.h:180
TOMMY_API void * tommy_hashlin_insert_unique(tommy_hashlin *hashlin, tommy_hashlin_node *node, void *data, tommy_search_func *cmp, const void *cmp_arg, tommy_hash_t hash)
Inserts an element only if no equal element is already contained.
TOMMY_API tommy_hashlin_node * tommy_hashlin_tail(tommy_hashlin *hashlin)
Gets the last node in iteration order, or 0 if empty.
tommy_size_t tommy_hashlin_bucket_count(const tommy_hashlin *hashlin)
Gets the number of active buckets.
Definition: tommyhashlin.h:538
TOMMY_API void tommy_hashlin_to_list(tommy_hashlin *hashlin, tommy_list *list)
Transfers all elements from the hashtable into a tommy_list.
void * tommy_hashlin_search(tommy_hashlin *hashlin, tommy_search_func *cmp, const void *cmp_arg, tommy_hash_t hash)
Searches an element in the hashtable.
Definition: tommyhashlin.h:375
TOMMY_API void tommy_hashlin_done(tommy_hashlin *hashlin)
Deinitializes the hashtable.
tommy_size_t tommy_hashlin_count(const tommy_hashlin *hashlin)
Gets the number of elements.
Definition: tommyhashlin.h:515
tommy_bool_t tommy_hashlin_empty(const tommy_hashlin *hashlin)
Checks whether the hashtable is empty.
Definition: tommyhashlin.h:526
TOMMY_API tommy_hashlin_node * tommy_hashlin_next(tommy_hashlin *hashlin, tommy_hashlin_node *node)
Gets the following node in iteration order, or 0 for the tail.
TOMMY_API void tommy_hashlin_init(tommy_hashlin *hashlin)
Initializes the hashtable.
TOMMY_API void * tommy_hashlin_remove_existing(tommy_hashlin *hashlin, tommy_hashlin_node *node)
Removes an element from the hashtable.
Doubly linked list for collisions into hashtables.
void tommy_foreach_func(void *elem)
Foreach function.
Definition: tommytypes.h:346
int tommy_search_func(const void *arg, const void *elem)
Search function for elements.
Definition: tommytypes.h:334
uint64_t tommy_size_t
Generic size_t type.
Definition: tommytypes.h:40
#define tommy_ilog2
Bit depth mapping.
Definition: tommytypes.h:573
void tommy_foreach_arg_func(void *arg, void *elem)
Foreach function with an argument.
Definition: tommytypes.h:353
tommy_size_t tommy_hash_t
Type used in hashtables to store the hash of an element.
Definition: tommytypes.h:224
tommy_uint32_t tommy_uint_t
Generic unsigned integer type.
Definition: tommytypes.h:61
int tommy_bool_t
Generic boolean type.
Definition: tommytypes.h:53