blob: fded428e6d0d15203c4c261a8631f4bd9dfd361e [file] [log] [blame]
swissChilica0d2e22020-08-16 15:09:25 -07001#pragma once
2
3
4#include <stdint.h>
5#include <stdlib.h>
6#include "hash.h"
7
8/* 1kb seems reasonable doesn't it? */
9#define MAP_ALLOC_SIZE (1 * 1024)
10
11struct map_node
12{
13 char *key;
14 void *val;
15 int used : 1;
16 uint32_t h;
17};
18
19typedef struct map_node map_node;
20
21#define EMPTY_NODE { NULL, NULL, 0, 0 }
22
23/**
24 * @brief A simple hashmap.
25 *
26 * Allocate map with new_map() and free it with free_map(). Items can be added
27 * with map_set() or the MAP_SET() macro. map_exists() can be used to check if
28 * an item exists in the map, map_get() and MAP_GET() can be used to retrieve
29 * items.
30 */
31struct map
32{
33 uint64_t len;
34 map_node *items;
35 uint64_t full;
36 uint64_t count;
37};
38
39typedef struct map map_t;
40
41/**
42 * @deprecated Used map_exists instead
43 */
44#define MAP_USED_AT(m, i) (m[i].used)
45
46/**
47 * @brief Allocate a new map on the heap
48 * @return A pointer to the allocated map
49 */
50map_t *new_map();
51
52/**
53 * @brief Allocate a map on the heap with a specific capacity. Map will be
54 * reallocated if this capacity is exceeded.
55 * @return A pointer to the allocated map
56 */
57map_t *new_map_sized(uint64_t);
58
59/**
60 * @brief Free a map on the heap
61 * @param m The map to free
62 */
63void free_map(map_t *m);
64
65/**
66 * @brief Free a map and its items
67 * @param m The map to free
68 */
69void free_map_items(map_t *m);
70
71/**
72 * @brief Set a certain value in the map
73 * @param m The map
74 * @param k The key whose value should be changed
75 * @param v The new value
76 */
77void map_set(map_t *m, char *k, void *v);
78
79/**
80 * @brief Get the value in a map by it's key
81 * @param m The map
82 * @param k The key
83 * @return The value at k
84 */
85void *map_get(map_t *m, char *k);
86
87/**
88 * @brief Check if a key is used in a map
89 * @param m The map
90 * @param k The key
91 * @return 1 if the key is used, 0 otherwise
92 */
93int map_exists(map_t *m, char *k);
94
95/**
96 * @brief Print a map's contents to stdout
97 * @warning Should not be used in production
98 * @param m The map
99 */
100void map_debug(map_t *m);
101
102#define MAP_GET(t, m, k) *(t *)map_get(m, k)
103
104/**
105 * @brief Helper macro to allocate memory for a value on the heap and store it
106 * at a given key
107 * @warning This is unsafe and should be used with caution, especially for more
108 * complex types
109 * @param m The map
110 * @param k The key at which to insert the value
111 * @param v The value
112 */
113#define MAP_SET(m, k, v) \
114 { \
115 __typeof__(v) *__map_temp = malloc(sizeof(__typeof(v))); \
116 *__map_temp = v; \
117 map_set(m, k, __map_temp); \
118 }
119