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))
     {