aboutsummaryrefslogtreecommitdiff
path: root/include/hashmap.h
blob: f027d25abd7b52fe565706d5e93ff79f5c72d88e (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
#ifndef MGUI_HASHMAP_H
#define MGUI_HASHMAP_H

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

typedef struct mgui_hashmap_entry mgui_hashmap_entry;

struct mgui_hashmap_entry {
    mgui_hashmap_entry *next;
    uint64_t hash;
    void *value;
    size_t key_size;
    /* char key[...]; Dynamically size string of size |key_size|. Allocated directly in the struct (sizeof(mgui_hashmap_entry) + key_size) */
};

typedef struct {
    mgui_hashmap_entry **entries;
    size_t capacity;
    size_t size;
} mgui_hashmap;

void mgui_hashmap_init(mgui_hashmap *self);
void mgui_hashmap_deinit(mgui_hashmap *self);

/*
    Note: stores the |value| itself, and does not copy the content of |value|.
    Note: inserting the same value multiple times in the hash map is undefined behavior.
    Note: |hash| can be NULL.
*/
void mgui_hashmap_insert(mgui_hashmap *self, const char *key, size_t key_size, void *value, uint64_t *hash_out);
bool mgui_hashmap_get(mgui_hashmap *self, const char *key, size_t key_size, void **value_out);
/* Note: |hash| has to be the hash for |key|, which you can get by using calling |mgui_hashmap_hash| with |key| or as a result of |mgui_hashmap_insert| */
bool mgui_hashmap_get_by_hash(mgui_hashmap *self, const char *key, size_t key_size, uint64_t hash, void **value_out);
uint64_t mgui_hashmap_hash(const char *key, size_t key_size);
/* Return false from |callback| to stop the iteration */
void mgui_hashmap_for_each(mgui_hashmap *self, bool(*callback)(void *value, void *userdata), void *userdata);
/* Return true from |callback| to erase the item */
void mgui_hashmap_for_each_erase(mgui_hashmap *self, bool(*callback)(void *value, void *userdata), void *userdata);

#endif /* MGUI_HASHMAP_H */