Mercurial
comparison dowa/d_memory.c @ 65:ecb6ee6a22c3
[Misc] I will no longer drink cool aids of capital P.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Wed, 24 Dec 2025 06:22:59 -0800 |
| parents | a30944e5719e |
| children | 75de5903355c |
comparison
equal
deleted
inserted
replaced
| 64:a30944e5719e | 65:ecb6ee6a22c3 |
|---|---|
| 1 #include "dowa.h" | 1 #include "dowa.h" |
| 2 | 2 |
| 3 // --- Arena --- // | 3 // --- Arena --- // |
| 4 Dowa_PArena Dowa_Arena_Create(size_t capacity) | 4 Dowa_Arena *Dowa_Arena_Create(size_t capacity) |
| 5 { | 5 { |
| 6 Dowa_PArena p_arena = malloc(sizeof(Dowa_Arena)); | 6 Dowa_Arena *p_arena = malloc(sizeof(Dowa_Arena)); |
| 7 if (p_arena == NULL) | 7 if (p_arena == NULL) |
| 8 { | 8 { |
| 9 perror("malloc"); | 9 perror("malloc"); |
| 10 return NULL; | 10 return NULL; |
| 11 } | 11 } |
| 19 p_arena->offset = 0; | 19 p_arena->offset = 0; |
| 20 p_arena->capacity = capacity; | 20 p_arena->capacity = capacity; |
| 21 return p_arena; | 21 return p_arena; |
| 22 } | 22 } |
| 23 | 23 |
| 24 void *Dowa_Arena_Allocate(Dowa_PArena p_arena, size_t size) | 24 void *Dowa_Arena_Allocate(Dowa_Arena *p_arena, size_t size) |
| 25 { | 25 { |
| 26 if (!p_arena || !p_arena->buffer || size == 0) | 26 if (!p_arena || !p_arena->buffer || size == 0) |
| 27 return NULL; | 27 return NULL; |
| 28 | 28 |
| 29 if (p_arena->offset + size > p_arena->capacity) | 29 if (p_arena->offset + size > p_arena->capacity) |
| 33 void *currnet_ptr = p_arena->buffer + p_arena->offset; | 33 void *currnet_ptr = p_arena->buffer + p_arena->offset; |
| 34 p_arena->offset += size; | 34 p_arena->offset += size; |
| 35 return currnet_ptr; | 35 return currnet_ptr; |
| 36 } | 36 } |
| 37 | 37 |
| 38 void Dowa_Arena_Destroy(Dowa_PArena p_arena) | 38 void Dowa_Arena_Destroy(Dowa_Arena *p_arena) |
| 39 { | 39 { |
| 40 if (!p_arena) return; | 40 if (!p_arena) return; |
| 41 | 41 |
| 42 if (p_arena->buffer) | 42 if (p_arena->buffer) |
| 43 Dowa_Free(p_arena->buffer); | 43 Dowa_Free(p_arena->buffer); |
| 44 Dowa_Free(p_arena); | 44 Dowa_Free(p_arena); |
| 45 } | 45 } |
| 46 | 46 |
| 47 void *Dowa_Arena_Copy(Dowa_PArena p_arena, const void *src, size_t size) | 47 void *Dowa_Arena_Copy(Dowa_Arena *p_arena, const void *src, size_t size) |
| 48 { | 48 { |
| 49 if (p_arena == NULL || src == NULL || size == 0) | 49 if (p_arena == NULL || src == NULL || size == 0) |
| 50 return NULL; | 50 return NULL; |
| 51 | 51 |
| 52 void *dest = Dowa_Arena_Allocate(p_arena, size); | 52 void *dest = Dowa_Arena_Allocate(p_arena, size); |
| 55 | 55 |
| 56 memcpy(dest, src, size); | 56 memcpy(dest, src, size); |
| 57 return dest; | 57 return dest; |
| 58 } | 58 } |
| 59 | 59 |
| 60 void Dowa_Arena_Reset(Dowa_PArena p_arena) | 60 void Dowa_Arena_Reset(Dowa_Arena *p_arena) |
| 61 { | 61 { |
| 62 if (!p_arena) return; | 62 if (!p_arena) return; |
| 63 p_arena->offset = 0; | 63 p_arena->offset = 0; |
| 64 } | 64 } |
| 65 | 65 |
| 66 size_t Dowa_Arena_Get_Used(Dowa_PArena p_arena) | 66 size_t Dowa_Arena_Get_Used(Dowa_Arena *p_arena) |
| 67 { | 67 { |
| 68 if (!p_arena) return 0; | 68 if (!p_arena) return 0; |
| 69 return p_arena->offset; | 69 return p_arena->offset; |
| 70 } | 70 } |
| 71 | 71 |
| 72 size_t Dowa_Arena_Get_Remaining(Dowa_PArena p_arena) | 72 size_t Dowa_Arena_Get_Remaining(Dowa_Arena *p_arena) |
| 73 { | 73 { |
| 74 if (!p_arena) return 0; | 74 if (!p_arena) return 0; |
| 75 return p_arena->capacity - p_arena->offset; | 75 return p_arena->capacity - p_arena->offset; |
| 76 } | 76 } |
| 77 | 77 |
| 78 // --- HashMap --- // | 78 // --- HashMap --- // |
| 79 Dowa_PHashMap Dowa_HashMap_Create(size_t capacity) | 79 Dowa_HashMap *Dowa_HashMap_Create(size_t capacity) |
| 80 { | 80 { |
| 81 Dowa_PHashMap p_hash_map; | 81 Dowa_HashMap *p_hash_map; |
| 82 p_hash_map = malloc(sizeof(Dowa_HashMap)); | 82 p_hash_map = malloc(sizeof(Dowa_HashMap)); |
| 83 if (p_hash_map == NULL) | 83 if (p_hash_map == NULL) |
| 84 { | 84 { |
| 85 return NULL; | 85 return NULL; |
| 86 } | 86 } |
| 94 p_hash_map->current_capacity = 0; | 94 p_hash_map->current_capacity = 0; |
| 95 p_hash_map->p_arena = NULL; | 95 p_hash_map->p_arena = NULL; |
| 96 return p_hash_map; | 96 return p_hash_map; |
| 97 } | 97 } |
| 98 | 98 |
| 99 Dowa_PHashMap Dowa_HashMap_Create_With_Arena(size_t capacity, Dowa_PArena p_arena) | 99 Dowa_HashMap *Dowa_HashMap_Create_With_Arena(size_t capacity, Dowa_Arena *p_arena) |
| 100 { | 100 { |
| 101 if (p_arena == NULL) | 101 if (p_arena == NULL) |
| 102 { | 102 { |
| 103 printf("Arena is NULL\n"); | 103 printf("Arena is NULL\n"); |
| 104 return Dowa_HashMap_Create(capacity); | 104 return Dowa_HashMap_Create(capacity); |
| 105 } | 105 } |
| 106 | 106 |
| 107 Dowa_PHashMap p_hash_map; | 107 Dowa_HashMap *p_hash_map; |
| 108 p_hash_map = Dowa_Arena_Allocate(p_arena, sizeof(Dowa_HashMap)); | 108 p_hash_map = Dowa_Arena_Allocate(p_arena, sizeof(Dowa_HashMap)); |
| 109 if (p_hash_map == NULL) | 109 if (p_hash_map == NULL) |
| 110 { | 110 { |
| 111 return NULL; | 111 return NULL; |
| 112 } | 112 } |
| 120 p_hash_map->current_capacity = 0; | 120 p_hash_map->current_capacity = 0; |
| 121 p_hash_map->p_arena = p_arena; | 121 p_hash_map->p_arena = p_arena; |
| 122 return p_hash_map; | 122 return p_hash_map; |
| 123 } | 123 } |
| 124 | 124 |
| 125 void Dowa_HashMap_Destroy(Dowa_PHashMap p_hash_map) | 125 void Dowa_HashMap_Destroy(Dowa_HashMap *p_hash_map) |
| 126 { | 126 { |
| 127 if (!p_hash_map) return; | 127 if (!p_hash_map) return; |
| 128 | 128 |
| 129 if (p_hash_map->p_arena) | 129 if (p_hash_map->p_arena) |
| 130 { | 130 { |
| 132 // Dowa_Arena_Destroy(p_hash_map->p_arena); | 132 // Dowa_Arena_Destroy(p_hash_map->p_arena); |
| 133 return; | 133 return; |
| 134 } | 134 } |
| 135 else | 135 else |
| 136 { | 136 { |
| 137 Dowa_PHashEntry entry; | 137 Dowa_HashEntry *entry; |
| 138 Dowa_PHashEntry next; | 138 Dowa_HashEntry *next; |
| 139 if (p_hash_map->entries) | 139 if (p_hash_map->entries) |
| 140 { | 140 { |
| 141 for (int idx=0; idx<p_hash_map->capacity; idx++) | 141 for (int idx=0; idx<p_hash_map->capacity; idx++) |
| 142 { | 142 { |
| 143 entry = p_hash_map->entries[idx]; | 143 entry = p_hash_map->entries[idx]; |
| 154 Dowa_Free(p_hash_map->entries); | 154 Dowa_Free(p_hash_map->entries); |
| 155 } | 155 } |
| 156 Dowa_Free(p_hash_map); | 156 Dowa_Free(p_hash_map); |
| 157 } | 157 } |
| 158 | 158 |
| 159 int32 Dowa_HashMap_Get_Position(Dowa_PHashMap p_hash_map, const char *key) | 159 int32 Dowa_HashMap_Get_Position(Dowa_HashMap *p_hash_map, const char *key) |
| 160 { | 160 { |
| 161 if (!p_hash_map || !key) | 161 if (!p_hash_map || !key) |
| 162 return -1; | 162 return -1; |
| 163 | 163 |
| 164 int32 hash_val = HASH_KEY_NUMBER; | 164 int32 hash_val = HASH_KEY_NUMBER; |
| 168 hash_val = (hash_val << 5) + hash_val + c; | 168 hash_val = (hash_val << 5) + hash_val + c; |
| 169 } | 169 } |
| 170 return hash_val % p_hash_map->capacity; | 170 return hash_val % p_hash_map->capacity; |
| 171 } | 171 } |
| 172 | 172 |
| 173 void *Dowa_HashMap_Get(Dowa_PHashMap p_hash_map, const char *key) | 173 void *Dowa_HashMap_Get(Dowa_HashMap *p_hash_map, const char *key) |
| 174 { | 174 { |
| 175 if (!p_hash_map || !key) | 175 if (!p_hash_map || !key) |
| 176 return NULL; | 176 return NULL; |
| 177 | 177 |
| 178 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); | 178 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); |
| 179 Dowa_PHashEntry entry = p_hash_map->entries[idx]; | 179 Dowa_HashEntry *entry = p_hash_map->entries[idx]; |
| 180 | 180 |
| 181 while (entry) | 181 while (entry) |
| 182 { | 182 { |
| 183 if (strcmp(entry->key, key) == 0) | 183 if (strcmp(entry->key, key) == 0) |
| 184 { | 184 { |
| 189 | 189 |
| 190 return NULL; | 190 return NULL; |
| 191 } | 191 } |
| 192 | 192 |
| 193 | 193 |
| 194 int32 Dowa_HashMap_Push_Value_With_Type_NoCopy(Dowa_PHashMap p_hash_map, const char *key, | 194 int32 Dowa_HashMap_Push_Value_With_Type_NoCopy(Dowa_HashMap *p_hash_map, const char *key, |
| 195 void *value, size_t value_size, | 195 void *value, size_t value_size, |
| 196 Dowa_HashMap_ValueType type) | 196 Dowa_HashMap_ValueType type) |
| 197 { | 197 { |
| 198 if (!p_hash_map || !key || !value) | 198 if (!p_hash_map || !key || !value) |
| 199 return -1; | 199 return -1; |
| 200 | 200 |
| 201 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); | 201 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); |
| 202 Dowa_PHashEntry entry = p_hash_map->entries[idx]; | 202 Dowa_HashEntry *entry = p_hash_map->entries[idx]; |
| 203 Dowa_PHashEntry prev = NULL; | 203 Dowa_HashEntry *prev = NULL; |
| 204 | 204 |
| 205 // Old key | 205 // Old key |
| 206 while (entry) | 206 while (entry) |
| 207 { | 207 { |
| 208 if (strcmp(entry->key, key) == 0) | 208 if (strcmp(entry->key, key) == 0) |
| 259 | 259 |
| 260 p_hash_map->current_capacity++; | 260 p_hash_map->current_capacity++; |
| 261 return 0; | 261 return 0; |
| 262 } | 262 } |
| 263 | 263 |
| 264 int32 Dowa_HashMap_Push_Value_With_Type(Dowa_PHashMap p_hash_map, const char *key, | 264 int32 Dowa_HashMap_Push_Value_With_Type(Dowa_HashMap *p_hash_map, const char *key, |
| 265 void *value, size_t value_size, | 265 void *value, size_t value_size, |
| 266 Dowa_HashMap_ValueType type) | 266 Dowa_HashMap_ValueType type) |
| 267 { | 267 { |
| 268 if (!p_hash_map || !key || !value) | 268 if (!p_hash_map || !key || !value) |
| 269 return -1; | 269 return -1; |
| 270 | 270 |
| 271 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); | 271 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); |
| 272 Dowa_PHashEntry entry = p_hash_map->entries[idx]; | 272 Dowa_HashEntry *entry = p_hash_map->entries[idx]; |
| 273 Dowa_PHashEntry prev = NULL; | 273 Dowa_HashEntry *prev = NULL; |
| 274 | 274 |
| 275 // Check for existing key | 275 // Check for existing key |
| 276 while (entry) | 276 while (entry) |
| 277 { | 277 { |
| 278 if (strcmp(entry->key, key) == 0) | 278 if (strcmp(entry->key, key) == 0) |
| 322 | 322 |
| 323 p_hash_map->current_capacity++; | 323 p_hash_map->current_capacity++; |
| 324 return 0; | 324 return 0; |
| 325 } | 325 } |
| 326 | 326 |
| 327 void Dowa_HashMap_Push_Value(Dowa_PHashMap p_hash_map, const char *key, void *value, size_t value_size) | 327 void Dowa_HashMap_Push_Value(Dowa_HashMap *p_hash_map, const char *key, void *value, size_t value_size) |
| 328 { | 328 { |
| 329 Dowa_HashMap_Push_Value_With_Type(p_hash_map, key, value, value_size, DOWA_HASH_MAP_TYPE_BUFFER); | 329 Dowa_HashMap_Push_Value_With_Type(p_hash_map, key, value, value_size, DOWA_HASH_MAP_TYPE_BUFFER); |
| 330 } | 330 } |
| 331 | 331 |
| 332 void Dowa_HashMap_Pop_Key(Dowa_PHashMap p_hash_map, const char *key) | 332 void Dowa_HashMap_Pop_Key(Dowa_HashMap *p_hash_map, const char *key) |
| 333 { | 333 { |
| 334 if (!p_hash_map || !key) | 334 if (!p_hash_map || !key) |
| 335 return; | 335 return; |
| 336 | 336 |
| 337 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); | 337 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); |
| 338 Dowa_PHashEntry entry = p_hash_map->entries[idx]; | 338 Dowa_HashEntry *entry = p_hash_map->entries[idx]; |
| 339 Dowa_PHashEntry prev = NULL; | 339 Dowa_HashEntry *prev = NULL; |
| 340 | 340 |
| 341 while (entry) | 341 while (entry) |
| 342 { | 342 { |
| 343 if (strcmp(entry->key, key) == 0) | 343 if (strcmp(entry->key, key) == 0) |
| 344 { | 344 { |
| 361 prev = entry; | 361 prev = entry; |
| 362 entry = entry->next; | 362 entry = entry->next; |
| 363 } | 363 } |
| 364 } | 364 } |
| 365 | 365 |
| 366 boolean Dowa_HashMap_Has_Key(Dowa_PHashMap p_hash_map, const char *key) | 366 boolean Dowa_HashMap_Has_Key(Dowa_HashMap *p_hash_map, const char *key) |
| 367 { | 367 { |
| 368 if (!p_hash_map || !key) | 368 if (!p_hash_map || !key) |
| 369 return FALSE; | 369 return FALSE; |
| 370 | 370 |
| 371 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); | 371 int idx = Dowa_HashMap_Get_Position(p_hash_map, key); |
| 372 Dowa_PHashEntry entry = p_hash_map->entries[idx]; | 372 Dowa_HashEntry *entry = p_hash_map->entries[idx]; |
| 373 | 373 |
| 374 while (entry) | 374 while (entry) |
| 375 { | 375 { |
| 376 if (strcmp(entry->key, key) == 0) | 376 if (strcmp(entry->key, key) == 0) |
| 377 return TRUE; | 377 return TRUE; |
| 379 } | 379 } |
| 380 | 380 |
| 381 return FALSE; | 381 return FALSE; |
| 382 } | 382 } |
| 383 | 383 |
| 384 void Dowa_HashMap_Clear(Dowa_PHashMap p_hash_map) | 384 void Dowa_HashMap_Clear(Dowa_HashMap *p_hash_map) |
| 385 { | 385 { |
| 386 if (!p_hash_map) return; | 386 if (!p_hash_map) return; |
| 387 | 387 |
| 388 if (p_hash_map->p_arena) | 388 if (p_hash_map->p_arena) |
| 389 { | 389 { |
| 390 for (int idx=0; idx<p_hash_map->capacity; idx++) | 390 for (int idx=0; idx<p_hash_map->capacity; idx++) |
| 391 p_hash_map->entries[idx] = NULL; | 391 p_hash_map->entries[idx] = NULL; |
| 392 } | 392 } |
| 393 else | 393 else |
| 394 { | 394 { |
| 395 Dowa_PHashEntry entry; | 395 Dowa_HashEntry *entry; |
| 396 Dowa_PHashEntry next; | 396 Dowa_HashEntry *next; |
| 397 if (p_hash_map->entries) | 397 if (p_hash_map->entries) |
| 398 { | 398 { |
| 399 for (int idx=0; idx<p_hash_map->capacity; idx++) | 399 for (int idx=0; idx<p_hash_map->capacity; idx++) |
| 400 { | 400 { |
| 401 entry = p_hash_map->entries[idx]; | 401 entry = p_hash_map->entries[idx]; |
| 412 } | 412 } |
| 413 } | 413 } |
| 414 p_hash_map->current_capacity = 0; | 414 p_hash_map->current_capacity = 0; |
| 415 } | 415 } |
| 416 | 416 |
| 417 uint32 Dowa_HashMap_Get_Count(Dowa_PHashMap p_hash_map) | 417 uint32 Dowa_HashMap_Get_Count(Dowa_HashMap *p_hash_map) |
| 418 { | 418 { |
| 419 if (!p_hash_map) return 0; | 419 if (!p_hash_map) return 0; |
| 420 return p_hash_map->current_capacity; | 420 return p_hash_map->current_capacity; |
| 421 } | 421 } |
| 422 | 422 |
| 423 void Dowa_HashMap_Print(Dowa_PHashMap map) | 423 void Dowa_HashMap_Print(Dowa_HashMap *map) |
| 424 { | 424 { |
| 425 if (!map) | 425 if (!map) |
| 426 { | 426 { |
| 427 printf("HashMap is NULL\n"); | 427 printf("HashMap is NULL\n"); |
| 428 return; | 428 return; |
| 429 } | 429 } |
| 430 | 430 |
| 431 printf("\n-----------\n\n"); | 431 printf("\n-----------\n\n"); |
| 432 for (size_t i = 0; i < map->capacity; ++i) | 432 for (size_t i = 0; i < map->capacity; ++i) |
| 433 { | 433 { |
| 434 Dowa_PHashEntry e = map->entries[i]; | 434 Dowa_HashEntry *e = map->entries[i]; |
| 435 while (e) | 435 while (e) |
| 436 { | 436 { |
| 437 if (!e) break; | 437 if (!e) break; |
| 438 printf("%s: ", e->key); | 438 printf("%s: ", e->key); |
| 439 switch (e->type) | 439 switch (e->type) |
| 448 printf("\n"); | 448 printf("\n"); |
| 449 } | 449 } |
| 450 break; | 450 break; |
| 451 case DOWA_HASH_MAP_TYPE_STRING: | 451 case DOWA_HASH_MAP_TYPE_STRING: |
| 452 { | 452 { |
| 453 printf("%s\n", (char*)e->buffer); | 453 printf("%.*s\n", (int)e->capacity, (char*)e->buffer); |
| 454 } | 454 } |
| 455 break; | 455 break; |
| 456 case DOWA_HASH_MAP_TYPE_HASHMAP: | 456 case DOWA_HASH_MAP_TYPE_HASHMAP: |
| 457 { | 457 { |
| 458 printf("This is a hashmap with size of %zu, and pointer %p\n", e->capacity, (void *)e); | 458 printf("This is a hashmap with size of %zu, and pointer %p\n", e->capacity, (void *)e); |
| 473 } | 473 } |
| 474 printf("-----------\n"); | 474 printf("-----------\n"); |
| 475 } | 475 } |
| 476 | 476 |
| 477 #ifdef DIRECTORY | 477 #ifdef DIRECTORY |
| 478 int Dowa_HashMap_Cache_Folder(Dowa_PHashMap p_hash_map, const char *folder_path) | 478 int Dowa_HashMap_Cache_Folder(Dowa_HashMap *p_hash_map, const char *folder_path) |
| 479 { | 479 { |
| 480 if (!p_hash_map || !folder_path) | 480 if (!p_hash_map || !folder_path) |
| 481 return -1; | 481 return -1; |
| 482 | 482 |
| 483 DIR *dir = opendir(folder_path); | 483 DIR *dir = opendir(folder_path); |
| 525 Dowa_Free(buf); // Dowa_HashMap_PushValue made its own copy | 525 Dowa_Free(buf); // Dowa_HashMap_PushValue made its own copy |
| 526 } | 526 } |
| 527 else if (S_ISDIR(st.st_mode)) | 527 else if (S_ISDIR(st.st_mode)) |
| 528 { | 528 { |
| 529 // TODO: Adjust the sizes of the recursive map? | 529 // TODO: Adjust the sizes of the recursive map? |
| 530 Dowa_PHashMap p_child_map = Dowa_HashMap_Create_With_Arena(100, p_hash_map->p_arena); | 530 Dowa_HashMap *p_child_map = Dowa_HashMap_Create_With_Arena(100, p_hash_map->p_arena); |
| 531 if (!p_child_map) | 531 if (!p_child_map) |
| 532 { | 532 { |
| 533 perror("Dowa_HashMap_Create"); | 533 perror("Dowa_HashMap_Create"); |
| 534 return -1; | 534 return -1; |
| 535 } | 535 } |