Derive-C
Loading...
Searching...
No Matches
map.c
Go to the documentation of this file.
1
4
9#include <derive-c/prelude.h>
10#include <inttypes.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <stdint.h>
15
16struct user_id {
17 char const* username;
18 uint64_t uuid;
19};
20
21static bool user_id_eq(struct user_id const* a, struct user_id const* b) {
22 return strcmp(a->username, b->username) == 0 && a->uuid == b->uuid;
23}
24
25static size_t user_id_hash(struct user_id const* self) {
26 const char* username_ptr = self->username;
27 size_t hash = dc_fnv1a_str_const(&username_ptr);
28 hash = dc_hash_combine(hash, DC_DEFAULT_HASH(&self->uuid));
29 return hash;
30}
31
32static void user_id_debug(struct user_id const* self, dc_debug_fmt fmt, FILE* stream) {
33 fprintf(stream, "user_id@%p {\n", (void*)self);
34 fmt = dc_debug_fmt_scope_begin(fmt);
35 dc_debug_fmt_print(fmt, stream, "username: %s,\n", self->username);
36 dc_debug_fmt_print(fmt, stream, "uuid: %" PRIu64 ",\n", self->uuid);
37 fmt = dc_debug_fmt_scope_end(fmt);
38 dc_debug_fmt_print(fmt, stream, "}");
39}
40
41struct userdata {
42 int score;
44};
45
46static void userdata_debug(struct userdata const* self, dc_debug_fmt fmt, FILE* stream) {
47 fprintf(stream, "userdata@%p {\n", (void*)self);
48 fmt = dc_debug_fmt_scope_begin(fmt);
49 dc_debug_fmt_print(fmt, stream, "score: %d,\n", self->score);
50 dc_debug_fmt_print(fmt, stream, "hashed_password: \"%.16s\",\n", self->hashed_password);
51 fmt = dc_debug_fmt_scope_end(fmt);
52 dc_debug_fmt_print(fmt, stream, "}");
53}
54
55#define KEY struct user_id
56#define KEY_EQ user_id_eq
57#define KEY_HASH user_id_hash
58#define KEY_DEBUG user_id_debug
59#define VALUE struct userdata
60#define VALUE_DEBUG userdata_debug
61#define NAME user_map
63
64static void example_basic() {
66 DC_SCOPED(user_map) map = user_map_new(stdalloc_get_ref());
67
68 struct user_id user1 = {.username = "alice", .uuid = 1001};
69 struct user_id user2 = {.username = "bob", .uuid = 1002};
70
71 struct userdata data1 = {.score = 1500, .hashed_password = "hash1234567890"};
72 struct userdata data2 = {.score = 2000, .hashed_password = "hash0987654321"};
73
74 user_map_insert(&map, user1, data1);
75 user_map_insert(&map, user2, data2);
76
77 struct userdata const* found_data1 = user_map_read(&map, user1);
78 DC_ASSERT(found_data1 != NULL);
79 DC_ASSERT(found_data1->score == 1500);
80 DC_ASSERT(strncmp(found_data1->hashed_password, "hash1234567890", 16) == 0);
81
82 struct userdata const* found_data2 = user_map_read(&map, user2);
83 DC_ASSERT(found_data2 != NULL);
84 DC_ASSERT(found_data2->score == 2000);
85
86 struct user_id invalid_user = {.username = "charlie", .uuid = 9999};
87 struct userdata const* not_found = user_map_try_read(&map, invalid_user);
88 DC_ASSERT(not_found == NULL);
89
90 user_map_debug(&map, dc_debug_fmt_new(), stdout);
91 fprintf(stdout, "\n");
92}
93
94struct largedata {
95 char data[32];
96};
97
98static void largedata_debug(struct largedata const* self, dc_debug_fmt fmt, FILE* stream) {
99 fprintf(stream, "largedata@%p {\n", (void*)self);
100 fmt = dc_debug_fmt_scope_begin(fmt);
101 dc_debug_fmt_print(fmt, stream, "data: \"%.32s\",\n", self->data);
102 fmt = dc_debug_fmt_scope_end(fmt);
103 dc_debug_fmt_print(fmt, stream, "}");
104}
105
106#define KEY uint64_t
107#define KEY_HASH DC_DEFAULT_HASH
108#define VALUE uint16_t
109#define NAME uuid_to_index_map
111
112static void example_small() {
114 DC_SCOPED(uuid_to_index_map) map = uuid_to_index_map_new(stdalloc_get_ref());
115
116 uuid_to_index_map_insert(&map, 1001, 0);
117 uuid_to_index_map_insert(&map, 1002, 1);
118 uuid_to_index_map_insert(&map, 1003, 2);
119
120 uuid_to_index_map_debug(&map, dc_debug_fmt_new(), stdout);
121 fprintf(stdout, "\n");
122
123 struct largedata large_data_array[3] = {
124 {.data = "First large data"}, {.data = "Second large data"}, {.data = "Third large data"}};
125
126 DC_FOR_CONST(uuid_to_index_map, &map, iter, entry) {
127 uint16_t index = *entry.value;
128 DC_ASSERT(index < 3);
129 largedata_debug(&large_data_array[index], dc_debug_fmt_new(), stdout);
130 fprintf(stdout, "\n");
131 }
132}
133
134#define KEY uint64_t
135#define KEY_HASH DC_DEFAULT_HASH
136#define VALUE struct largedata
137#define VALUE_DEBUG largedata_debug
138#define NAME ankerl_largedata_map
140
141static void example_iteration() {
143 DC_SCOPED(ankerl_largedata_map) map = ankerl_largedata_map_new(stdalloc_get_ref());
144
145 struct largedata data1 = {.data = "Ankerl map entry number one"};
146 struct largedata data2 = {.data = "Ankerl map entry number two"};
147 struct largedata data3 = {.data = "Ankerl map entry number three"};
148
149 ankerl_largedata_map_insert(&map, 2001, data1);
150 ankerl_largedata_map_insert(&map, 2002, data2);
151 ankerl_largedata_map_insert(&map, 2003, data3);
152
153 size_t count = 0;
154 DC_FOR_CONST(ankerl_largedata_map, &map, iter, entry) {
155 printf("Entry %zu: uuid=%" PRIu64 " data=", count, *entry.key);
156 largedata_debug(entry.value, dc_debug_fmt_new(), stdout);
157 fprintf(stdout, "\n");
158 count++;
159 }
160 DC_ASSERT(count == 3);
161
162 ankerl_largedata_map_debug(&map, dc_debug_fmt_new(), stdout);
163 fprintf(stdout, "\n");
164}
165
166int main() {
170 return 0;
171}
static DC_PUBLIC size_t dc_hash_combine(size_t seed, size_t h)
Definition combine.h:7
#define DC_DEFAULT_HASH(obj)
Definition default.h:15
static DC_PUBLIC void dc_debug_fmt_print(dc_debug_fmt fmt, FILE *stream, const char *format,...)
Definition fmt.h:32
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_new()
Definition fmt.h:15
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_end(dc_debug_fmt fmt)
Definition fmt.h:57
static DC_PUBLIC dc_debug_fmt dc_debug_fmt_scope_begin(dc_debug_fmt fmt)
Definition fmt.h:50
static DC_PUBLIC uint64_t dc_fnv1a_str_const(const char *const *s)
Definition fnv1a.h:26
#define DC_FOR_CONST(TYPE, INSTANCE, ITER, ITEM)
Definition for.h:14
static void largedata_debug(struct largedata const *self, dc_debug_fmt fmt, FILE *stream)
Definition map.c:98
static void example_small()
Definition map.c:112
static void example_iteration()
Definition map.c:141
static size_t user_id_hash(struct user_id const *self)
Definition map.c:25
static void userdata_debug(struct userdata const *self, dc_debug_fmt fmt, FILE *stream)
Definition map.c:46
static void example_basic()
Definition map.c:64
static void user_id_debug(struct user_id const *self, dc_debug_fmt fmt, FILE *stream)
Definition map.c:32
static bool user_id_eq(struct user_id const *a, struct user_id const *b)
Definition map.c:21
int main()
Definition map.c:166
#define DC_ASSERT(expr,...)
Definition panic.h:37
#define DC_SCOPED(type,...)
RAII in C. Call the destructor when the variable goes out of scope.
Definition scope.h:5
Debug format helpers for debug printin data structures.
Definition fmt.h:11
char data[32]
Definition map.c:95
Definition map.c:16
uint64_t uuid
Definition map.c:18
char const * username
Definition map.c:17
Definition map.c:41
int score
Definition map.c:42
char hashed_password[16]
Definition map.c:43
#define DC_DEBUG_TRACE
Definition debug.h:17
static DC_PUBLIC FILE * stream(SELF *self)
Definition template.h:108