Tramway SDK
hashmap.h
Go to the documentation of this file.
1// Tramway Drifting and Dungeon Exploration Simulator SDK Runtime
2
3#ifndef TRAM_SDK_TEMPLATES_HASHMAP_H
4#define TRAM_SDK_TEMPLATES_HASHMAP_H
5
6#include <framework/uid.h>
7#include <iostream> // error message
8#include <cstring> // memset
9
10/* instead of having two sets of each method, one with uint32_t and the other
11 * with UID, maybe we could create some kind of a struct called Key and then we
12 * could add a uint32_t converter to it and then we could add a constructor from
13 * both uint32_t and UID and then we could just have only a single of each
14 * method and all of the conversions would happen automatically
15 *
16 * TODO: investigate
17 */
18
19namespace tram {
20
21template <typename T>
22class Hashmap {
23public:
24 constexpr Hashmap(std::string name, size_t max_size) {
25 this->name = name;
26 this->max_size = max_size;
27 this->hash_parameter = max_size * 2;
28
29 size_t memory_size = ((max_size * 2) + padding) * sizeof(Record);
30
31 char* memory = (char*)::operator new(memory_size);
32
33 first = (Record*) memory;
34 last = (Record*) (memory + memory_size);
35
36 memset(memory, 0, memory_size);
37 }
38
39 constexpr Hashmap(std::string name, size_t max_size, std::initializer_list<std::pair<uint32_t, T>> list) : Hashmap(name, max_size) {
40 for (const auto& entry : list) {
41 Insert(entry.first, entry.second);
42 }
43 }
44
45 T Find(UID key) {
46 return Find(key.key);
47 }
48
49 T Find(uint32_t key) {
50 uint32_t hash = key % hash_parameter;
51
52 Record* candidate = first + hash;
53
54 while (candidate != last) {
55 if (!(candidate->flags & (FLAG_DELETED | FLAG_RECORD))) {
56 break;
57 }
58
59 if (candidate->key == key) {
60 if (candidate->flags & FLAG_DELETED) {
61 break;
62 } else {
63 return candidate->value;
64 }
65
66 }
67
68 candidate++;
69 }
70
71 return T();
72 }
73
74 bool Exists(UID key) {
75 return Exists(key.key);
76 }
77
78 bool Exists(uint32_t key) {
79 uint32_t hash = key % hash_parameter;
80
81 Record* candidate = first + hash;
82
83 while (candidate != last) {
84 if (!(candidate->flags & (FLAG_DELETED | FLAG_RECORD))) {
85 break;
86 }
87
88 if (candidate->key == key) {
89 if (candidate->flags & FLAG_DELETED) {
90 break;
91 } else {
92 return true;
93 }
94
95 }
96
97 candidate++;
98 }
99
100 return false;
101 }
102
103 void Insert(UID key, T value) {
104 Insert(key.key, value);
105 }
106
107 void Insert(uint32_t key, T value) {
108 if (size == max_size) {
109 std::cout << "Hashmap " << name << " density reached!" << std::endl;
110 }
111
112 uint32_t hash = key % hash_parameter;
113
114 Record* candidate = first + hash;
115
116 while (candidate != last) {
117 if (candidate->flags & FLAG_RECORD) {
118 if (candidate->key == key) {
119 candidate->value.~T();
120 size--;
121 break;
122 } else {
123 candidate++;
124 continue;
125 }
126 }
127
128 if (candidate->flags & FLAG_DELETED) {
129 break;
130 }
131
132 break;
133 }
134
135 if (candidate == last) {
136 std::cout << "Hashmap " << name << " overflow!" << std::endl;
137 abort();
138 }
139
140 size++;
141
142 candidate->key = key;
143 candidate->value = value;
144 candidate->flags = FLAG_RECORD;
145 }
146
147 void Remove(UID key) {
148 Remove(key.key);
149 }
150
151 void Remove(uint32_t key) {
152 uint32_t hash = key % hash_parameter;
153
154 Record* candidate = first + hash;
155
156 while (candidate != last) {
157 if (!(candidate->flags & (FLAG_DELETED | FLAG_RECORD))) {
158 return;
159 }
160
161 if (candidate->key == key) {
162 if (candidate->flags & FLAG_DELETED) {
163 return;
164 } else {
165 candidate->value.~T();
166 candidate->flags = FLAG_DELETED;
167 size--;
168 return;
169 }
170
171 }
172
173 candidate++;
174 }
175 }
176
177 T& operator[](UID key) {
178 return operator[](key.key);
179 }
180
181 T& operator[](uint32_t key) {
182 uint32_t hash = key % hash_parameter;
183
184 Record* candidate = first + hash;
185
186 while (candidate != last) {
187 if (candidate->key == key) {
188 return candidate->value;
189 }
190
191 if (candidate->flags & FLAG_RECORD) {
192 candidate++;
193 continue;
194 }
195
196 if (candidate->flags & FLAG_DELETED) {
197 break;
198 }
199
200 break;
201 }
202
203 if (candidate == last) {
204 std::cout << "Hashmap " << name << " overflow!" << std::endl;
205 abort();
206 }
207
208 size++;
209
210 if (size == max_size) {
211 std::cout << "Hashmap " << name << " density reached!" << std::endl;
212 }
213
214 candidate->key = key;
215 candidate->value = T();
216 candidate->flags = FLAG_RECORD;
217
218 return candidate->value;
219 }
220
221protected:
222 struct Record {
223 uint32_t key = 0;
224 uint32_t flags = 0;
226 };
227 const size_t padding = 10;
228
229 enum {
231 FLAG_DELETED = 2
232 };
233
234 std::string name;
235 size_t size = 0;
236 size_t max_size = 0;
237 uint32_t hash_parameter = 0;
238 Record* first = nullptr;
239 Record* last = nullptr;
240};
241
242}
243
244#endif // TRAM_SDK_TEMPLATES_HASHMAP_H
Definition: hashmap.h:22
Record * last
Definition: hashmap.h:239
size_t max_size
Definition: hashmap.h:236
T & operator[](UID key)
Definition: hashmap.h:177
T & operator[](uint32_t key)
Definition: hashmap.h:181
const size_t padding
Definition: hashmap.h:227
constexpr Hashmap(std::string name, size_t max_size)
Definition: hashmap.h:24
size_t size
Definition: hashmap.h:235
void Insert(UID key, T value)
Definition: hashmap.h:103
bool Exists(UID key)
Definition: hashmap.h:74
void Insert(uint32_t key, T value)
Definition: hashmap.h:107
T Find(UID key)
Definition: hashmap.h:45
@ FLAG_DELETED
Definition: hashmap.h:231
@ FLAG_RECORD
Definition: hashmap.h:230
bool Exists(uint32_t key)
Definition: hashmap.h:78
std::string name
Definition: hashmap.h:234
constexpr Hashmap(std::string name, size_t max_size, std::initializer_list< std::pair< uint32_t, T > > list)
Definition: hashmap.h:39
void Remove(UID key)
Definition: hashmap.h:147
void Remove(uint32_t key)
Definition: hashmap.h:151
Record * first
Definition: hashmap.h:238
uint32_t hash_parameter
Definition: hashmap.h:237
T Find(uint32_t key)
Definition: hashmap.h:49
Serialization, i.e.
Definition: hashmap.h:222
uint32_t flags
Definition: hashmap.h:224
T value
Definition: hashmap.h:225
uint32_t key
Definition: hashmap.h:223
Interned string type.
Definition: uid.h:10
uint32_t key
Definition: uid.h:40