Mercurial
comparison dowa/d_memory.c @ 92:655ea0b661fd
[Seobeo] Added few endpoints for handling files. [Dowa] Added few functions for random number and generating uuids
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Fri, 02 Jan 2026 17:47:10 -0800 |
| parents | d39e8860a361 |
| children |
comparison
equal
deleted
inserted
replaced
| 91:19cccf6e866a | 92:655ea0b661fd |
|---|---|
| 1 #include "dowa.h" | 1 #include "dowa.h" |
| 2 | |
| 3 #ifndef DOWA_ALIGNMENT | |
| 4 #define DOWA_ALIGNMENT sizeof(void*) * 2 | |
| 5 #endif | |
| 2 | 6 |
| 3 // --- Arena --- // | 7 // --- Arena --- // |
| 4 Dowa_Arena *Dowa_Arena_Create(size_t capacity) | 8 Dowa_Arena *Dowa_Arena_Create(size_t capacity) |
| 5 { | 9 { |
| 6 Dowa_Arena *p_arena = malloc(sizeof(Dowa_Arena)); | 10 Dowa_Arena *p_arena = malloc(sizeof(Dowa_Arena)); |
| 21 return p_arena; | 25 return p_arena; |
| 22 } | 26 } |
| 23 | 27 |
| 24 void *Dowa_Arena_Allocate(Dowa_Arena *p_arena, size_t size) | 28 void *Dowa_Arena_Allocate(Dowa_Arena *p_arena, size_t size) |
| 25 { | 29 { |
| 26 return Dowa_Arena_Allocate_Aligned(p_arena, size, sizeof(void*) * 2); | 30 return Dowa_Arena_Allocate_Aligned(p_arena, size, DOWA_ALIGNMENT); |
| 27 } | 31 } |
| 28 | 32 |
| 29 void Dowa_Arena_Free(Dowa_Arena *p_arena) | 33 void Dowa_Arena_Free(Dowa_Arena *p_arena) |
| 30 { | 34 { |
| 31 if (!p_arena) | 35 if (!p_arena) |
| 83 void *p_result = p_arena->buffer + p_arena->offset; | 87 void *p_result = p_arena->buffer + p_arena->offset; |
| 84 p_arena->offset += size; | 88 p_arena->offset += size; |
| 85 return p_result; | 89 return p_result; |
| 86 } | 90 } |
| 87 | 91 |
| 88 // --- NEW stb_ds-style Array Implementation --- // | 92 // --- Array Implementation --- // |
| 89 | 93 |
| 90 void* dowa__array_grow(void* p_array, size_t element_size, size_t minimum_capacity, Dowa_Arena* p_arena) | 94 void *dowa__array_grow(void* p_array, size_t element_size, size_t minimum_capacity, Dowa_Arena* p_arena) |
| 91 { | 95 { |
| 92 Dowa_Array_Header* p_header; | 96 Dowa_Array_Header* p_header; |
| 93 size_t new_capacity; | 97 size_t new_capacity; |
| 94 size_t current_capacity; | 98 size_t current_capacity; |
| 95 | 99 |
| 107 else | 111 else |
| 108 { | 112 { |
| 109 current_capacity = 0; | 113 current_capacity = 0; |
| 110 } | 114 } |
| 111 | 115 |
| 112 // Calculate needed capacity: if minimum_capacity is 0, we need room for at least one more element | 116 // if minimum_capacity is 0, we need room for at least one more element |
| 113 size_t needed_capacity = minimum_capacity; | 117 size_t needed_capacity = minimum_capacity; |
| 114 if (p_array && needed_capacity == 0) | 118 if (p_array && needed_capacity == 0) |
| 115 needed_capacity = p_header->length + 1; | 119 needed_capacity = p_header->length + 1; |
| 116 | 120 |
| 117 if (current_capacity >= needed_capacity && p_array != NULL) | 121 if (current_capacity >= needed_capacity && p_array != NULL) |
| 125 | 129 |
| 126 size_t total_size = sizeof(Dowa_Array_Header) + (element_size * new_capacity); | 130 size_t total_size = sizeof(Dowa_Array_Header) + (element_size * new_capacity); |
| 127 | 131 |
| 128 if (p_arena) | 132 if (p_arena) |
| 129 { | 133 { |
| 130 // Array header and data must be properly aligned | 134 Dowa_Array_Header* p_new_header = (Dowa_Array_Header*)Dowa_Arena_Allocate_Aligned(p_arena, total_size, DOWA_ALIGNMENT); |
| 131 size_t alignment = element_size >= 16 ? 16 : (element_size >= 8 ? 8 : element_size); | |
| 132 Dowa_Array_Header* p_new_header = (Dowa_Array_Header*)Dowa_Arena_Allocate_Aligned(p_arena, total_size, alignment); | |
| 133 if (!p_new_header) | 135 if (!p_new_header) |
| 134 return p_array; | 136 return p_array; |
| 135 | 137 |
| 136 void* p_new_array = (char*)p_new_header + sizeof(Dowa_Array_Header); | 138 void* p_new_array = (char*)p_new_header + sizeof(Dowa_Array_Header); |
| 137 | 139 |
| 189 | 191 |
| 190 if (p_header->allocator_type == DOWA_ALLOCATOR_MALLOC) | 192 if (p_header->allocator_type == DOWA_ALLOCATOR_MALLOC) |
| 191 free(p_header); | 193 free(p_header); |
| 192 } | 194 } |
| 193 | 195 |
| 194 // --- NEW stb_ds-style HashMap Implementation --- // | 196 // --- HashMap Implementation --- // |
| 195 | 197 |
| 196 #define DOWA_HASH_EMPTY 0xFFFFFFFF | 198 #define DOWA_HASH_EMPTY 0xFFFFFFFF |
| 197 #define DOWA_HASH_TOMBSTONE 0xFFFFFFFE | 199 #define DOWA_HASH_TOMBSTONE 0xFFFFFFFE |
| 198 | 200 |
| 199 uint32 dowa__hash_bytes(void* p_key, size_t key_size) | 201 uint32 dowa__hash_bytes(void* p_key, size_t key_size) |
| 217 | 219 |
| 218 Dowa_Array_Header* p_header = dowa__header(p_map); | 220 Dowa_Array_Header* p_header = dowa__header(p_map); |
| 219 return (Dowa_Hash_Index*)p_header->p_hash; | 221 return (Dowa_Hash_Index*)p_header->p_hash; |
| 220 } | 222 } |
| 221 | 223 |
| 222 static void* dowa__hashmap_find_slot(void* p_map, size_t element_size, void* p_key, size_t key_size, uint32 hash, boolean* p_found) | 224 static void *dowa__hashmap_find_slot(void *p_map, size_t element_size, void *p_key, size_t key_size, uint32 hash, boolean *p_found) |
| 223 { | 225 { |
| 224 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); | 226 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); |
| 225 if (!p_index || !p_index->p_buckets) | 227 if (!p_index || !p_index->p_buckets) |
| 226 { | 228 { |
| 227 *p_found = FALSE; | 229 *p_found = FALSE; |
| 245 } | 247 } |
| 246 | 248 |
| 247 if (p_bucket->hash[i] == hash && p_bucket->index[i] != DOWA_HASH_TOMBSTONE) | 249 if (p_bucket->hash[i] == hash && p_bucket->index[i] != DOWA_HASH_TOMBSTONE) |
| 248 { | 250 { |
| 249 uint32 array_index = p_bucket->index[i]; | 251 uint32 array_index = p_bucket->index[i]; |
| 250 char* p_element = (char*)p_map + (array_index * element_size); | 252 char *p_element = (char*)p_map + (array_index * element_size); |
| 251 | 253 |
| 252 char** p_stored_key_ptr = (char**)p_element; | 254 char **p_stored_key_ptr = (char**)p_element; |
| 253 char* p_stored_key = *p_stored_key_ptr; | 255 char *p_stored_key = *p_stored_key_ptr; |
| 254 char* p_search_key = (char*)p_key; | 256 char *p_search_key = (char*)p_key; |
| 255 | 257 |
| 256 if (memcmp(p_stored_key, p_search_key, key_size) == 0) | 258 if (memcmp(p_stored_key, p_search_key, key_size) == 0) |
| 257 { | 259 { |
| 258 *p_found = TRUE; | 260 *p_found = TRUE; |
| 259 return p_element; | 261 return p_element; |
| 270 | 272 |
| 271 *p_found = FALSE; | 273 *p_found = FALSE; |
| 272 return NULL; | 274 return NULL; |
| 273 } | 275 } |
| 274 | 276 |
| 275 void* dowa__hashmap_get_ptr(void* p_map, size_t element_size, void* p_key, size_t key_size) | 277 void *dowa__hashmap_get_ptr(void *p_map, size_t element_size, void *p_key, size_t key_size) |
| 276 { | 278 { |
| 277 if (!p_map) | 279 if (!p_map) |
| 278 return NULL; | 280 return NULL; |
| 279 | 281 |
| 280 uint32 hash = dowa__hash_bytes(p_key, key_size); | 282 uint32 hash = dowa__hash_bytes(p_key, key_size); |
| 282 void* p_result = dowa__hashmap_find_slot(p_map, element_size, p_key, key_size, hash, &found); | 284 void* p_result = dowa__hashmap_find_slot(p_map, element_size, p_key, key_size, hash, &found); |
| 283 | 285 |
| 284 return found ? p_result : NULL; | 286 return found ? p_result : NULL; |
| 285 } | 287 } |
| 286 | 288 |
| 287 void* dowa__hashmap_get(void* p_map, size_t element_size, void* p_key, size_t key_size) | 289 void *dowa__hashmap_get(void *p_map, size_t element_size, void *p_key, size_t key_size) |
| 288 { | 290 { |
| 289 void* p_kv = dowa__hashmap_get_ptr(p_map, element_size, p_key, key_size); | 291 void *p_kv = dowa__hashmap_get_ptr(p_map, element_size, p_key, key_size); |
| 290 if (!p_kv) | 292 if (!p_kv) |
| 291 return NULL; | 293 return NULL; |
| 292 | 294 |
| 293 return (char*)p_kv + key_size; | 295 return (char*)p_kv + key_size; |
| 294 } | 296 } |
| 295 | 297 |
| 296 boolean dowa__hashmap_has_key(void* p_map, size_t element_size, void* p_key, size_t key_size) | 298 boolean dowa__hashmap_has_key(void *p_map, size_t element_size, void *p_key, size_t key_size) |
| 297 { | 299 { |
| 298 return dowa__hashmap_get_ptr(p_map, element_size, p_key, key_size) != NULL; | 300 return dowa__hashmap_get_ptr(p_map, element_size, p_key, key_size) != NULL; |
| 299 } | 301 } |
| 300 | 302 |
| 301 static void* dowa__hashmap_rehash(void* p_map, size_t element_size, size_t new_bucket_count, Dowa_Arena* p_arena) | 303 static void* dowa__hashmap_rehash(void *p_map, size_t element_size, size_t new_bucket_count, Dowa_Arena* p_arena) |
| 302 { | 304 { |
| 303 Dowa_Hash_Index* p_old_index = dowa__hashmap_get_index(p_map); | 305 Dowa_Hash_Index* p_old_index = dowa__hashmap_get_index(p_map); |
| 304 if (!p_old_index) | 306 if (!p_old_index) |
| 305 return p_map; | 307 return p_map; |
| 306 | 308 |
| 395 | 397 |
| 396 dowa__header(p_map)->p_hash = p_new_index; | 398 dowa__header(p_map)->p_hash = p_new_index; |
| 397 return p_map; | 399 return p_map; |
| 398 } | 400 } |
| 399 | 401 |
| 400 void* dowa__hashmap_push(void* p_map, size_t element_size, void* p_key, size_t key_size, Dowa_Arena* p_arena) | 402 void *dowa__hashmap_push(void *p_map, size_t element_size, void *p_key, size_t key_size, Dowa_Arena* p_arena) |
| 401 { | 403 { |
| 402 uint32 hash = dowa__hash_bytes(p_key, key_size); | 404 uint32 hash = dowa__hash_bytes(p_key, key_size); |
| 403 | 405 |
| 404 if (p_map) | 406 if (p_map) |
| 405 { | 407 { |
| 539 } | 541 } |
| 540 | 542 |
| 541 return p_map; | 543 return p_map; |
| 542 } | 544 } |
| 543 | 545 |
| 544 void dowa__hashmap_delete(void* p_map, size_t element_size, void* p_key, size_t key_size) | 546 void dowa__hashmap_delete(void *p_map, size_t element_size, void *p_key, size_t key_size) |
| 545 { | 547 { |
| 546 if (!p_map) | 548 if (!p_map) |
| 547 return; | 549 return; |
| 548 | 550 |
| 549 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); | 551 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); |
| 590 probe_step++; | 592 probe_step++; |
| 591 bucket_index = (hash + (probe_step * probe_step)) & bucket_mask; | 593 bucket_index = (hash + (probe_step * probe_step)) & bucket_mask; |
| 592 } | 594 } |
| 593 } | 595 } |
| 594 | 596 |
| 595 void dowa__hashmap_clear(void* p_map, size_t element_size) | 597 void dowa__hashmap_clear(void *p_map, size_t element_size) |
| 596 { | 598 { |
| 597 if (!p_map) | 599 if (!p_map) |
| 598 return; | 600 return; |
| 599 | 601 |
| 600 Dowa_Array_Header* p_header = dowa__header(p_map); | 602 Dowa_Array_Header* p_header = dowa__header(p_map); |
| 614 p_index->item_count = 0; | 616 p_index->item_count = 0; |
| 615 p_index->tombstone_count = 0; | 617 p_index->tombstone_count = 0; |
| 616 } | 618 } |
| 617 } | 619 } |
| 618 | 620 |
| 619 void dowa__hashmap_free(void* p_map) | 621 void dowa__hashmap_free(void *p_map) |
| 620 { | 622 { |
| 621 if (!p_map) | 623 if (!p_map) |
| 622 return; | 624 return; |
| 623 | 625 |
| 624 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); | 626 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); |
| 630 } | 632 } |
| 631 | 633 |
| 632 dowa__array_free(p_map); | 634 dowa__array_free(p_map); |
| 633 } | 635 } |
| 634 | 636 |
| 635 size_t dowa__hashmap_count(void* p_map) | 637 size_t dowa__hashmap_count(void *p_map) |
| 636 { | 638 { |
| 637 if (!p_map) | 639 if (!p_map) |
| 638 return 0; | 640 return 0; |
| 639 | 641 |
| 640 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); | 642 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map); |