diff options
author | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-03 13:23:44 +0100 |
---|---|---|
committer | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-03 13:23:44 +0100 |
commit | 416d009ffaead754fc13bd6f2093f6c65c17fa95 (patch) | |
tree | 0e6471f6477588f6b4cd365f049cb0746c9bcee1 /src/hashtable.c | |
parent | Initial commit (diff) | |
download | c-hashtable-416d009ffaead754fc13bd6f2093f6c65c17fa95.tar.gz c-hashtable-416d009ffaead754fc13bd6f2093f6c65c17fa95.tar.bz2 c-hashtable-416d009ffaead754fc13bd6f2093f6c65c17fa95.zip |
Kind of works~
Diffstat (limited to 'src/hashtable.c')
-rw-r--r-- | src/hashtable.c | 96 |
1 files changed, 81 insertions, 15 deletions
diff --git a/src/hashtable.c b/src/hashtable.c index 14ab58a..af3f37e 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -1,52 +1,118 @@ #include <stddef.h> #include <stdlib.h> #include <stdio.h> +#include <string.h> #include "hashtable.h" struct { - void** data; - size_t size; + char* key; + void* data; + int deleted; +} typedef HashTableData; + +struct { + HashTableData* data; + size_t length; +} typedef HashTableBucket; + +struct { + HashTableBucket* buckets; + size_t buckets_length; } typedef HashTableImpl; -static int hash(char key) { - return key % 7;//TODO +static int hash(char* key, size_t bucket_len) { + int sum = 0; + while(*key != '\0') { + sum += *key; + *key++; + } + + return sum % bucket_len; } HashTable hashtable_init() { HashTableImpl* ht = (HashTableImpl*) malloc(sizeof(HashTableImpl)); - int len = 8; - ht->data = (void**) malloc(sizeof(void*) * len); - ht->size = len; + int capacity = 8; + ht->buckets = (HashTableBucket*) calloc(sizeof(HashTableBucket), capacity); + ht->buckets_length = capacity; return (HashTable) ht; } int hashtable_deinit(HashTable* ht) { HashTableImpl* ht_impl = (HashTableImpl*) *ht; - free(ht_impl->data); + + for (int i = 0; i < ht_impl->buckets_length; ++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) { +void* hashtable_get(HashTable ht, char* key) { + HashTableImpl* ht_impl = (HashTableImpl*) ht; + + int index = hash(key, ht_impl->buckets_length); + + 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); + int index = hash(key, ht_impl->buckets_length); + HashTableBucket* bucket = &ht_impl->buckets[index]; - void* res = ht_impl->data[index]; + 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; + } + } - return res; + + //otherwise, realloc + bucket->length++; + bucket->data = realloc(bucket->data, bucket->length); + + HashTableData newData; + newData.key = key; + newData.data = val; + newData.deleted = 0; + bucket->data[bucket->length - 1] = newData; + + return 0; } -int hashtable_put(HashTable ht, char key, void* val) { +int hashtable_remove(HashTable ht, char* key) { HashTableImpl* ht_impl = (HashTableImpl*) ht; - int index = hash(key); + int index = hash(key, ht_impl->buckets_length); + HashTableBucket* bucket = &ht_impl->buckets[index]; - ht_impl->data[index] = val; + 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; } |