comparison dowa/d_memory.c @ 5:3e12bf044589

Fixed Dowa hashmap to recursively add files into memory.
author June Park <parkjune1995@gmail.com>
date Sat, 27 Sep 2025 16:23:04 -0700
parents 2758f5527d2b
children 1e61008b9980
comparison
equal deleted inserted replaced
4:0b3b4f5887bb 5:3e12bf044589
1 #include "dowa.h" 1 #include "dowa.h"
2 2
3 // --- Arena --- // 3 // --- Arena --- //
4 Dowa_PArena Dowa_Arena_Initialize(size_t capacity) 4 Dowa_PArena Dowa_Arena_Create(size_t capacity)
5 { 5 {
6 Dowa_PArena p_arena; 6 Dowa_PArena p_arena = malloc(sizeof(Dowa_Arena));
7 p_arena = malloc(capacity);
8 if (p_arena == NULL) 7 if (p_arena == NULL)
9 { 8 {
10 perror("malloc"); 9 perror("malloc");
11 return NULL; 10 return NULL;
12 } 11 }
12 p_arena->buffer = malloc(capacity);
13 p_arena->offset = 0; 13 p_arena->offset = 0;
14 p_arena->capacity = capacity; 14 p_arena->capacity = capacity;
15 return p_arena; 15 return p_arena;
16 } 16 }
17 17
26 return currnet_ptr; 26 return currnet_ptr;
27 } 27 }
28 28
29 void Dowa_Arena_Free(Dowa_PArena p_arena) 29 void Dowa_Arena_Free(Dowa_PArena p_arena)
30 { 30 {
31 if (p_arena) { 31 if (p_arena)
32 free(p_arena->buffer); 32 {
33 if (p_arena->buffer)
34 free(p_arena->buffer);
33 free(p_arena); 35 free(p_arena);
34 } 36 }
35 } 37 }
36 38
37 // --- HashMap --- // 39 // --- HashMap --- //
41 p_hash_map = malloc(sizeof(Dowa_HashMap)); 43 p_hash_map = malloc(sizeof(Dowa_HashMap));
42 if (p_hash_map == NULL) 44 if (p_hash_map == NULL)
43 { 45 {
44 return NULL; 46 return NULL;
45 } 47 }
46 p_hash_map->entries = calloc(capacity, sizeof *p_hash_map->entries); 48 p_hash_map->entries = calloc(capacity, sizeof(*p_hash_map->entries));
47 if (p_hash_map->entries == NULL) 49 if (p_hash_map->entries == NULL)
48 { 50 {
49 free(p_hash_map); 51 free(p_hash_map);
50 return NULL; 52 return NULL;
51 } 53 }
52 p_hash_map->capacity = capacity; 54 p_hash_map->capacity = capacity;
53 p_hash_map->current_capacity = 0; 55 p_hash_map->current_capacity = 0;
54 return p_hash_map; 56 return p_hash_map;
55 } 57 }
56 58
59 void Dowa_HashMap_Free(Dowa_PHashMap p_hash_map)
60 {
61 if (p_hash_map)
62 {
63 Dowa_PHashEntry entry;
64 if (p_hash_map->entries)
65 {
66 for (int idx=0; idx<p_hash_map->capacity; idx++)
67 {
68 entry = p_hash_map->entries[idx];
69 if (entry)
70 {
71 free(entry->key);
72 free(entry->buffer);
73 free(entry);
74 }
75 }
76 free(p_hash_map->entries);
77 }
78 }
79 free(p_hash_map);
80 }
81
57 int32 Dowa_HashMap_GetPosition(Dowa_PHashMap p_hash_map, char *key) 82 int32 Dowa_HashMap_GetPosition(Dowa_PHashMap p_hash_map, char *key)
58 { 83 {
59 int32 hash_val = HASH_KEY_NUMBER; 84 int32 hash_val = HASH_KEY_NUMBER;
60 int32 c; 85 int32 c;
61 while ((c = *key++)) 86 while ((c = *key++))
63 hash_val = (hash_val << 5) + hash_val + c; 88 hash_val = (hash_val << 5) + hash_val + c;
64 } 89 }
65 return hash_val % p_hash_map->capacity; 90 return hash_val % p_hash_map->capacity;
66 } 91 }
67 92
68 void Dowa_HashMap_PushValueWithType(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_ValueType type) 93 void *Dowa_HashMap_Get(Dowa_PHashMap p_hash_map, char *key)
94 {
95 int idx_foo = Dowa_HashMap_GetPosition(p_hash_map, key);
96 void *value = p_hash_map->entries[idx_foo];
97 if (strcmp(((Dowa_PHashEntry) value)->key, key) != 0)
98 {
99 return NULL;
100 }
101 return ((Dowa_PHashEntry) value)->buffer;
102 }
103
104 int32 Dowa_HashMap_PushValueWithTypeNoCopy(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type)
69 { 105 {
70 int idx = Dowa_HashMap_GetPosition(p_hash_map, key); 106 int idx = Dowa_HashMap_GetPosition(p_hash_map, key);
71 Dowa_PHashEntry entry = p_hash_map->entries[idx]; 107 Dowa_PHashEntry entry = p_hash_map->entries[idx];
72 if (entry) 108 if (entry)
73 {
74 free(entry->key);
75 free(entry->buffer); 109 free(entry->buffer);
76 }
77 else 110 else
78 { 111 {
79 entry = malloc(sizeof(Dowa_HashEntry)); 112 entry = malloc(sizeof(Dowa_HashEntry));
80 if (entry == NULL) 113 if (entry == NULL) { perror("malloc"); return -1; }
81 { 114
82 perror("malloc");
83 return;
84 }
85 p_hash_map->entries[idx] = entry; 115 p_hash_map->entries[idx] = entry;
86 } 116 p_hash_map->current_capacity++;
87 entry->key = strdup(key); 117 entry->key = strdup(key);
118 }
119 entry->buffer = value;
120 entry->capacity = value_size;
121 entry->type = type;
122 return 0;
123 }
124
125 int32 Dowa_HashMap_PushValueWithType(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type)
126 {
127 int idx = Dowa_HashMap_GetPosition(p_hash_map, key);
128 Dowa_PHashEntry entry = p_hash_map->entries[idx];
129 if (entry)
130 free(entry->buffer);
131 else
132 {
133 entry = malloc(sizeof(Dowa_HashEntry));
134 if (entry == NULL) { perror("malloc"); return -1; }
135
136 p_hash_map->entries[idx] = entry;
137 p_hash_map->current_capacity++;
138 entry->key = strdup(key);
139 }
88 entry->buffer = malloc(value_size); 140 entry->buffer = malloc(value_size);
89 if (entry->buffer == NULL) 141 if (entry->buffer == NULL) { perror("malloc"); return -1; }
90 {
91 perror("malloc");
92 return;
93 }
94 entry->capacity = value_size; 142 entry->capacity = value_size;
95 entry->type = type; 143 entry->type = type;
96 memcpy(entry->buffer, value, value_size); 144 memcpy(entry->buffer, value, value_size);
97 p_hash_map->current_capacity++; 145 return 0;
98 } 146 }
99 147
100 void Dowa_HashMap_PushValue(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size) 148 void Dowa_HashMap_PushValue(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size)
101 { 149 {
102 Dowa_HashMap_PushValueWithType(p_hash_map, key, value, value_size, DOWA_TYPE_BUFFER); 150 Dowa_HashMap_PushValueWithType(p_hash_map, key, value, value_size, DOWA_HASH_MAP_TYPE_BUFFER);
103 } 151 }
104 152
105 void Dowa_HashMap_PopKey(Dowa_PHashMap p_hash_map, char *key) 153 void Dowa_HashMap_PopKey(Dowa_PHashMap p_hash_map, char *key)
106 { 154 {
107 int idx = Dowa_HashMap_GetPosition(p_hash_map, key); 155 int idx = Dowa_HashMap_GetPosition(p_hash_map, key);
117 { 165 {
118 p_hash_map->current_capacity--; 166 p_hash_map->current_capacity--;
119 } 167 }
120 } 168 }
121 169
122 #include <stdio.h>
123
124 void Dowa_HashMap_Print(Dowa_PHashMap map) 170 void Dowa_HashMap_Print(Dowa_PHashMap map)
125 { 171 {
172 printf("\n-----------\n\n");
126 for (size_t i = 0; i < map->capacity; ++i) 173 for (size_t i = 0; i < map->capacity; ++i)
127 { 174 {
128 Dowa_PHashEntry e = map->entries[i]; 175 Dowa_PHashEntry e = map->entries[i];
129 if (!e) continue; 176 if (!e) continue;
130 printf("%s: ", e->key); 177 printf("%s: ", e->key);
131 switch (e->type) 178 switch (e->type)
132 { 179 {
133 case DOWA_TYPE_BUFFER: 180 case DOWA_HASH_MAP_TYPE_BUFFER:
134 { 181 {
135 unsigned char *p = e->buffer; 182 unsigned char *p = e->buffer;
136 for (size_t j = 0; j < e->capacity; ++j) { 183 for (size_t j = 0; j < e->capacity; ++j)
184 {
137 printf("%02x", p[j]); 185 printf("%02x", p[j]);
138 } 186 }
139 printf("\n"); 187 printf("\n");
140 } 188 }
141 break; 189 break;
142 case DOWA_TYPE_STRING: 190 case DOWA_HASH_MAP_TYPE_STRING:
143 { 191 {
144 printf("%s\n", (char*)e->buffer); 192 printf("%s\n", (char*)e->buffer);
145 } 193 }
146 break; 194 break;
147 case DOWA_TYPE_INT: 195 case DOWA_HASH_MAP_TYPE_HASHMAP:
148 { 196 {
149 printf("%d\n", *(int32_t*)e->buffer); 197 printf("This is a hashmap with size of %zu, and pointer %p\n", (Dowa_PHashMap)e->capacity, (void *)e);
198 }
199 break;
200 case DOWA_HASH_MAP_TYPE_INT:
201 {
202 printf("%d\n", *(int32*)e->buffer);
150 } 203 }
151 break; 204 break;
152 default: 205 default:
153 { 206 {
154 printf("<unknown type>\n"); 207 printf("<unknown type>\n");
155 } 208 }
156 } 209 }
157 } 210 }
158 } 211 printf("-----------\n");
159 212 }
160 213
161 214 int Dowa_HashMap_Cache_Folder(Dowa_PHashMap map, const char *folder_path)
162 int Dowa_Cache_Folder(Dowa_PHashMap map, const char *folder_path)
163 { 215 {
164 DIR *dir = opendir(folder_path); 216 DIR *dir = opendir(folder_path);
165 if (!dir) { 217 if (!dir) { perror("opendir"); return -1; }
166 perror("opendir");
167 return -1;
168 }
169 218
170 struct dirent *entry; 219 struct dirent *entry;
171 while ((entry = readdir(dir))) { 220 while ((entry = readdir(dir)))
221 {
172 // skip "." and ".." 222 // skip "." and ".."
173 if (entry->d_name[0] == '.' && 223 if (entry->d_name[0] == '.' &&
174 (entry->d_name[1] == '\0' || 224 (entry->d_name[1] == '\0' ||
175 (entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) 225 (entry->d_name[1] == '.' && entry->d_name[2] == '\0')))
176 continue; 226 continue;
177 227
178 char fullpath[PATH_MAX]; 228 char fullpath[PATH_MAX];
179 snprintf(fullpath, sizeof fullpath, "%s/%s", folder_path, entry->d_name); 229 snprintf(fullpath, sizeof fullpath, "%s/%s", folder_path, entry->d_name);
180 230
181 struct stat st; 231 struct stat st;
182 if (stat(fullpath, &st) < 0 || !S_ISREG(st.st_mode)) 232 if (stat(fullpath, &st) < 0) { perror("stat"); continue; }
183 continue; // skip non-files or errors 233
184 234 if (S_ISREG(st.st_mode))
185 size_t size = (size_t)st.st_size; 235 {
186 FILE *f = fopen(fullpath, "rb"); 236 size_t size = (size_t)st.st_size;
187 if (!f) 237 FILE *f = fopen(fullpath, "rb");
188 { 238 if (!f) { perror("fopen"); continue; }
189 perror("fopen"); 239
190 continue; 240 void *buf = malloc(size);
191 } 241 if (!buf) { perror("malloc"); fclose(f); closedir(dir); return -1; }
192 242
193 void *buf = malloc(size); 243 if (fread(buf, 1, size, f) != size)
194 if (!buf) 244 {
195 { 245 perror("fread");
196 perror("malloc"); 246 free(buf);
247 fclose(f);
248 continue;
249 }
197 fclose(f); 250 fclose(f);
198 closedir(dir); 251
199 return -1; 252 Dowa_HashMap_PushValueWithType(map, entry->d_name, buf, size, DOWA_HASH_MAP_TYPE_STRING);
200 } 253 free(buf); // Dowa_HashMap_PushValue made its own copy
201 254 }
202 if (fread(buf, 1, size, f) != size) 255 else if (S_ISDIR(st.st_mode))
203 { 256 {
204 perror("fread"); 257 Dowa_PHashMap p_child_map = Dowa_HashMap_Create(100);
205 free(buf); 258 if (!p_child_map)
206 fclose(f); 259 {
207 continue; 260 perror("Dowa_HashMap_Create");
208 } 261 return -1;
209 fclose(f); 262 }
210 263 if (Dowa_HashMap_Cache_Folder(p_child_map, fullpath) == -1)
211 // key = filename (d_name), value = file contents 264 {
212 Dowa_HashMap_PushValueWithType(map, entry->d_name, buf, size, DOWA_TYPE_STRING); 265 perror("Dowa_HashMap_Cache_Folder");
213 266 return -1;
214 free(buf); // Dowa_HashMap_PushValue made its own copy 267 }
215 } 268 void *value = Dowa_HashMap_Get(p_child_map, "bar.txt");
216 269
270 // Should not copy as we malloced alredy.
271 if (Dowa_HashMap_PushValueWithTypeNoCopy(map, entry->d_name, p_child_map,
272 sizeof(p_child_map), DOWA_HASH_MAP_TYPE_HASHMAP) == -1)
273 {
274 Dowa_HashMap_Free(map);
275 return -1;
276 }
277 }
278 }
217 closedir(dir); 279 closedir(dir);
218 return 0; 280 return 0;
219 } 281 }