Mercurial
diff 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 |
line wrap: on
line diff
--- a/dowa/d_memory.c Fri Sep 26 15:14:46 2025 -0700 +++ b/dowa/d_memory.c Sat Sep 27 16:23:04 2025 -0700 @@ -1,15 +1,15 @@ #include "dowa.h" // --- Arena --- // -Dowa_PArena Dowa_Arena_Initialize(size_t capacity) +Dowa_PArena Dowa_Arena_Create(size_t capacity) { - Dowa_PArena p_arena; - p_arena = malloc(capacity); + Dowa_PArena p_arena = malloc(sizeof(Dowa_Arena)); if (p_arena == NULL) { perror("malloc"); return NULL; } + p_arena->buffer = malloc(capacity); p_arena->offset = 0; p_arena->capacity = capacity; return p_arena; @@ -28,8 +28,10 @@ void Dowa_Arena_Free(Dowa_PArena p_arena) { - if (p_arena) { - free(p_arena->buffer); + if (p_arena) + { + if (p_arena->buffer) + free(p_arena->buffer); free(p_arena); } } @@ -43,7 +45,7 @@ { return NULL; } - p_hash_map->entries = calloc(capacity, sizeof *p_hash_map->entries); + p_hash_map->entries = calloc(capacity, sizeof(*p_hash_map->entries)); if (p_hash_map->entries == NULL) { free(p_hash_map); @@ -54,6 +56,29 @@ return p_hash_map; } +void Dowa_HashMap_Free(Dowa_PHashMap p_hash_map) +{ + if (p_hash_map) + { + Dowa_PHashEntry entry; + if (p_hash_map->entries) + { + for (int idx=0; idx<p_hash_map->capacity; idx++) + { + entry = p_hash_map->entries[idx]; + if (entry) + { + free(entry->key); + free(entry->buffer); + free(entry); + } + } + free(p_hash_map->entries); + } + } + free(p_hash_map); +} + int32 Dowa_HashMap_GetPosition(Dowa_PHashMap p_hash_map, char *key) { int32 hash_val = HASH_KEY_NUMBER; @@ -65,41 +90,64 @@ return hash_val % p_hash_map->capacity; } -void Dowa_HashMap_PushValueWithType(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_ValueType type) +void *Dowa_HashMap_Get(Dowa_PHashMap p_hash_map, char *key) +{ + int idx_foo = Dowa_HashMap_GetPosition(p_hash_map, key); + void *value = p_hash_map->entries[idx_foo]; + if (strcmp(((Dowa_PHashEntry) value)->key, key) != 0) + { + return NULL; + } + return ((Dowa_PHashEntry) value)->buffer; +} + +int32 Dowa_HashMap_PushValueWithTypeNoCopy(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type) { int idx = Dowa_HashMap_GetPosition(p_hash_map, key); Dowa_PHashEntry entry = p_hash_map->entries[idx]; if (entry) - { - free(entry->key); free(entry->buffer); - } else { entry = malloc(sizeof(Dowa_HashEntry)); - if (entry == NULL) - { - perror("malloc"); - return; - } + if (entry == NULL) { perror("malloc"); return -1; } + p_hash_map->entries[idx] = entry; + p_hash_map->current_capacity++; + entry->key = strdup(key); } - entry->key = strdup(key); - entry->buffer = malloc(value_size); - if (entry->buffer == NULL) + entry->buffer = value; + entry->capacity = value_size; + entry->type = type; + return 0; +} + +int32 Dowa_HashMap_PushValueWithType(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type) +{ + int idx = Dowa_HashMap_GetPosition(p_hash_map, key); + Dowa_PHashEntry entry = p_hash_map->entries[idx]; + if (entry) + free(entry->buffer); + else { - perror("malloc"); - return; + entry = malloc(sizeof(Dowa_HashEntry)); + if (entry == NULL) { perror("malloc"); return -1; } + + p_hash_map->entries[idx] = entry; + p_hash_map->current_capacity++; + entry->key = strdup(key); } + entry->buffer = malloc(value_size); + if (entry->buffer == NULL) { perror("malloc"); return -1; } entry->capacity = value_size; entry->type = type; memcpy(entry->buffer, value, value_size); - p_hash_map->current_capacity++; + return 0; } void Dowa_HashMap_PushValue(Dowa_PHashMap p_hash_map, char *key, void *value, size_t value_size) { - Dowa_HashMap_PushValueWithType(p_hash_map, key, value, value_size, DOWA_TYPE_BUFFER); + Dowa_HashMap_PushValueWithType(p_hash_map, key, value, value_size, DOWA_HASH_MAP_TYPE_BUFFER); } void Dowa_HashMap_PopKey(Dowa_PHashMap p_hash_map, char *key) @@ -119,10 +167,9 @@ } } -#include <stdio.h> - void Dowa_HashMap_Print(Dowa_PHashMap map) { + printf("\n-----------\n\n"); for (size_t i = 0; i < map->capacity; ++i) { Dowa_PHashEntry e = map->entries[i]; @@ -130,23 +177,29 @@ printf("%s: ", e->key); switch (e->type) { - case DOWA_TYPE_BUFFER: + case DOWA_HASH_MAP_TYPE_BUFFER: { unsigned char *p = e->buffer; - for (size_t j = 0; j < e->capacity; ++j) { + for (size_t j = 0; j < e->capacity; ++j) + { printf("%02x", p[j]); } printf("\n"); } break; - case DOWA_TYPE_STRING: + case DOWA_HASH_MAP_TYPE_STRING: { printf("%s\n", (char*)e->buffer); } break; - case DOWA_TYPE_INT: + case DOWA_HASH_MAP_TYPE_HASHMAP: { - printf("%d\n", *(int32_t*)e->buffer); + printf("This is a hashmap with size of %zu, and pointer %p\n", (Dowa_PHashMap)e->capacity, (void *)e); + } + break; + case DOWA_HASH_MAP_TYPE_INT: + { + printf("%d\n", *(int32*)e->buffer); } break; default: @@ -155,20 +208,17 @@ } } } + printf("-----------\n"); } - - -int Dowa_Cache_Folder(Dowa_PHashMap map, const char *folder_path) +int Dowa_HashMap_Cache_Folder(Dowa_PHashMap map, const char *folder_path) { DIR *dir = opendir(folder_path); - if (!dir) { - perror("opendir"); - return -1; - } + if (!dir) { perror("opendir"); return -1; } struct dirent *entry; - while ((entry = readdir(dir))) { + while ((entry = readdir(dir))) + { // skip "." and ".." if (entry->d_name[0] == '.' && (entry->d_name[1] == '\0' || @@ -179,41 +229,53 @@ snprintf(fullpath, sizeof fullpath, "%s/%s", folder_path, entry->d_name); struct stat st; - if (stat(fullpath, &st) < 0 || !S_ISREG(st.st_mode)) - continue; // skip non-files or errors + if (stat(fullpath, &st) < 0) { perror("stat"); continue; } - size_t size = (size_t)st.st_size; - FILE *f = fopen(fullpath, "rb"); - if (!f) + if (S_ISREG(st.st_mode)) { - perror("fopen"); - continue; - } + size_t size = (size_t)st.st_size; + FILE *f = fopen(fullpath, "rb"); + if (!f) { perror("fopen"); continue; } + + void *buf = malloc(size); + if (!buf) { perror("malloc"); fclose(f); closedir(dir); return -1; } - void *buf = malloc(size); - if (!buf) - { - perror("malloc"); + if (fread(buf, 1, size, f) != size) + { + perror("fread"); + free(buf); + fclose(f); + continue; + } fclose(f); - closedir(dir); - return -1; + + Dowa_HashMap_PushValueWithType(map, entry->d_name, buf, size, DOWA_HASH_MAP_TYPE_STRING); + free(buf); // Dowa_HashMap_PushValue made its own copy } - - if (fread(buf, 1, size, f) != size) + else if (S_ISDIR(st.st_mode)) { - perror("fread"); - free(buf); - fclose(f); - continue; - } - fclose(f); + Dowa_PHashMap p_child_map = Dowa_HashMap_Create(100); + if (!p_child_map) + { + perror("Dowa_HashMap_Create"); + return -1; + } + if (Dowa_HashMap_Cache_Folder(p_child_map, fullpath) == -1) + { + perror("Dowa_HashMap_Cache_Folder"); + return -1; + } + void *value = Dowa_HashMap_Get(p_child_map, "bar.txt"); - // key = filename (d_name), value = file contents - Dowa_HashMap_PushValueWithType(map, entry->d_name, buf, size, DOWA_TYPE_STRING); - - free(buf); // Dowa_HashMap_PushValue made its own copy + // Should not copy as we malloced alredy. + if (Dowa_HashMap_PushValueWithTypeNoCopy(map, entry->d_name, p_child_map, + sizeof(p_child_map), DOWA_HASH_MAP_TYPE_HASHMAP) == -1) + { + Dowa_HashMap_Free(map); + return -1; + } + } } - closedir(dir); return 0; }