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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
#pragma once
#include "allocator.h"
#include <stdint.h>
#include <stdbool.h>
#include <sys/types.h>
#define HMAP_ITER(map, iter) \
hmap_iter_init(&(iter)); hmap_iter_next(map, &(iter));
#define HMAP_STRERR_INIT \
[HMAP_OK] = "Success", \
[HMAP_KEY_EXISTS] = "Key exists", \
[HMAP_KEY_MISSING] = "Key missing"
#ifdef LIBHMAP_ASSERT_ARGS
#define LIBHMAP_ABORT_ON_ARGS(cond) do { if (cond) abort(); } while (0)
#else
#define LIBHMAP_ABORT_ON_ARGS(cond)
#endif
#ifdef LIBHMAP_ASSERT_ALLOC
#define LIBHMAP_ABORT_ON_ALLOC(cond) do { if (cond) abort(); } while (0)
#else
#define LIBHMAP_ABORT_ON_ALLOC(cond)
#endif
struct hmap_key;
typedef uint32_t (*hmap_hash_func)(struct hmap_key key);
typedef bool (*hmap_keycmp_func)(struct hmap_key k1, struct hmap_key k2);
enum {
HMAP_OK = 0,
HMAP_KEY_EXISTS,
HMAP_KEY_MISSING,
};
struct hmap_key {
union {
bool b;
char c;
float f;
double d;
int i;
unsigned int u;
size_t s;
ssize_t ss;
const void *p;
void *_p;
};
};
struct hmap_val {
union {
bool b;
char c;
float f;
double d;
int i;
unsigned int u;
size_t s;
ssize_t ss;
const void *p;
void *_p;
};
};
struct hmap_link {
struct hmap_key key;
struct hmap_val value;
struct hmap_link *next;
};
struct hmap_iter {
struct hmap_link *link;
size_t bucket;
};
struct hmap {
hmap_hash_func hash;
hmap_keycmp_func keycmp;
struct hmap_link **buckets;
size_t bucketcnt;
const struct allocator *allocator;
};
int hmap_init(struct hmap *map, size_t buckets, hmap_hash_func hasher,
hmap_keycmp_func keycmp, const struct allocator *allocator);
int hmap_deinit(struct hmap *map);
struct hmap *hmap_alloc(size_t buckets, hmap_hash_func hasher,
hmap_keycmp_func keycmp, const struct allocator *allocator, int *rc);
int hmap_free(struct hmap *map);
int hmap_copy(const struct hmap *dst, const struct hmap *src);
void hmap_swap(struct hmap *m1, struct hmap *m2);
void hmap_clear(const struct hmap *map);
struct hmap_link **hmap_link_get(const struct hmap *map, struct hmap_key key);
struct hmap_link **hmap_link_pos(const struct hmap *map, struct hmap_key key);
struct hmap_link *hmap_link_pop(const struct hmap *map, struct hmap_link **linkp);
struct hmap_link *hmap_link_alloc(const struct hmap *map,
struct hmap_key key, struct hmap_val value, int *rc);
struct hmap_link *hmap_get(const struct hmap *map, struct hmap_key key);
int hmap_set(const struct hmap *map, struct hmap_key key, struct hmap_val value);
int hmap_rm(const struct hmap *map, struct hmap_key key);
int hmap_add(const struct hmap *map, struct hmap_key key, struct hmap_val value);
void hmap_iter_init(struct hmap_iter *iter);
bool hmap_iter_next(const struct hmap *map, struct hmap_iter *iter);
static inline bool hmap_iter_done(const struct hmap_iter *iter);
uint32_t hmap_str_hash(struct hmap_key key);
bool hmap_str_keycmp(struct hmap_key k1, struct hmap_key k2);
static inline bool
hmap_iter_done(const struct hmap_iter *iter)
{
return !iter->link;
}
|