view dowa/dowa.h @ 180:3a4ebe4552bf

Remove playground file as it is not needed to be tracked.
author June Park <parkjune1995@gmail.com>
date Mon, 19 Jan 2026 08:05:02 -0800
parents 70401cf61e97
children a2720eac50ce
line wrap: on
line source

#ifndef DOWA
#define DOWA

#include <stdio.h> // printfs...
#include <string.h> // strdup, strlen, memcmp, memcpy
#include <stdlib.h> // malloc, free, realloc
#include <assert.h> // mostly for TODO
#include <stddef.h> // size_t

#include "dowa_internal.h"

// DLAPI macro for DLL export/import
#ifndef DLAPI
  #ifdef _WIN32
    #ifdef DOWA_EXPORTS
      #define DLAPI __declspec(dllexport)
    #else
      #define DLAPI __declspec(dllimport)
    #endif
  #else
    #define DLAPI extern
  #endif
#endif

#define HASH_KEY_NUMBER 5381
#define ONE_MEGA_BYTE   1048576
#define TRUE  1
#define FALSE 0
#define DOWA_HASH_BUCKET_SIZE 8
#define DOWA_HASH_CACHE_LINE_SIZE 64

#define Dowa_Free(p) do { \
  if (p) {                \
    free(p);              \
    (p) = NULL;           \
  }                       \
} while (0)

typedef unsigned long long   uint64;
typedef long long            int64;
typedef unsigned int         uint32;
typedef int                  int32;
typedef unsigned short       uint16;
typedef short                int16;
typedef unsigned char        uint8;
typedef char                 int8;
typedef char                 boolean;

// --- Arena Allocator --- //
typedef struct {
  char   *buffer;
  size_t  offset;
  size_t  capacity;
} Dowa_Arena;

DLAPI Dowa_Arena *Dowa_Arena_Create(size_t capacity);
DLAPI void       *Dowa_Arena_Allocate(Dowa_Arena *p_arena, size_t size);
DLAPI void       *Dowa_Arena_Allocate_Aligned(Dowa_Arena *p_arena, size_t size, size_t alignment);
DLAPI void        Dowa_Arena_Free(Dowa_Arena *p_arena);
DLAPI void       *Dowa_Arena_Copy(Dowa_Arena *p_arena, const void *p_src, size_t size);
DLAPI void        Dowa_Arena_Reset(Dowa_Arena *p_arena);
DLAPI size_t      Dowa_Arena_Get_Used(Dowa_Arena *p_arena);
DLAPI size_t      Dowa_Arena_Get_Remaining(Dowa_Arena *p_arena);

// --- Array and HashMap --- //

typedef enum {
  DOWA_ALLOCATOR_MALLOC = 0,
  DOWA_ALLOCATOR_ARENA = 1
} Dowa_Allocator_Type;

typedef struct {
  size_t length;
  size_t capacity;
  uint8  allocator_type;
  Dowa_Arena *p_arena;
  void *p_hash;
} Dowa_Array_Header;

typedef struct {
  uint32 hash[DOWA_HASH_BUCKET_SIZE];
  uint32 index[DOWA_HASH_BUCKET_SIZE];
} Dowa_Hash_Bucket;

typedef struct {
  size_t bucket_count;
  size_t item_count;
  size_t tombstone_count;
  uint8  allocator_type;
  Dowa_Arena* p_arena;
  Dowa_Hash_Bucket* p_buckets;
} Dowa_Hash_Index;

#define Dowa_KV(K, V) struct { K key; V value; }

#define dowa__header(a) ((Dowa_Array_Header*)(a) - 1)

// --- Array Macros --- //

#define Dowa_Array_Length(a)   ((a) ? dowa__header(a)->length : 0)
#define Dowa_Array_Capacity(a) ((a) ? dowa__header(a)->capacity : 0)

#define Dowa_Array_Push(a, v) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), 0, NULL), \
   (a)[dowa__header(a)->length++] = (v))

#define Dowa_Array_Push_Arena(a, v, arena) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), 0, (arena)), \
   (a)[dowa__header(a)->length++] = (v))

#define Dowa_Array_Pop(a) ((a)[--dowa__header(a)->length])

#define Dowa_Array_Clear(a) ((a) ? (dowa__header(a)->length = 0) : 0)

#define Dowa_Array_Free(a) ((a) ? (dowa__array_free((a)), (a) = NULL) : 0)

#define Dowa_Array_Reserve(a, n) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), (n), NULL))

#define Dowa_Array_Reserve_Arena(a, n, arena) \
  ((a) = dowa__array_grow((a), sizeof(*(a)), (n), (arena)))

// --- HashMap Macros --- //

#define Dowa_HashMap_Get(m, k) \
  dowa__hashmap_get((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Get_Ptr(m, k) \
  dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Push(m, k, v) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), strlen(k) + 1, NULL); \
    void *p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), strlen(k) + 1); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

#define Dowa_HashMap_Push_Arena(m, k, v, arena) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), strlen(k) + 1, (arena)); \
    void *p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), strlen(k) + 1); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

#define Dowa_HashMap_Has_Key(m, k) \
  dowa__hashmap_has_key((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Delete(m, k) \
  dowa__hashmap_delete((m), sizeof(*(m)), (k), strlen(k) + 1)

#define Dowa_HashMap_Clear(m) dowa__hashmap_clear((m), sizeof(*(m)))

#define Dowa_HashMap_Free(m) ((m) ? (dowa__hashmap_free((m)), (m) = NULL) : 0)

#define Dowa_HashMap_Count(m) dowa__hashmap_count(m)

#define Dowa_HashMap_Get_Binary(m, k, ksize) \
  dowa__hashmap_get((m), sizeof(*(m)), (k), (ksize))

#define Dowa_HashMap_Get_Ptr_Binary(m, k, ksize) \
  dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), (ksize))

#define Dowa_HashMap_Push_Binary(m, k, ksize, v) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), (ksize), NULL); \
    void *p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), (ksize)); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

#define Dowa_HashMap_Push_Binary_Arena(m, k, ksize, v, arena) \
  do { \
    (m) = dowa__hashmap_push((m), sizeof(*(m)), (k), (ksize), (arena)); \
    void *p_kv_temp = dowa__hashmap_get_ptr((m), sizeof(*(m)), (k), (ksize)); \
    if (p_kv_temp) \
      ((typeof(m))p_kv_temp)->value = (v); \
  } while (0)

// --- Array Core Functions --- //

DLAPI void *dowa__array_grow(void *p_array, size_t element_size, size_t minimum_capacity, Dowa_Arena* p_arena);
DLAPI void  dowa__array_free(void *p_array);

// --- HashMap Core Functions --- //

DLAPI uint32  dowa__hash_bytes(void *p_key, size_t key_size);
DLAPI void   *dowa__hashmap_get(void *p_map, size_t element_size, void *p_key, size_t key_size);
DLAPI void   *dowa__hashmap_get_ptr(void *p_map, size_t element_size, void *p_key, size_t key_size);
DLAPI void   *dowa__hashmap_push(void *p_map, size_t element_size, void *p_key, size_t key_size, Dowa_Arena* p_arena);
DLAPI boolean dowa__hashmap_has_key(void *p_map, size_t element_size, void *p_key, size_t key_size);
DLAPI void    dowa__hashmap_delete(void *p_map, size_t element_size, void *p_key, size_t key_size);
DLAPI void    dowa__hashmap_clear(void *p_map, size_t element_size);
DLAPI void    dowa__hashmap_free(void *p_map);
DLAPI size_t  dowa__hashmap_count(void *p_map);

// --- String Manipulation --- //

DLAPI char       *Dowa_String_Slice(char *from, size_t start, size_t end, Dowa_Arena *p_arena);
DLAPI char      **Dowa_String_Split(char *from, char *token, int32 from_length, int32 token_length, Dowa_Arena *p_arena);
DLAPI char       *Dowa_String_Copy_Arena(char *from, Dowa_Arena *p_arena);
DLAPI int32       Dowa_String_Pos_Find(const char *p_from, const char *p_value, const size_t from_length, const size_t value_length);
DLAPI char       *Dowa_String_Find(const char *p_from, const char *p_value, const size_t from_length, const size_t value_length);
DLAPI int32       Dowa_String_Pos_Find_Char(const char *p_from, int c, int32 from_length);
DLAPI char       *Dowa_String_Find_Char(const char *p_from, int c, int32 from_length);
DLAPI char       *Dowa_String_UUID(uint32 seed, void *buffer);

// --- Math --- //
DLAPI uint32      Dowa_Math_Random_Uint32(uint32 seed_number);

#endif