reactor-c 1.0
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
hashmap.h
Go to the documentation of this file.
1
16
17#ifndef K
18#define K void*
19#endif
20#ifndef V
21#define V void*
22#endif
23#ifndef HASH_OF
24#define HASH_OF(key) (size_t)key
25#endif
26#ifndef HASHMAP
27#define HASHMAP(token) hashmap##_##token
28#endif
29
30#include <stddef.h>
31#include <assert.h>
32#include <stdbool.h>
33
35
40typedef struct HASHMAP(entry_t) {
43} HASHMAP(entry_t);
44
49typedef struct HASHMAP(t) {
50 HASHMAP(entry_t) * entries;
51 size_t capacity;
55
57
66HASHMAP(t) * HASHMAP(new)(size_t capacity, K nothing);
67
72void HASHMAP(free)(HASHMAP(t) * hashmap);
73
78void HASHMAP(put)(HASHMAP(t) * hashmap, K key, V value);
79
86V HASHMAP(get)(HASHMAP(t) * hashmap, K key);
87
89
90static HASHMAP(entry_t) * HASHMAP(get_ideal_address)(HASHMAP(t) * hashmap, K key) {
91 HASHMAP(entry_t)* address = hashmap->entries + (HASH_OF(key) % hashmap->capacity);
92 assert(address >= hashmap->entries);
93 assert(address < hashmap->entries + hashmap->capacity);
94 return address;
95}
96
105static HASHMAP(entry_t) * HASHMAP(get_actual_address)(HASHMAP(t) * hashmap, K key) {
106 HASHMAP(entry_t)* address = HASHMAP(get_ideal_address)(hashmap, key);
107 HASHMAP(entry_t)* upper_limit = hashmap->entries + hashmap->capacity;
108 while ((address->key != hashmap->nothing) & (address->key != key))
109 address++;
110 if (address == upper_limit) {
111 address = hashmap->entries;
112 while ((address->key != hashmap->nothing) & (address->key != key))
113 address++;
114 if (address == upper_limit)
115 return NULL;
116 }
117 assert(address->key == key || address->key == hashmap->nothing);
118 return address;
119}
120
122
123HASHMAP(t) * HASHMAP(new)(size_t capacity, K nothing) {
124 HASHMAP(entry_t)* entries = (HASHMAP(entry_t)*)malloc((capacity + 1) * sizeof(HASHMAP(entry_t)));
125 if (!entries)
126 exit(1);
127 HASHMAP(t)* ret = (HASHMAP(t)*)malloc(sizeof(HASHMAP(t)));
128 if (!ret)
129 exit(1);
130 // The entry at the end is used as a boundary. It will never again be written to.
131 for (size_t i = 0; i < capacity + 1; i++) {
132 entries[i].key = nothing;
133 }
134 ret->entries = entries;
135 ret->capacity = capacity;
136 ret->num_entries = 0;
137 // A second nothing may be required if removal is to be supported and we want to make removal
138 // a constant-time operation.
139 ret->nothing = nothing;
140 return ret;
141}
142
143void HASHMAP(free)(HASHMAP(t) * hashmap) {
144 free(hashmap->entries);
145 free(hashmap);
146}
147
148void HASHMAP(put)(HASHMAP(t) * hashmap, K key, V value) {
149 assert(key != hashmap->nothing);
150 HASHMAP(entry_t)* write_to = HASHMAP(get_actual_address)(hashmap, key);
151 write_to->key = key;
152 write_to->value = value;
153}
154
155V HASHMAP(get)(HASHMAP(t) * hashmap, K key) {
156 assert(key != hashmap->nothing);
157 HASHMAP(entry_t)* read_from = HASHMAP(get_actual_address)(hashmap, key);
158 return read_from->value; // Crash the program if the key cannot be found
159}
#define HASH_OF(key)
Definition hashmap.h:24
#define K
Definition hashmap.h:18
#define HASHMAP(token)
Definition hashmap.h:27
#define V
Definition hashmap.h:21
void * value
Definition hashmap.h:42
void * key
Definition hashmap.h:41
size_t num_entries
Definition hashmap.h:52
hashmap_entry_t * entries
Definition hashmap.h:50
void * nothing
Definition hashmap.h:53
size_t capacity
Definition hashmap.h:51