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;
 }