cdcontainers  0.1.1
Library of data containers and collections for C programming language.
hash-table.h
Go to the documentation of this file.
1 // The MIT License (MIT)
2 // Copyright (c) 2018 Maksim Andrianov
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to
6 // deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 // sell copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 // IN THE SOFTWARE.
26 #ifndef CDCONTAINERS_INCLUDE_CDCONTAINERS_HASH_TABLE_H
27 #define CDCONTAINERS_INCLUDE_CDCONTAINERS_HASH_TABLE_H
28 
29 #include <cdcontainers/common.h>
30 #include <cdcontainers/hash.h>
31 #include <cdcontainers/status.h>
32 
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <stdbool.h>
36 #include <stdlib.h>
37 
50  void *key;
51  void *value;
52  size_t hash;
53 };
54 
63  size_t bcount;
64  float load_factor;
65  size_t size;
67 };
68 
77 };
78 // Base
91  struct cdc_data_info *info);
92 
114  struct cdc_data_info *info, ...);
115 
125  struct cdc_data_info *info, va_list args);
126 
136  struct cdc_data_info *info,
137  float load_factor);
138 
150  struct cdc_data_info *info,
151  float load_factor, ...);
152 
163  struct cdc_data_info *info,
164  float load_factor, va_list args);
165 
170 void cdc_hash_table_dtor(struct cdc_hash_table *t);
173 // Lookup
186 enum cdc_stat cdc_hash_table_get(struct cdc_hash_table *t, void *key,
187  void **value);
188 
197 size_t cdc_hash_table_count(struct cdc_hash_table *t, void *key);
198 
207 void cdc_hash_table_find(struct cdc_hash_table *t, void *key,
208  struct cdc_hash_table_iter *it);
211 // Capacity
221 static inline size_t cdc_hash_table_size(struct cdc_hash_table *t)
222 {
223  assert(t != NULL);
224 
225  return t->size;
226 }
227 
233 static inline bool cdc_hash_table_empty(struct cdc_hash_table *t)
234 {
235  assert(t != NULL);
236 
237  return t->size == 0;
238 }
241 // Modifiers
250 void cdc_hash_table_clear(struct cdc_hash_table *t);
251 
264 enum cdc_stat cdc_hash_table_insert(struct cdc_hash_table *t, void *key,
265  void *value, struct cdc_hash_table_iter *it,
266  bool *inserted);
267 
281  void *key, void *value,
282  struct cdc_hash_table_iter *it,
283  bool *inserted);
284 
291 size_t cdc_hash_table_erase(struct cdc_hash_table *t, void *key);
292 
298 void cdc_hash_table_swap(struct cdc_hash_table *a, struct cdc_hash_table *b);
301 // Iterators
311 static inline void cdc_hash_table_begin(struct cdc_hash_table *t,
312  struct cdc_hash_table_iter *it)
313 {
314  assert(t != NULL);
315  assert(it != NULL);
316 
317  it->container = t;
318  it->current = t->buckets[0]->next;
319 }
320 
326 static inline void cdc_hash_table_end(struct cdc_hash_table *t,
327  struct cdc_hash_table_iter *it)
328 {
329  assert(t != NULL);
330  assert(it != NULL);
331 
332  it->container = t;
333  it->current = NULL;
334 }
337 // Hash policy
347 static inline float cdc_hash_table_load_factor(struct cdc_hash_table *t)
348 {
349  assert(t != NULL);
350 
351  return (float)t->size / (float)t->bcount;
352 }
353 
359 static inline float cdc_hash_table_max_load_factor(struct cdc_hash_table *t)
360 {
361  assert(t != NULL);
362 
363  return t->load_factor;
364 }
365 
372  float load_factor)
373 {
374  assert(t != NULL);
375 
376  t->load_factor = load_factor;
377 }
378 
387 enum cdc_stat cdc_hash_table_rehash(struct cdc_hash_table *t, size_t count);
388 
397 enum cdc_stat cdc_hash_table_reserve(struct cdc_hash_table *t, size_t count);
400 // Bucket interface
410 static inline size_t cdc_hash_table_bucket_count(struct cdc_hash_table *t)
411 {
412  assert(t != NULL);
413 
414  return t->bcount;
415 }
418 // Iterators
428 static inline void cdc_hash_table_iter_next(struct cdc_hash_table_iter *it)
429 {
430  assert(it != NULL);
431 
432  it->current = it->current->next;
433 }
434 
442 static inline bool cdc_hash_table_iter_has_next(struct cdc_hash_table_iter *it)
443 {
444  assert(it != NULL);
445 
446  return it->current != NULL;
447 }
448 
454 static inline void *cdc_hash_table_iter_key(struct cdc_hash_table_iter *it)
455 {
456  assert(it != NULL);
457 
458  return it->current->key;
459 }
460 
466 static inline void *cdc_hash_table_iter_value(struct cdc_hash_table_iter *it)
467 {
468  assert(it != NULL);
469 
470  return it->current->value;
471 }
472 
479  struct cdc_hash_table_iter *it)
480 {
481  assert(it != NULL);
482 
483  struct cdc_pair pair = {it->current->key, it->current->value};
484  return pair;
485 }
486 
495 static inline bool cdc_hash_table_iter_is_eq(struct cdc_hash_table_iter *it1,
496  struct cdc_hash_table_iter *it2)
497 {
498  assert(it1 != NULL);
499  assert(it2 != NULL);
500 
501  return it1->container == it2->container && it1->current == it2->current;
502 }
505 // Short names
506 #ifdef CDC_USE_SHORT_NAMES
507 typedef struct cdc_hash_table hash_table_t;
508 typedef struct cdc_hash_table_iter hash_table_iter_t;
509 typedef struct cdc_pair_hash_table_iter pair_hash_table_iter_t;
510 typedef struct cdc_pair_hash_table_iter_bool pair_hash_table_iter_bool_t;
511 
512 // Base
513 #define hash_table_ctor(...) cdc_hash_table_ctor(__VA_ARGS__)
514 #define hash_table_ctorl(...) cdc_hash_table_ctorl(__VA_ARGS__)
515 #define hash_table_ctorv(...) cdc_hash_table_ctorv(__VA_ARGS__)
516 #define hash_table_ctor1(...) cdc_hash_table_ctor1(__VA_ARGS__)
517 #define hash_table_ctorl1(...) cdc_hash_table_ctorl1(__VA_ARGS__)
518 #define hash_table_ctorv1(...) cdc_hash_table_ctorv1(__VA_ARGS__)
519 #define hash_table_dtor(...) cdc_hash_table_dtor(__VA_ARGS__)
520 
521 // Lookup
522 #define hash_table_get(...) cdc_hash_table_get(__VA_ARGS__)
523 #define hash_table_count(...) cdc_hash_table_count(__VA_ARGS__)
524 #define hash_table_find(...) cdc_hash_table_find(__VA_ARGS__)
525 
526 // Capacity
527 #define hash_table_size(...) cdc_hash_table_size(__VA_ARGS__)
528 #define hash_table_empty(...) cdc_hash_table_empty(__VA_ARGS__)
529 
530 // Modifiers
531 #define hash_table_clear(...) cdc_hash_table_clear(__VA_ARGS__)
532 #define hash_table_insert(...) cdc_hash_table_insert(__VA_ARGS__)
533 #define hash_table_insert_or_assign(...) \
534  cdc_hash_table_insert_or_assign(__VA_ARGS__)
535 #define hash_table_erase(...) cdc_hash_table_erase(__VA_ARGS__)
536 #define hash_table_swap(...) cdc_hash_table_swap(__VA_ARGS__)
537 
538 // Iterators
539 #define hash_table_begin(...) cdc_hash_table_begin(__VA_ARGS__)
540 #define hash_table_end(...) cdc_hash_table_end(__VA_ARGS__)
541 
542 // Hash policy
543 #define hash_table_load_factor(...) cdc_hash_table_load_factor(__VA_ARGS__)
544 #define hash_table_max_load_factor(...) \
545  cdc_hash_table_max_load_factor(__VA_ARGS__)
546 #define hash_table_set_max_load_factor(...) \
547  cdc_hash_table_set_max_load_factor(__VA_ARGS__)
548 #define hash_table_rehash(...) cdc_hash_table_rehash(__VA_ARGS__)
549 #define hash_table_reserve(...) cdc_hash_table_reserve(__VA_ARGS__)
550 
551 // Bucket interface
552 #define hash_table_bucket_count(...) cdc_hash_table_bucket_count(__VA_ARGS__)
553 
554 // Iterators
555 #define hash_table_iter_next(...) cdc_hash_table_iter_next(__VA_ARGS__)
556 #define hash_table_iter_has_next(...) cdc_hash_table_iter_has_next(__VA_ARGS__)
557 #define hash_table_iter_key(...) cdc_hash_table_iter_key(__VA_ARGS__)
558 #define hash_table_iter_value(...) cdc_hash_table_iter_value(__VA_ARGS__)
559 #define hash_table_iter_key_value(...) \
560  cdc_hash_table_iter_key_value(__VA_ARGS__)
561 #define hash_table_iter_is_eq(...) cdc_hash_table_iter_is_eq(__VA_ARGS__)
562 #endif
563 
564 #endif // CDCONTAINERS_INCLUDE_CDCONTAINERS_HASH_TABLE_H
enum cdc_stat cdc_hash_table_reserve(struct cdc_hash_table *t, size_t count)
Reserves space for at least the specified number of elements. This regenerates the hash table...
struct cdc_hash_table_entry * tail
Definition: hash-table.h:61
static void cdc_hash_table_set_max_load_factor(struct cdc_hash_table *t, float load_factor)
Sets the maximum load factor.
Definition: hash-table.h:371
size_t bcount
Definition: hash-table.h:63
struct cdc_hash_table_entry ** buckets
Definition: hash-table.h:62
struct cdc_hash_table_entry * current
Definition: hash-table.h:76
size_t cdc_hash_table_erase(struct cdc_hash_table *t, void *key)
Removes the element (if one exists) with the key equivalent to key.
static size_t cdc_hash_table_bucket_count(struct cdc_hash_table *t)
Returns the number of buckets.
Definition: hash-table.h:410
void cdc_hash_table_find(struct cdc_hash_table *t, void *key, struct cdc_hash_table_iter *it)
Finds an element with key equivalent to key.
enum cdc_stat cdc_hash_table_ctorl1(struct cdc_hash_table **t, struct cdc_data_info *info, float load_factor,...)
Constructs a hash table, initialized by an variable number of pointers on cdc_pair&#39;s(first - key...
This file contains different utilities for hashing. The ideas of algorithms were borrowed from the bo...
static void * cdc_hash_table_iter_key(struct cdc_hash_table_iter *it)
Returns an item&#39;s key.
Definition: hash-table.h:454
enum cdc_stat cdc_hash_table_ctorl(struct cdc_hash_table **t, struct cdc_data_info *info,...)
Constructs a hash table, initialized by an variable number of pointers on cdc_pair&#39;s(first - key...
void * value
Definition: hash-table.h:51
size_t hash
Definition: hash-table.h:52
struct cdc_hash_table_entry * next
Definition: hash-table.h:49
static struct cdc_pair cdc_hash_table_iter_key_value(struct cdc_hash_table_iter *it)
Returns a pair, where first - key, second - value.
Definition: hash-table.h:478
enum cdc_stat cdc_hash_table_insert(struct cdc_hash_table *t, void *key, void *value, struct cdc_hash_table_iter *it, bool *inserted)
Inserts an element into the container, if the container doesn&#39;t already contain an element with an eq...
static size_t cdc_hash_table_size(struct cdc_hash_table *t)
Returns the number of items in the hash_table.
Definition: hash-table.h:221
static bool cdc_hash_table_iter_has_next(struct cdc_hash_table_iter *it)
Returns true if there is at least one element ahead of the iterator, i.e. the iterator is not at the ...
Definition: hash-table.h:442
struct cdc_hash_table * container
Definition: hash-table.h:75
static float cdc_hash_table_max_load_factor(struct cdc_hash_table *t)
Returns current maximum load factor.
Definition: hash-table.h:359
void cdc_hash_table_clear(struct cdc_hash_table *t)
Removes all the elements from the hash_table.
The cdc_hash_table_iter is service struct.
Definition: hash-table.h:74
Definition: common.h:60
enum cdc_stat cdc_hash_table_rehash(struct cdc_hash_table *t, size_t count)
Reserves at least the specified number of buckets. This regenerates the hash table.
enum cdc_stat cdc_hash_table_ctorv1(struct cdc_hash_table **t, struct cdc_data_info *info, float load_factor, va_list args)
Constructs a hash table, initialized by args. The last item must be CDC_END.
cdc_stat
Definition: status.h:24
static void cdc_hash_table_begin(struct cdc_hash_table *t, struct cdc_hash_table_iter *it)
Initializes the iterator to the beginning.
Definition: hash-table.h:311
static bool cdc_hash_table_iter_is_eq(struct cdc_hash_table_iter *it1, struct cdc_hash_table_iter *it2)
Returns false if the iterator |it1| equal to the iterator |it2|, otherwise returns false...
Definition: hash-table.h:495
enum cdc_stat cdc_hash_table_ctor(struct cdc_hash_table **t, struct cdc_data_info *info)
Constructs an empty hash table.
size_t size
Definition: hash-table.h:65
void cdc_hash_table_swap(struct cdc_hash_table *a, struct cdc_hash_table *b)
Swaps hash_tables a and b. This operation is very fast and never fails.
enum cdc_stat cdc_hash_table_get(struct cdc_hash_table *t, void *key, void **value)
Returns a value that is mapped to a key. If the key does not exist, then NULL will return...
void cdc_hash_table_dtor(struct cdc_hash_table *t)
Destroys the hash table.
static void cdc_hash_table_end(struct cdc_hash_table *t, struct cdc_hash_table_iter *it)
Initializes the iterator to the end.
Definition: hash-table.h:326
enum cdc_stat cdc_hash_table_ctorv(struct cdc_hash_table **t, struct cdc_data_info *info, va_list args)
Constructs a hash table, initialized by args. The last item must be CDC_END.
static void cdc_hash_table_iter_next(struct cdc_hash_table_iter *it)
Advances the iterator to the next element in the hash table.
Definition: hash-table.h:428
enum cdc_stat cdc_hash_table_insert_or_assign(struct cdc_hash_table *t, void *key, void *value, struct cdc_hash_table_iter *it, bool *inserted)
Inserts an element or assigns to the current element if the key already exists.
static float cdc_hash_table_load_factor(struct cdc_hash_table *t)
Returns average number of elements per bucket.
Definition: hash-table.h:347
static void * cdc_hash_table_iter_value(struct cdc_hash_table_iter *it)
Returns an item&#39;s value.
Definition: hash-table.h:466
size_t cdc_hash_table_count(struct cdc_hash_table *t, void *key)
Returns the number of elements with key that compares equal to the specified argument key...
The cdc_hash_table is service struct.
Definition: hash-table.h:60
The cdc_data_info struct used to initialize contaners.
Definition: common.h:71
static bool cdc_hash_table_empty(struct cdc_hash_table *t)
Checks if the hash table has no elements.
Definition: hash-table.h:233
void * key
Definition: hash-table.h:50
The cdc_hash_table_entry struct.
Definition: hash-table.h:48
struct cdc_data_info * dinfo
Definition: hash-table.h:66
float load_factor
Definition: hash-table.h:64
enum cdc_stat cdc_hash_table_ctor1(struct cdc_hash_table **t, struct cdc_data_info *info, float load_factor)
Constructs an empty hash table.