PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
map.h
Go to the documentation of this file.
1#pragma once
2
3#define __STDC_WANT_LIB_EXT1__ 1
4#include <assert.h>
5#include <stdbool.h>
6#include <stdint.h>
7#include <string.h>
8#include <sys/fs.h>
9
10typedef struct map_key map_key_t;
11typedef struct map_entry map_entry_t;
12typedef struct map map_t;
13
14/**
15 * @brief Hash Map
16 * @defgroup kernel_utils_map Hash Map
17 * @ingroup kernel_utils
18 *
19 * @todo Dynamically sized keys without heap allocation?
20 *
21 * @{
22 */
23
24/**
25 * @brief The minimum capacity of a map.
26 */
27#define MAP_MIN_CAPACITY 16
28
29/**
30 * @brief The maximum load percentage of a map before it resizes.
31 */
32#define MAP_MAX_LOAD_PERCENTAGE 75
33
34/**
35 * @brief The minimum load percentage of a map before it resizes down.
36 */
37#define MAP_MIN_LOAD_PERCENTAGE 25
38
39/**
40 * @brief The value used to indicate a tombstone (removed entry).
41 */
42#define MAP_TOMBSTONE ((map_entry_t*)1)
43
44/**
45 * @brief The maximum length of a key in the map.
46 */
47#define MAP_KEY_MAX_LENGTH 118
48
49/**
50 * @brief Map key stucture.
51 *
52 * Is used to implement a generic key for the map. The object is copied into `key` and hashed.
53 * We can then use the hash for quick comparisons and lookups while using the key itself for full comparisons no matter
54 * the type of the key.
55 */
56typedef struct map_key
57{
61} map_key_t;
62
63/**
64 * @brief Map entry structure.
65 *
66 * Place this in a structure to make it addable to a map and then use `CONTAINER_OF` to get the structure back.
67 */
68typedef struct map_entry
69{
74
75/**
76 * @brief Check if a map entry pointer is valid (not NULL or tombstone).
77 *
78 * @param entryPtr The map entry pointer to check.
79 * @return true if the entry pointer is valid, false otherwise.
80 */
81#define MAP_ENTRY_PTR_IS_VALID(entryPtr) ((entryPtr) != NULL && (entryPtr) != MAP_TOMBSTONE)
82
83/**
84 * @brief Hash map structure.
85 *
86 * The entries can be safely iterated over as an array as long sa the `MAP_ENTRY_PTR_IS_VALID` macro is used to check
87 * each entry before dereferencing it.
88 */
96
97/**
98 * @brief Hash a object.
99 *
100 * @param object The object to hash.
101 * @param length The length of the object in bytes.
102 * @return The hash of the object.
103 */
104uint64_t hash_object(const void* object, uint64_t length);
105
106/**
107 * @brief Create a map key from a buffer.
108 *
109 * @param buffer The buffer to create the key from.
110 * @param length The length of the buffer in bytes.
111 * @return The map key.
112 */
113static inline map_key_t map_key_buffer(const void* buffer, uint64_t length)
114{
115 assert(length <= MAP_KEY_MAX_LENGTH);
116 map_key_t key;
117 memcpy(key.key, buffer, length);
118 key.len = length;
119 key.hash = hash_object(buffer, length);
120 return key;
121}
122
123/**
124 * @brief Create a map key from a uint64_t.
125 *
126 * @param uint64 The uint64_t to create the key from.
127 * @return The map key.
128 */
129static inline map_key_t map_key_uint64(uint64_t uint64)
130{
131 map_key_t key;
132 memcpy(key.key, &uint64, sizeof(uint64_t));
133 key.len = sizeof(uint64_t);
134 key.hash = hash_object(&uint64, sizeof(uint64_t));
135 return key;
136}
137
138/**
139 * @brief Create a map key from a string.
140 *
141 * @param str The string to create the key from.
142 * @return The map key.
143 */
144static inline map_key_t map_key_string(const char* str)
145{
147}
148
149/**
150 * @brief Initialize a map entry.
151 *
152 * @param entry The map entry to initialize.
153 */
154void map_entry_init(map_entry_t* entry);
155
156/**
157 * @brief Create a map initializer.
158 *
159 * @return A map initializer.
160 */
161#define MAP_CREATE() {.entries = NULL, .capacity = 0, .length = 0, .tombstones = 0}
162
163/**
164 * @brief Initialize a map.
165 *
166 * @param map The map to initialize.
167 */
168void map_init(map_t* map);
169
170/**
171 * @brief Deinitialize a map.
172 *
173 * @param map The map to deinitialize.
174 */
175void map_deinit(map_t* map);
176
177/**
178 * @brief Insert a key-value pair into the map.
179 *
180 * If the key already exists, then an `EEXIST` error is returned.
181 *
182 * @param map The map to insert into.
183 * @param key The key to insert.
184 * @param value The value to insert.
185 * @return On success, `0`. On failure, `ERR` and `errno` is set.
186 */
187uint64_t map_insert(map_t* map, const map_key_t* key, map_entry_t* value);
188
189/**
190 * @brief Replace a key-value pair in the map.
191 *
192 * If the key does not exist, it is inserted.
193 *
194 * @param map The map to replace in.
195 * @param key The key to replace.
196 * @param value The value to replace.
197 * @return On success, `0`. On failure, `ERR` and `errno` is set.
198 */
199uint64_t map_replace(map_t* map, const map_key_t* key, map_entry_t* entry);
200
201/**
202 * @brief Get a value from the map by key.
203 *
204 * @param map The map to get from.
205 * @param key The key to get.
206 * @return On success, the value. If the key does not exist, returns `NULL`.
207 */
208map_entry_t* map_get(map_t* map, const map_key_t* key);
209
210/**
211 * @brief Get and remove a key-value pair from the map.
212 *
213 * @param map The map to get from.
214 * @param key The key to get and remove.
215 * @return On success, the value. If the key does not exist, returns `NULL`.
216 */
218
219/**
220 * @brief Remove a entry from the map.
221 *
222 * If the entry does not exist, nothing happens.
223 *
224 * @param map The map to remove from.
225 * @param entry The entry to remove.
226 */
227void map_remove(map_t* map, map_entry_t* entry);
228
229/**
230 * @brief Remove a key-value pair from the map by key.
231 *
232 * If the key does not exist, nothing happens.
233 *
234 * @param map The map to remove from.
235 * @param key The key to remove.
236 */
237void map_remove_key(map_t* map, const map_key_t* key);
238
239/**
240 * @brief Get the number of entries in the map.
241 *
242 * @param map The map to get the size of.
243 * @return The number of entries in the map.
244 */
245uint64_t map_size(const map_t* map);
246
247/**
248 * @brief Get the capacity of the map.
249 *
250 * @param map The map to get the capacity of.
251 * @return The capacity of the map.
252 */
254
255/**
256 * @brief Check if the map is empty.
257 *
258 * @param map The map to check.
259 * @return `true` if the map is empty, `false` otherwise.
260 */
261bool map_is_empty(const map_t* map);
262
263/**
264 * @brief Check if the map contains a key.
265 *
266 * @param map The map to check.
267 * @param key The key to check for.
268 * @return `true` if the map contains the key, `false` otherwise.
269 */
270bool map_contains(map_t* map, const map_key_t* key);
271
272/**
273 * @brief Clear all entries from the map.
274 *
275 * Note that this does not free the entries themselves, only removes them from the map.
276 *
277 * @param map The map to clear.
278 */
279void map_clear(map_t* map);
280
281/**
282 * @brief Reserve space in the map for at least `minCapacity` entries.
283 *
284 * @param map The map to reserve space in.
285 * @param minCapacity The minimum capacity to reserve.
286 * @return On success, `0`. On failure, `ERR` and `errno` is set.
287 */
288uint64_t map_reserve(map_t* map, uint64_t minCapacity);
289
290/** @} */
#define assert(expression)
Definition assert.h:29
boot_memory_map_t * map
Definition main.c:241
EFI_PHYSICAL_ADDRESS buffer
Definition main.c:237
uint64_t hash_object(const void *object, uint64_t length)
Hash a object.
Definition map.c:8
static map_key_t map_key_buffer(const void *buffer, uint64_t length)
Create a map key from a buffer.
Definition map.h:113
void map_init(map_t *map)
Initialize a map.
Definition map.c:142
uint64_t map_capacity(const map_t *map)
Get the capacity of the map.
Definition map.c:352
bool map_contains(map_t *map, const map_key_t *key)
Check if the map contains a key.
Definition map.c:362
void map_clear(map_t *map)
Clear all entries from the map.
Definition map.c:367
void map_deinit(map_t *map)
Deinitialize a map.
Definition map.c:150
#define MAP_KEY_MAX_LENGTH
The maximum length of a key in the map.
Definition map.h:47
uint64_t map_replace(map_t *map, const map_key_t *key, map_entry_t *entry)
Replace a key-value pair in the map.
Definition map.c:213
void map_entry_init(map_entry_t *entry)
Initialize a map entry.
Definition map.c:37
static map_key_t map_key_uint64(uint64_t uint64)
Create a map key from a uint64_t.
Definition map.h:129
uint64_t map_size(const map_t *map)
Get the number of entries in the map.
Definition map.c:347
uint64_t map_insert(map_t *map, const map_key_t *key, map_entry_t *value)
Insert a key-value pair into the map.
Definition map.c:170
map_entry_t * map_get_and_remove(map_t *map, const map_key_t *key)
Get and remove a key-value pair from the map.
Definition map.c:301
void map_remove(map_t *map, map_entry_t *entry)
Remove a entry from the map.
Definition map.c:319
void map_remove_key(map_t *map, const map_key_t *key)
Remove a key-value pair from the map by key.
Definition map.c:330
bool map_is_empty(const map_t *map)
Check if the map is empty.
Definition map.c:357
map_entry_t * map_get(map_t *map, const map_key_t *key)
Get a value from the map by key.
Definition map.c:253
uint64_t map_reserve(map_t *map, uint64_t minCapacity)
Reserve space in the map for at least minCapacity entries.
Definition map.c:384
static map_key_t map_key_string(const char *str)
Create a map key from a string.
Definition map.h:144
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
size_t strnlen_s(const char *s, size_t maxsize)
Definition strnlen_s.c:4
Map entry structure.
Definition map.h:69
uint64_t index
Definition map.h:71
map_t * map
Definition map.h:72
map_key_t key
Definition map.h:70
Map key stucture.
Definition map.h:57
uint8_t key[MAP_KEY_MAX_LENGTH]
Definition map.h:58
uint8_t len
Definition map.h:59
uint64_t hash
Definition map.h:60
Hash map structure.
Definition map.h:90
uint64_t capacity
Definition map.h:92
map_entry_t ** entries
Definition map.h:91
uint64_t tombstones
Definition map.h:94
uint64_t length
Definition map.h:93