aboutsummaryrefslogtreecommitdiff
path: root/src/hashtable.h
blob: b9b1b2a55460a4615500551b8b3c35ac1d4aa5f1 (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
#ifndef HASHMAP_H
#define HASHMAP_H

#include <stdbool.h>

typedef struct hashtable *hashtable_t;

typedef size_t (*hashtable_hash_func)(void *key);
typedef bool (*hashtable_equal_func)(void *key1, void *key2);

struct hashtable {
    hashtable_hash_func hash_func;
    hashtable_equal_func equal_func;

    struct hashtable_item {
        struct hashtable_item *next;
        void *key;
        void *data;
    } **table;

    size_t size;
    size_t cap;
};

hashtable_t hashtable_create(size_t cap, hashtable_hash_func hash_func, hashtable_equal_func equal_func);
void hashtable_destroy(hashtable_t ht);
void hashtable_reset(hashtable_t ht);

int hashtable_insert(hashtable_t ht, void *key, void *data,
                     void **prevkey, void **prevdata);
int hashtable_query(hashtable_t ht, void *key, void **data);
int hashtable_delete(hashtable_t ht, void *key);

#define hashtable_for_each_item(ht, item, i)            \
    for(size_t i = 0; i < ht->cap; i++)                 \
        for(struct hashtable_item *item = ht->table[i]; \
            item != NULL;                               \
            item = item->next)

#define hashtable_for_each_item_on_index(ht, item, idx) \
    for(struct hashtable_item *item =                   \
            ht->table[idx];                             \
        item != NULL;                                   \
        item = item->next)

#define hashtable_for_each_item_safe(ht, item, i)                       \
    for(size_t i = 0; i < ht->cap; i++)                                 \
        for(struct hashtable_item                                       \
                *item = ht->table[i],                                   \
                *next = NULL;                                           \
            item != NULL && (next = item->next, 1);                     \
            item = next)

#endif