#include "collection.h" #include #include #include #include void array_push( void** data, size_t* capacity, size_t* size, void* elem, size_t elem_size) { if (!*capacity) { *capacity = 4; } if (!*data) { *data = malloc(*capacity * elem_size); *size = 0; } if (*size >= *capacity) { *capacity *= 2; *data = realloc(*data, *capacity * elem_size); } memcpy((unsigned char*)*data + *size * elem_size, elem, elem_size); *size += 1; } static void push_kwpair(Hashmap* m, KwPair* pair) { array_push((void**)&m->entries, &m->entries_capacity, &m->entries_size, pair, sizeof(*pair)); } void hashmap_init(Hashmap* m) { *m = (Hashmap) { .entries = nullptr, .entries_capacity = 8, .entries_size = 0, }; } void hashmap_deinit(Hashmap* m) { if (m->entries) { for (size_t i = 0; i < m->entries_size; ++i) { free(m->entries[i].key); } free(m->entries); } } static KwPair* find_entry(Hashmap* m, const char* key) { for (size_t i = 0; i < m->entries_size; ++i) { if (strcmp(m->entries[i].key, key) == 0) { return &m->entries[i]; } } return nullptr; } void hashmap_set(Hashmap* m, const char* key, void* val) { KwPair* existing = find_entry(m, key); if (existing) { existing->val = val; return; } push_kwpair(m, &(KwPair) { strdup(key), val }); } void* hashmap_get(Hashmap* m, const char* key) { KwPair* existing = find_entry(m, key); return existing ? existing->val : nullptr; } void arena_init(Arena* a, size_t bucket_cap) { *a = (Arena) { .buckets = nullptr, .buckets_cap = 0, .buckets_size = 0, .default_bucket_cap = bucket_cap, }; array_push((void**)&a->buckets, &a->buckets_cap, &a->buckets_size, &(ArenaBucket) { .data = malloc(bucket_cap), .cap = bucket_cap, .offset = 0, }, sizeof(ArenaBucket)); } void arena_deinit(Arena* a) { if (a->buckets) { for (size_t i = 0; i < a->buckets_size; ++i) { free(a->buckets[i].data); } free(a->buckets); } } void* arena_alloc(Arena* a, size_t size) { ArenaBucket* b = &a->buckets[a->buckets_size - 1]; if (b->offset + size > b->cap) { size_t buffer_cap = a->default_bucket_cap > size ? a->default_bucket_cap : size; array_push((void**)&a->buckets, &a->buckets_cap, &a->buckets_size, &(ArenaBucket) { .data = malloc(buffer_cap), .cap = buffer_cap, .offset = 0, }, sizeof(ArenaBucket)); b = &a->buckets[a->buckets_size - 1]; } unsigned char* ptr = b->data + b->offset; b->offset += (size + 7ul) & ~7ul; return ptr; }