comparison dowa/d_memory.c @ 71:75de5903355c

Giagantic changes that update Dowa library to be more align with stb style array and hashmap. Updated Seobeo to be caching on server side instead of file level caching. Deleted bunch of things I don't really use.
author June Park <parkjune1995@gmail.com>
date Sun, 28 Dec 2025 20:34:22 -0800
parents ecb6ee6a22c3
children 4532ce6d9eb8
comparison
equal deleted inserted replaced
70:4bc56e88e1f3 71:75de5903355c
21 return p_arena; 21 return p_arena;
22 } 22 }
23 23
24 void *Dowa_Arena_Allocate(Dowa_Arena *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 return Dowa_Arena_Allocate_Aligned(p_arena, size, sizeof(void*) * 2);
27 return NULL;
28
29 if (p_arena->offset + size > p_arena->capacity)
30 {
31 return NULL;
32 }
33 void *currnet_ptr = p_arena->buffer + p_arena->offset;
34 p_arena->offset += size;
35 return currnet_ptr;
36 } 27 }
37 28
38 void Dowa_Arena_Destroy(Dowa_Arena *p_arena) 29 void Dowa_Arena_Destroy(Dowa_Arena *p_arena)
39 { 30 {
40 if (!p_arena) return; 31 if (!p_arena) return;
73 { 64 {
74 if (!p_arena) return 0; 65 if (!p_arena) return 0;
75 return p_arena->capacity - p_arena->offset; 66 return p_arena->capacity - p_arena->offset;
76 } 67 }
77 68
78 // --- HashMap --- // 69 void *Dowa_Arena_Allocate_Aligned(Dowa_Arena *p_arena, size_t size, size_t alignment)
70 {
71 if (!p_arena || !p_arena->buffer || size == 0 || alignment == 0)
72 return NULL;
73
74 size_t current_address = (size_t)(p_arena->buffer + p_arena->offset);
75 size_t aligned_address = (current_address + alignment - 1) & ~(alignment - 1);
76 size_t padding = aligned_address - current_address;
77
78 if (p_arena->offset + padding + size > p_arena->capacity)
79 return NULL;
80
81 p_arena->offset += padding;
82 void *p_result = p_arena->buffer + p_arena->offset;
83 p_arena->offset += size;
84 return p_result;
85 }
86
87 // --- NEW stb_ds-style Array Implementation --- //
88
89 void* dowa__array_grow(void* p_array, size_t element_size, size_t minimum_capacity, Dowa_Arena* p_arena)
90 {
91 Dowa_Array_Header* p_header;
92 size_t new_capacity;
93 size_t current_capacity;
94
95 if (p_array)
96 {
97 p_header = dowa__header(p_array);
98 current_capacity = p_header->capacity;
99
100 if (p_header->allocator_type == DOWA_ALLOCATOR_ARENA && p_header->p_arena != p_arena)
101 {
102 fprintf(stderr, "Error: Cannot mix arena allocators\n");
103 return p_array;
104 }
105 }
106 else
107 {
108 current_capacity = 0;
109 }
110
111 if (current_capacity >= minimum_capacity && p_array != NULL)
112 return p_array;
113
114 new_capacity = current_capacity * 2;
115 if (new_capacity < 4)
116 new_capacity = 4;
117 if (new_capacity < minimum_capacity)
118 new_capacity = minimum_capacity;
119
120 size_t total_size = sizeof(Dowa_Array_Header) + (element_size * new_capacity);
121
122 if (p_arena)
123 {
124 // Array header and data must be properly aligned
125 size_t alignment = element_size >= 16 ? 16 : (element_size >= 8 ? 8 : element_size);
126 Dowa_Array_Header* p_new_header = (Dowa_Array_Header*)Dowa_Arena_Allocate_Aligned(p_arena, total_size, alignment);
127 if (!p_new_header)
128 return p_array;
129
130 void* p_new_array = (char*)p_new_header + sizeof(Dowa_Array_Header);
131
132 if (p_array)
133 {
134 memcpy(p_new_array, p_array, element_size * p_header->length);
135 p_new_header->length = p_header->length;
136 }
137 else
138 {
139 p_new_header->length = 0;
140 }
141
142 p_new_header->capacity = new_capacity;
143 p_new_header->allocator_type = DOWA_ALLOCATOR_ARENA;
144 p_new_header->p_arena = p_arena;
145 p_new_header->p_hash = p_array ? p_header->p_hash : NULL;
146
147 return p_new_array;
148 }
149 else
150 {
151 Dowa_Array_Header* p_new_header;
152
153 if (p_array)
154 {
155 p_header = dowa__header(p_array);
156 p_new_header = (Dowa_Array_Header*)realloc(p_header, total_size);
157 }
158 else
159 {
160 p_new_header = (Dowa_Array_Header*)malloc(total_size);
161 if (p_new_header)
162 p_new_header->length = 0;
163 }
164
165 if (!p_new_header)
166 return p_array;
167
168 p_new_header->capacity = new_capacity;
169 p_new_header->allocator_type = DOWA_ALLOCATOR_MALLOC;
170 p_new_header->p_arena = NULL;
171 p_new_header->p_hash = NULL;
172
173 return (char*)p_new_header + sizeof(Dowa_Array_Header);
174 }
175 }
176
177 void dowa__array_free(void* p_array)
178 {
179 if (!p_array)
180 return;
181
182 Dowa_Array_Header* p_header = dowa__header(p_array);
183
184 if (p_header->allocator_type == DOWA_ALLOCATOR_MALLOC)
185 free(p_header);
186 }
187
188 // --- NEW stb_ds-style HashMap Implementation --- //
189
190 #define DOWA_HASH_EMPTY 0xFFFFFFFF
191 #define DOWA_HASH_TOMBSTONE 0xFFFFFFFE
192
193 uint32 dowa__hash_bytes(void* p_key, size_t key_size)
194 {
195 uint32 hash = HASH_KEY_NUMBER;
196 uint8* p_bytes = (uint8*)p_key;
197
198 for (size_t i = 0; i < key_size; i++)
199 hash = ((hash << 5) + hash) + p_bytes[i];
200
201 if (hash == DOWA_HASH_EMPTY || hash == DOWA_HASH_TOMBSTONE)
202 hash = HASH_KEY_NUMBER;
203
204 return hash;
205 }
206
207 static Dowa_Hash_Index* dowa__hashmap_get_index(void* p_map)
208 {
209 if (!p_map)
210 return NULL;
211
212 Dowa_Array_Header* p_header = dowa__header(p_map);
213 return (Dowa_Hash_Index*)p_header->p_hash;
214 }
215
216 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)
217 {
218 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map);
219 if (!p_index || !p_index->p_buckets)
220 {
221 *p_found = FALSE;
222 return NULL;
223 }
224
225 size_t bucket_mask = p_index->bucket_count - 1;
226 size_t bucket_index = hash & bucket_mask;
227 size_t probe_step = 0;
228
229 while (1)
230 {
231 Dowa_Hash_Bucket* p_bucket = &p_index->p_buckets[bucket_index];
232
233 for (size_t i = 0; i < DOWA_HASH_BUCKET_SIZE; i++)
234 {
235 if (p_bucket->hash[i] == DOWA_HASH_EMPTY)
236 {
237 *p_found = FALSE;
238 return NULL;
239 }
240
241 if (p_bucket->hash[i] == hash && p_bucket->index[i] != DOWA_HASH_TOMBSTONE)
242 {
243 uint32 array_index = p_bucket->index[i];
244 char* p_element = (char*)p_map + (array_index * element_size);
245
246 char** p_stored_key_ptr = (char**)p_element;
247 char* p_stored_key = *p_stored_key_ptr;
248 char* p_search_key = (char*)p_key;
249
250 if (memcmp(p_stored_key, p_search_key, key_size) == 0)
251 {
252 *p_found = TRUE;
253 return p_element;
254 }
255 }
256 }
257
258 probe_step++;
259 bucket_index = (hash + (probe_step * probe_step)) & bucket_mask;
260
261 if (probe_step > p_index->bucket_count)
262 break;
263 }
264
265 *p_found = FALSE;
266 return NULL;
267 }
268
269 void* dowa__hashmap_get_ptr(void* p_map, size_t element_size, void* p_key, size_t key_size)
270 {
271 if (!p_map)
272 return NULL;
273
274 uint32 hash = dowa__hash_bytes(p_key, key_size);
275 boolean found = FALSE;
276 void* p_result = dowa__hashmap_find_slot(p_map, element_size, p_key, key_size, hash, &found);
277
278 return found ? p_result : NULL;
279 }
280
281 void* dowa__hashmap_get(void* p_map, size_t element_size, void* p_key, size_t key_size)
282 {
283 void* p_kv = dowa__hashmap_get_ptr(p_map, element_size, p_key, key_size);
284 if (!p_kv)
285 return NULL;
286
287 return (char*)p_kv + key_size;
288 }
289
290 boolean dowa__hashmap_has_key(void* p_map, size_t element_size, void* p_key, size_t key_size)
291 {
292 return dowa__hashmap_get_ptr(p_map, element_size, p_key, key_size) != NULL;
293 }
294
295 static void* dowa__hashmap_rehash(void* p_map, size_t element_size, size_t new_bucket_count, Dowa_Arena* p_arena)
296 {
297 Dowa_Hash_Index* p_old_index = dowa__hashmap_get_index(p_map);
298 if (!p_old_index)
299 return p_map;
300
301 size_t bucket_alloc_size = sizeof(Dowa_Hash_Bucket) * new_bucket_count;
302 Dowa_Hash_Bucket* p_new_buckets;
303
304 if (p_arena)
305 {
306 p_new_buckets = (Dowa_Hash_Bucket*)Dowa_Arena_Allocate_Aligned(p_arena, bucket_alloc_size, DOWA_HASH_CACHE_LINE_SIZE);
307 }
308 else
309 {
310 if (posix_memalign((void**)&p_new_buckets, DOWA_HASH_CACHE_LINE_SIZE, bucket_alloc_size) != 0)
311 p_new_buckets = NULL;
312 }
313
314 if (!p_new_buckets)
315 return p_map;
316
317 for (size_t i = 0; i < new_bucket_count; i++)
318 {
319 for (size_t j = 0; j < DOWA_HASH_BUCKET_SIZE; j++)
320 {
321 p_new_buckets[i].hash[j] = DOWA_HASH_EMPTY;
322 p_new_buckets[i].index[j] = DOWA_HASH_EMPTY;
323 }
324 }
325
326 Dowa_Hash_Index* p_new_index;
327 if (p_arena)
328 p_new_index = (Dowa_Hash_Index*)Dowa_Arena_Allocate_Aligned(p_arena, sizeof(Dowa_Hash_Index), 16);
329 else
330 p_new_index = (Dowa_Hash_Index*)malloc(sizeof(Dowa_Hash_Index));
331
332 if (!p_new_index)
333 {
334 if (!p_arena)
335 free(p_new_buckets);
336 return p_map;
337 }
338
339 p_new_index->bucket_count = new_bucket_count;
340 p_new_index->item_count = 0;
341 p_new_index->tombstone_count = 0;
342 p_new_index->allocator_type = p_arena ? DOWA_ALLOCATOR_ARENA : DOWA_ALLOCATOR_MALLOC;
343 p_new_index->p_arena = p_arena;
344 p_new_index->p_buckets = p_new_buckets;
345
346 size_t map_length = Dowa_Array_Length(p_map);
347 for (size_t i = 0; i < map_length; i++)
348 {
349 char* p_element = (char*)p_map + (i * element_size);
350 char** p_key_ptr = (char**)p_element;
351 char* p_key_data = *p_key_ptr;
352 uint32 hash = dowa__hash_bytes(p_key_data, strlen(p_key_data) + 1);
353
354 size_t bucket_mask = new_bucket_count - 1;
355 size_t bucket_index = hash & bucket_mask;
356 size_t probe_step = 0;
357 boolean inserted = FALSE;
358
359 while (!inserted && probe_step <= new_bucket_count)
360 {
361 Dowa_Hash_Bucket* p_bucket = &p_new_buckets[bucket_index];
362
363 for (size_t j = 0; j < DOWA_HASH_BUCKET_SIZE; j++)
364 {
365 if (p_bucket->hash[j] == DOWA_HASH_EMPTY)
366 {
367 p_bucket->hash[j] = hash;
368 p_bucket->index[j] = (uint32)i;
369 p_new_index->item_count++;
370 inserted = TRUE;
371 break;
372 }
373 }
374
375 if (!inserted)
376 {
377 probe_step++;
378 bucket_index = (hash + (probe_step * probe_step)) & bucket_mask;
379 }
380 }
381 }
382
383 if (p_old_index->allocator_type == DOWA_ALLOCATOR_MALLOC)
384 {
385 if (p_old_index->p_buckets)
386 free(p_old_index->p_buckets);
387 free(p_old_index);
388 }
389
390 dowa__header(p_map)->p_hash = p_new_index;
391 return p_map;
392 }
393
394 void* dowa__hashmap_push(void* p_map, size_t element_size, void* p_key, size_t key_size, Dowa_Arena* p_arena)
395 {
396 uint32 hash = dowa__hash_bytes(p_key, key_size);
397
398 if (p_map)
399 {
400 boolean found = FALSE;
401 dowa__hashmap_find_slot(p_map, element_size, p_key, key_size, hash, &found);
402 if (found)
403 return p_map;
404 }
405
406 p_map = dowa__array_grow(p_map, element_size, 0, p_arena);
407
408 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map);
409 if (!p_index)
410 {
411 size_t initial_bucket_count = 4;
412 size_t bucket_alloc_size = sizeof(Dowa_Hash_Bucket) * initial_bucket_count;
413 Dowa_Hash_Bucket* p_buckets;
414
415 if (p_arena)
416 {
417 p_buckets = (Dowa_Hash_Bucket*)Dowa_Arena_Allocate_Aligned(p_arena, bucket_alloc_size, DOWA_HASH_CACHE_LINE_SIZE);
418 }
419 else
420 {
421 if (posix_memalign((void**)&p_buckets, DOWA_HASH_CACHE_LINE_SIZE, bucket_alloc_size) != 0)
422 p_buckets = NULL;
423 }
424
425 if (!p_buckets)
426 return p_map;
427
428 for (size_t i = 0; i < initial_bucket_count; i++)
429 {
430 for (size_t j = 0; j < DOWA_HASH_BUCKET_SIZE; j++)
431 {
432 p_buckets[i].hash[j] = DOWA_HASH_EMPTY;
433 p_buckets[i].index[j] = DOWA_HASH_EMPTY;
434 }
435 }
436
437 if (p_arena)
438 p_index = (Dowa_Hash_Index*)Dowa_Arena_Allocate_Aligned(p_arena, sizeof(Dowa_Hash_Index), 16);
439 else
440 p_index = (Dowa_Hash_Index*)malloc(sizeof(Dowa_Hash_Index));
441
442 if (!p_index)
443 {
444 if (!p_arena)
445 free(p_buckets);
446 return p_map;
447 }
448
449 p_index->bucket_count = initial_bucket_count;
450 p_index->item_count = 0;
451 p_index->tombstone_count = 0;
452 p_index->allocator_type = p_arena ? DOWA_ALLOCATOR_ARENA : DOWA_ALLOCATOR_MALLOC;
453 p_index->p_arena = p_arena;
454 p_index->p_buckets = p_buckets;
455
456 dowa__header(p_map)->p_hash = p_index;
457 }
458
459 // Rehash when load factor exceeds ~50% (bucket_count * BUCKET_SIZE * 0.5)
460 // This ensures we rehash before probe chains get too long
461 if (p_index->item_count + p_index->tombstone_count >= p_index->bucket_count * 4)
462 p_map = dowa__hashmap_rehash(p_map, element_size, p_index->bucket_count * 2, p_arena);
463
464 p_index = dowa__hashmap_get_index(p_map);
465
466 Dowa_Array_Header* p_header = dowa__header(p_map);
467 uint32 new_index = (uint32)p_header->length;
468 char* p_new_element = (char*)p_map + (new_index * element_size);
469
470 char* p_key_copy;
471 if (p_arena)
472 p_key_copy = (char*)Dowa_Arena_Allocate(p_arena, key_size);
473 else
474 p_key_copy = (char*)malloc(key_size);
475
476 if (!p_key_copy)
477 return p_map;
478
479 memcpy(p_key_copy, p_key, key_size);
480
481 memcpy(p_new_element, &p_key_copy, sizeof(char*));
482 p_header->length++;
483
484 // Try to insert into hash table - if it fails, rehash and retry
485 boolean inserted = FALSE;
486 for (int attempt = 0; attempt < 2 && !inserted; attempt++)
487 {
488 if (attempt == 1)
489 {
490 // First attempt failed - rehash to make more room
491 p_header->length--; // Undo the array length increment temporarily
492 p_map = dowa__hashmap_rehash(p_map, element_size, p_index->bucket_count * 2, p_arena);
493 p_index = dowa__hashmap_get_index(p_map);
494 p_header = dowa__header(p_map);
495
496 // Restore array state
497 new_index = (uint32)p_header->length;
498 p_new_element = (char*)p_map + (new_index * element_size);
499 memcpy(p_new_element, &p_key_copy, sizeof(char*));
500 p_header->length++;
501 }
502
503 size_t bucket_mask = p_index->bucket_count - 1;
504 size_t bucket_index = hash & bucket_mask;
505 size_t probe_step = 0;
506
507 while (!inserted && probe_step <= p_index->bucket_count)
508 {
509 Dowa_Hash_Bucket* p_bucket = &p_index->p_buckets[bucket_index];
510
511 for (size_t i = 0; i < DOWA_HASH_BUCKET_SIZE; i++)
512 {
513 if (p_bucket->hash[i] == DOWA_HASH_EMPTY || p_bucket->hash[i] == DOWA_HASH_TOMBSTONE)
514 {
515 if (p_bucket->hash[i] == DOWA_HASH_TOMBSTONE)
516 p_index->tombstone_count--;
517
518 p_bucket->hash[i] = hash;
519 p_bucket->index[i] = new_index;
520 p_index->item_count++;
521 inserted = TRUE;
522 break;
523 }
524 }
525
526 if (!inserted)
527 {
528 probe_step++;
529 bucket_index = (hash + (probe_step * probe_step)) & bucket_mask;
530 }
531 }
532 }
533
534 return p_map;
535 }
536
537 void dowa__hashmap_delete(void* p_map, size_t element_size, void* p_key, size_t key_size)
538 {
539 if (!p_map)
540 return;
541
542 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map);
543 if (!p_index || !p_index->p_buckets)
544 return;
545
546 uint32 hash = dowa__hash_bytes(p_key, key_size);
547 size_t bucket_mask = p_index->bucket_count - 1;
548 size_t bucket_index = hash & bucket_mask;
549 size_t probe_step = 0;
550
551 while (probe_step <= p_index->bucket_count)
552 {
553 Dowa_Hash_Bucket* p_bucket = &p_index->p_buckets[bucket_index];
554
555 for (size_t i = 0; i < DOWA_HASH_BUCKET_SIZE; i++)
556 {
557 if (p_bucket->hash[i] == DOWA_HASH_EMPTY)
558 return;
559
560 if (p_bucket->hash[i] == hash && p_bucket->index[i] != DOWA_HASH_TOMBSTONE)
561 {
562 uint32 array_index = p_bucket->index[i];
563 char* p_element = (char*)p_map + (array_index * element_size);
564
565 char** p_stored_key_ptr = (char**)p_element;
566 char* p_stored_key = *p_stored_key_ptr;
567 char* p_search_key = (char*)p_key;
568
569 if (memcmp(p_stored_key, p_search_key, key_size) == 0)
570 {
571 if (dowa__header(p_map)->allocator_type == DOWA_ALLOCATOR_MALLOC)
572 free(p_stored_key);
573
574 p_bucket->hash[i] = DOWA_HASH_TOMBSTONE;
575 p_bucket->index[i] = DOWA_HASH_TOMBSTONE;
576 p_index->item_count--;
577 p_index->tombstone_count++;
578 return;
579 }
580 }
581 }
582
583 probe_step++;
584 bucket_index = (hash + (probe_step * probe_step)) & bucket_mask;
585 }
586 }
587
588 void dowa__hashmap_clear(void* p_map, size_t element_size)
589 {
590 if (!p_map)
591 return;
592
593 Dowa_Array_Header* p_header = dowa__header(p_map);
594 p_header->length = 0;
595
596 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map);
597 if (p_index && p_index->p_buckets)
598 {
599 for (size_t i = 0; i < p_index->bucket_count; i++)
600 {
601 for (size_t j = 0; j < DOWA_HASH_BUCKET_SIZE; j++)
602 {
603 p_index->p_buckets[i].hash[j] = DOWA_HASH_EMPTY;
604 p_index->p_buckets[i].index[j] = DOWA_HASH_EMPTY;
605 }
606 }
607 p_index->item_count = 0;
608 p_index->tombstone_count = 0;
609 }
610 }
611
612 void dowa__hashmap_free(void* p_map)
613 {
614 if (!p_map)
615 return;
616
617 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map);
618 if (p_index && p_index->allocator_type == DOWA_ALLOCATOR_MALLOC)
619 {
620 if (p_index->p_buckets)
621 free(p_index->p_buckets);
622 free(p_index);
623 }
624
625 dowa__array_free(p_map);
626 }
627
628 size_t dowa__hashmap_count(void* p_map)
629 {
630 if (!p_map)
631 return 0;
632
633 Dowa_Hash_Index* p_index = dowa__hashmap_get_index(p_map);
634 return p_index ? p_index->item_count : 0;
635 }
636
637 /*
638 // --- OLD HashMap Implementation (Commented out for migration) --- //
79 Dowa_HashMap *Dowa_HashMap_Create(size_t capacity) 639 Dowa_HashMap *Dowa_HashMap_Create(size_t capacity)
80 { 640 {
81 Dowa_HashMap *p_hash_map; 641 Dowa_HashMap *p_hash_map;
82 p_hash_map = malloc(sizeof(Dowa_HashMap)); 642 p_hash_map = malloc(sizeof(Dowa_HashMap));
83 if (p_hash_map == NULL) 643 if (p_hash_map == NULL)
212 } 772 }
213 prev = entry; 773 prev = entry;
214 entry = entry->next; 774 entry = entry->next;
215 } 775 }
216 776
217 // Overriding doesn't really make sense? when copying over
218 // as we need to free it.
219 //
220 //while (entry)
221 //{
222 // if (strcmp(entry->key, key) == 0)
223 // {
224 // if (!p_hash_map->p_arena && entry->buffer)
225 // Dowa_Free(entry->buffer);
226 // entry->buffer = value;
227 // entry->capacity = value_size;
228 // entry->type = type;
229 // return 0;
230 // }
231 // prev = entry;
232 // entry = entry->next;
233 //}
234
235 // New Key 777 // New Key
236 entry = p_hash_map->p_arena ? 778 entry = p_hash_map->p_arena ?
237 Dowa_Arena_Allocate(p_hash_map->p_arena, sizeof(Dowa_HashEntry)) : 779 Dowa_Arena_Allocate(p_hash_map->p_arena, sizeof(Dowa_HashEntry)) :
238 malloc(sizeof(Dowa_HashEntry)); 780 malloc(sizeof(Dowa_HashEntry));
239 if (!entry) { perror("malloc or arena alloc"); return -1; } 781 if (!entry) { perror("malloc or arena alloc"); return -1; }
240 782
241 entry->key = p_hash_map->p_arena ? 783 entry->key = p_hash_map->p_arena ?
242 Dowa_Arena_Copy(p_hash_map->p_arena, key, strlen(key) + 1 /* \0 */) : 784 Dowa_Arena_Copy(p_hash_map->p_arena, key, strlen(key) + 1) :
243 strdup(key); 785 strdup(key);
244 if (!entry->key) 786 if (!entry->key)
245 { 787 {
246 perror("strdup or arena copy"); 788 perror("strdup or arena copy");
247 if (!p_hash_map->p_arena) Dowa_Free(entry); 789 if (!p_hash_map->p_arena) Dowa_Free(entry);
299 Dowa_Arena_Allocate(p_hash_map->p_arena, sizeof(Dowa_HashEntry)) : 841 Dowa_Arena_Allocate(p_hash_map->p_arena, sizeof(Dowa_HashEntry)) :
300 malloc(sizeof(Dowa_HashEntry)); 842 malloc(sizeof(Dowa_HashEntry));
301 if (!entry) { perror("malloc or arena alloc"); return -1; } 843 if (!entry) { perror("malloc or arena alloc"); return -1; }
302 844
303 entry->key = p_hash_map->p_arena ? 845 entry->key = p_hash_map->p_arena ?
304 Dowa_Arena_Copy(p_hash_map->p_arena, key, strlen(key) + 1 /* \0 */) : 846 Dowa_Arena_Copy(p_hash_map->p_arena, key, strlen(key) + 1) :
305 strdup(key); 847 strdup(key);
306 if (!entry->key) { perror("strdup"); return -1; } 848 if (!entry->key) { perror("strdup"); return -1; }
307 849
308 entry->buffer = p_hash_map->p_arena ? 850 entry->buffer = p_hash_map->p_arena ?
309 Dowa_Arena_Allocate(p_hash_map->p_arena, value_size) : 851 Dowa_Arena_Allocate(p_hash_map->p_arena, value_size) :
472 } 1014 }
473 } 1015 }
474 printf("-----------\n"); 1016 printf("-----------\n");
475 } 1017 }
476 1018
1019 // -- Array --//
1020 Dowa_Array *Dowa_Array_Init()
1021 {
1022 Dowa_Array *dowa_array = malloc(sizeof(Dowa_Array));
1023 if (dowa_array == NULL)
1024 {
1025 return NULL;
1026 }
1027
1028 dowa_array->capacity = DOWA_ARRAY_DEFAULT_CAPACITY;
1029 dowa_array->items = (Dowa_Array_Item *)malloc(sizeof(Dowa_Array_Item) * DOWA_ARRAY_DEFAULT_CAPACITY);
1030 if (dowa_array->items == NULL)
1031 {
1032 return NULL;
1033 }
1034
1035 dowa_array->current_length = 0;
1036 return dowa_array;
1037 }
1038
1039 // void Dowa_Array_Push_Value(Dowa_Array *dowa_array, void *buffer, uint32 length)
1040 // {
1041 // if (dowa_array->current_length == dowa_array->capacity)
1042 // {
1043 // dowa_array->items = realloc(dowa_array->items, sizeof(Dowa_Array_Item) * dowa_array->capacity * 2);
1044 // dowa_array->capacity = dowa_array->capacity * 2;
1045 // }
1046 // Dowa_Array_Item *item = &(dowa_array->items[dowa_array->current_length]);
1047 // item->value = malloc(length);
1048 // if (item->value == NULL)
1049 // {
1050 // // didn't alloc should raise an error.
1051 // return;
1052 // }
1053 // memcpy(item->value, buffer, length);
1054 // item->length = length;
1055 // dowa_array->current_length += 1;
1056 // }
1057
1058
477 #ifdef DIRECTORY 1059 #ifdef DIRECTORY
478 int Dowa_HashMap_Cache_Folder(Dowa_HashMap *p_hash_map, const char *folder_path) 1060 int Dowa_HashMap_Cache_Folder(Dowa_HashMap *p_hash_map, const char *folder_path)
479 { 1061 {
480 if (!p_hash_map || !folder_path) 1062 if (!p_hash_map || !folder_path)
481 return -1; 1063 return -1;
550 } 1132 }
551 closedir(dir); 1133 closedir(dir);
552 return 0; 1134 return 0;
553 } 1135 }
554 #endif 1136 #endif
1137 */