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 | |
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')
-rw-r--r-- | src/hashtable.c | 96 | ||||
-rw-r--r-- | src/hashtable.h | 6 | ||||
-rw-r--r-- | src/main.c | 34 |
3 files changed, 108 insertions, 28 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; } diff --git a/src/hashtable.h b/src/hashtable.h index 2a31204..5bdcb08 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -7,8 +7,10 @@ HashTable hashtable_init(); int hashtable_deinit(HashTable*); -int hashtable_put(HashTable, char, void*); +int hashtable_put(HashTable, char*, void*); -void* hashtable_get(HashTable, char); +int hashtable_remove(HashTable, char*); + +void* hashtable_get(HashTable, char*); #endif diff --git a/src/main.c b/src/main.c index d1d84bf..55b2b9e 100644 --- a/src/main.c +++ b/src/main.c @@ -6,21 +6,33 @@ int main(int argc, char** argv) { HashTable ht = hashtable_init(); - char res = hashtable_get(ht, 'a'); + char* res = (char*) hashtable_get(ht, "a"); - printf("Result: %c\n", res); + printf("Result: %s\n", res); - hashtable_put(ht, 'a', 'x'); - - res = hashtable_get(ht, 'a'); + hashtable_put(ht, "aa", (void*)"x"); - printf("Result: %c\n", res); - - hashtable_put(ht, 'h', '1'); - - res = hashtable_get(ht, 'a'); + res = hashtable_get(ht, "aa"); + + printf("Result: %s\n", res); + + hashtable_put(ht, "b", (void*)"1"); + + printf("This should still be x\n"); + + res = hashtable_get(ht, "aa"); + + printf("Result: %s\n", res); - printf("Result: %c\n", res); + res = hashtable_get(ht, "b"); + + printf("Result: %s\n", res); + + hashtable_remove(ht, "b"); + + res = hashtable_get(ht, "b"); + + printf("Result: %s\n", res); hashtable_deinit(&ht); |