diff options
author | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-04 00:02:56 +0100 |
---|---|---|
committer | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-04 00:02:56 +0100 |
commit | 9034899b3e8158cb35d3d62a64082ce67c72d669 (patch) | |
tree | 44126a758f06f6cb7372138561be6e7c475b03fe /lib/hashtable.c | |
parent | switch compiler to zig (diff) | |
download | c-hashtable-9034899b3e8158cb35d3d62a64082ce67c72d669.tar.gz c-hashtable-9034899b3e8158cb35d3d62a64082ce67c72d669.tar.bz2 c-hashtable-9034899b3e8158cb35d3d62a64082ce67c72d669.zip |
Call c from zig
Diffstat (limited to 'lib/hashtable.c')
-rw-r--r-- | lib/hashtable.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/hashtable.c b/lib/hashtable.c new file mode 100644 index 0000000..00e05d7 --- /dev/null +++ b/lib/hashtable.c @@ -0,0 +1,119 @@ +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "hashtable.h" + +struct { + char* key; + void* data; + int deleted; +} typedef HashTableData; + +struct { + HashTableData* data; + size_t length; +} typedef HashTableBucket; + +struct { + HashTableBucket* buckets; + size_t capacity; +} typedef HashTableImpl; + +static int hash(char* key, size_t bucket_len) { + int sum = 0; + while(*key != '\0') { + sum += *key++; + } + + return sum % bucket_len; +} + +HashTable hashtable_init() { + HashTableImpl* ht = (HashTableImpl*) malloc(sizeof(HashTableImpl)); + + int capacity = 8; + ht->buckets = (HashTableBucket*) calloc(sizeof(HashTableBucket), capacity); + ht->capacity = capacity; + + return (HashTable) ht; +} + +int hashtable_deinit(HashTable* ht) { + HashTableImpl* ht_impl = (HashTableImpl*) *ht; + + for (int i = 0; i < ht_impl->capacity; ++i) { + HashTableBucket bucket = ht_impl->buckets[i]; + free(bucket.data); + } + + free(ht_impl->buckets); + free(ht_impl); + ht = NULL; + return 0; +} + +void* hashtable_get(HashTable ht, char* key) { + HashTableImpl* ht_impl = (HashTableImpl*) ht; + + int index = hash(key, ht_impl->capacity); + + HashTableBucket bucket = ht_impl->buckets[index]; + + for (int i = 0; i < bucket.length; ++i) { + HashTableData data = bucket.data[i]; + if (!data.deleted && strcmp(data.key, key) == 0) return data.data; + } + + return NULL; +} + +int hashtable_put(HashTable ht, char* key, void* val) { + HashTableImpl* ht_impl = (HashTableImpl*) ht; + + int index = hash(key, ht_impl->capacity); + HashTableBucket* bucket = &ht_impl->buckets[index]; + + + //TODO: reuse the deleted? + for (int i = 0; i < bucket->length; ++i) { + HashTableData* data = &bucket->data[i]; + if (strcmp(data->key, key) == 0) { + data->data = val; + data->deleted = 0; + return 0; + } + } + + + //otherwise, realloc + bucket->length++; + bucket->data = realloc(bucket->data, sizeof(HashTableData) * bucket->length); + + HashTableData newData = { + .key = key, + .data = val, + .deleted = 0 + }; + bucket->data[bucket->length - 1] = newData; + + return 0; +} + +int hashtable_remove(HashTable ht, char* key) { + HashTableImpl* ht_impl = (HashTableImpl*) ht; + + int index = hash(key, ht_impl->capacity); + HashTableBucket* bucket = &ht_impl->buckets[index]; + + for (int i = 0; i < bucket->length; ++i) { + HashTableData* data = &bucket->data[i]; + if (strcmp(data->key, key) == 0) { + data->deleted = 1; + return 0; + } + } + + return 0; +} |