Mercurial
diff dowa/d_memory.c @ 60:d64a8c189a77
Merged
| author | June Park <me@mrjunejune.com> |
|---|---|
| date | Sat, 20 Dec 2025 13:56:01 -0500 |
| parents | 636eab07809d |
| children | a30944e5719e |
line wrap: on
line diff
--- a/dowa/d_memory.c Tue Dec 16 21:01:45 2025 -0500 +++ b/dowa/d_memory.c Sat Dec 20 13:56:01 2025 -0500 @@ -10,6 +10,12 @@ return NULL; } p_arena->buffer = malloc(capacity); + if (p_arena->buffer == NULL) + { + perror("malloc"); + Dowa_Free(p_arena); + return NULL; + } p_arena->offset = 0; p_arena->capacity = capacity; return p_arena; @@ -17,6 +23,9 @@ void *Dowa_Arena_Allocate(Dowa_PArena p_arena, size_t size) { + if (!p_arena || !p_arena->buffer || size == 0) + return NULL; + if (p_arena->offset + size > p_arena->capacity) { return NULL; @@ -48,6 +57,24 @@ return dest; } +void Dowa_Arena_Reset(Dowa_PArena p_arena) +{ + if (!p_arena) return; + p_arena->offset = 0; +} + +size_t Dowa_Arena_Get_Used(Dowa_PArena p_arena) +{ + if (!p_arena) return 0; + return p_arena->offset; +} + +size_t Dowa_Arena_Get_Remaining(Dowa_PArena p_arena) +{ + if (!p_arena) return 0; + return p_arena->capacity - p_arena->offset; +} + // --- HashMap --- // Dowa_PHashMap Dowa_HashMap_Create(size_t capacity) { @@ -84,12 +111,11 @@ return NULL; } p_hash_map->entries = Dowa_Arena_Allocate(p_arena, sizeof(*p_hash_map->entries) * capacity); - memset(p_hash_map->entries, 0, capacity * sizeof *p_hash_map->entries); if (p_hash_map->entries == NULL) { - Dowa_Free(p_hash_map); return NULL; } + memset(p_hash_map->entries, 0, capacity * sizeof *p_hash_map->entries); p_hash_map->capacity = capacity; p_hash_map->current_capacity = 0; p_hash_map->p_arena = p_arena; @@ -109,16 +135,19 @@ else { Dowa_PHashEntry entry; + Dowa_PHashEntry next; if (p_hash_map->entries) { for (int idx=0; idx<p_hash_map->capacity; idx++) { entry = p_hash_map->entries[idx]; - if (entry) + while (entry) { + next = entry->next; Dowa_Free(entry->key); Dowa_Free(entry->buffer); Dowa_Free(entry); + entry = next; } } } @@ -129,6 +158,9 @@ int32 Dowa_HashMap_Get_Position(Dowa_PHashMap p_hash_map, const char *key) { + if (!p_hash_map || !key) + return -1; + int32 hash_val = HASH_KEY_NUMBER; int32 c; while ((c = *key++)) @@ -140,6 +172,9 @@ void *Dowa_HashMap_Get(Dowa_PHashMap p_hash_map, const char *key) { + if (!p_hash_map || !key) + return NULL; + int idx = Dowa_HashMap_Get_Position(p_hash_map, key); Dowa_PHashEntry entry = p_hash_map->entries[idx]; @@ -156,22 +191,27 @@ } -int32 Dowa_HashMap_Push_Value_With_Type_NoCopy(Dowa_PHashMap p_hash_map, const char *key, +int32 Dowa_HashMap_Push_Value_With_Type_NoCopy(Dowa_PHashMap p_hash_map, const char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type) { + if (!p_hash_map || !key || !value) + return -1; + int idx = Dowa_HashMap_Get_Position(p_hash_map, key); Dowa_PHashEntry entry = p_hash_map->entries[idx]; Dowa_PHashEntry prev = NULL; - // Old key + // Old key while (entry) { if (strcmp(entry->key, key) == 0) { // Fails if it the key exists... - return -1; + return -1; } + prev = entry; + entry = entry->next; } // Overriding doesn't really make sense? when copying over @@ -186,21 +226,27 @@ // entry->buffer = value; // entry->capacity = value_size; // entry->type = type; - // return 0; + // return 0; // } // prev = entry; // entry = entry->next; //} - // New Key - entry = p_hash_map->p_arena ? + // New Key + entry = p_hash_map->p_arena ? Dowa_Arena_Allocate(p_hash_map->p_arena, sizeof(Dowa_HashEntry)) : malloc(sizeof(Dowa_HashEntry)); if (!entry) { perror("malloc or arena alloc"); return -1; } entry->key = p_hash_map->p_arena ? - Dowa_Arena_Copy(p_hash_map->p_arena, key, strlen(key) + 1 /* \0 */) : + Dowa_Arena_Copy(p_hash_map->p_arena, key, strlen(key) + 1 /* \0 */) : strdup(key); + if (!entry->key) + { + perror("strdup or arena copy"); + if (!p_hash_map->p_arena) Dowa_Free(entry); + return -1; + } entry->buffer = value; entry->capacity = value_size; entry->type = type; @@ -215,10 +261,13 @@ return 0; } -int32 Dowa_HashMap_Push_Value_With_Type(Dowa_PHashMap p_hash_map, const char *key, +int32 Dowa_HashMap_Push_Value_With_Type(Dowa_PHashMap p_hash_map, const char *key, void *value, size_t value_size, Dowa_HashMap_ValueType type) { + if (!p_hash_map || !key || !value) + return -1; + int idx = Dowa_HashMap_Get_Position(p_hash_map, key); Dowa_PHashEntry entry = p_hash_map->entries[idx]; Dowa_PHashEntry prev = NULL; @@ -282,23 +331,103 @@ void Dowa_HashMap_Pop_Key(Dowa_PHashMap p_hash_map, const char *key) { + if (!p_hash_map || !key) + return; + + int idx = Dowa_HashMap_Get_Position(p_hash_map, key); + Dowa_PHashEntry entry = p_hash_map->entries[idx]; + Dowa_PHashEntry prev = NULL; + + while (entry) + { + if (strcmp(entry->key, key) == 0) + { + if (prev) + prev->next = entry->next; + else + p_hash_map->entries[idx] = entry->next; + + if (!(p_hash_map->p_arena)) + { + Dowa_Free(entry->key); + Dowa_Free(entry->buffer); + Dowa_Free(entry); + } + + if (p_hash_map->current_capacity > 0) + p_hash_map->current_capacity--; + return; + } + prev = entry; + entry = entry->next; + } +} + +boolean Dowa_HashMap_Has_Key(Dowa_PHashMap p_hash_map, const char *key) +{ + if (!p_hash_map || !key) + return FALSE; + int idx = Dowa_HashMap_Get_Position(p_hash_map, key); Dowa_PHashEntry entry = p_hash_map->entries[idx]; - if (entry && !(p_hash_map->p_arena)) + + while (entry) { - Dowa_Free(entry->key); - Dowa_Free(entry->buffer); - Dowa_Free(entry); + if (strcmp(entry->key, key) == 0) + return TRUE; + entry = entry->next; + } + + return FALSE; +} + +void Dowa_HashMap_Clear(Dowa_PHashMap p_hash_map) +{ + if (!p_hash_map) return; + + if (p_hash_map->p_arena) + { + for (int idx=0; idx<p_hash_map->capacity; idx++) + p_hash_map->entries[idx] = NULL; } - p_hash_map->entries[idx] = NULL; - if (p_hash_map->current_capacity > 0) + else { - p_hash_map->current_capacity--; + Dowa_PHashEntry entry; + Dowa_PHashEntry next; + if (p_hash_map->entries) + { + for (int idx=0; idx<p_hash_map->capacity; idx++) + { + entry = p_hash_map->entries[idx]; + while (entry) + { + next = entry->next; + Dowa_Free(entry->key); + Dowa_Free(entry->buffer); + Dowa_Free(entry); + entry = next; + } + p_hash_map->entries[idx] = NULL; + } + } } + p_hash_map->current_capacity = 0; +} + +uint32 Dowa_HashMap_Get_Count(Dowa_PHashMap p_hash_map) +{ + if (!p_hash_map) return 0; + return p_hash_map->current_capacity; } void Dowa_HashMap_Print(Dowa_PHashMap map) { + if (!map) + { + printf("HashMap is NULL\n"); + return; + } + printf("\n-----------\n\n"); for (size_t i = 0; i < map->capacity; ++i) { @@ -347,6 +476,9 @@ int Dowa_HashMap_Cache_Folder(Dowa_PHashMap p_hash_map, const char *folder_path) { + if (!p_hash_map || !folder_path) + return -1; + DIR *dir = opendir(folder_path); if (!dir) { perror("opendir"); return -1; } @@ -371,9 +503,9 @@ FILE *f = fopen(fullpath, "rb"); if (!f) { perror("fopen"); continue; } - void *buf = p_hash_map->p_arena ? - Dowa_Arena_Allocate(p_hash_map->p_arena, size) : - malloc(size); + void *buf = p_hash_map->p_arena ? + Dowa_Arena_Allocate(p_hash_map->p_arena, size + 1) : + malloc(size + 1); if (!buf) { perror("malloc"); fclose(f); closedir(dir); return -1; } @@ -386,8 +518,10 @@ } fclose(f); - Dowa_HashMap_Push_Value_With_Type(p_hash_map, entry->d_name, buf, size, DOWA_HASH_MAP_TYPE_STRING); - Dowa_Free(buf); // Dowa_HashMap_PushValue made its own copy + ((char *)buf)[size] = '\0'; + Dowa_HashMap_Push_Value_With_Type(p_hash_map, entry->d_name, buf, size + 1, DOWA_HASH_MAP_TYPE_STRING); + if (!p_hash_map->p_arena) + Dowa_Free(buf); // Dowa_HashMap_PushValue made its own copy } else if (S_ISDIR(st.st_mode)) {