summaryrefslogtreecommitdiffstats
path: root/include/hmap.h
blob: 3700c6e12e491c7aad0c9b49aa5ad352f853d627 (plain) (blame)
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;
}