summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-03 13:23:44 +0100
committerBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-03 13:23:44 +0100
commit416d009ffaead754fc13bd6f2093f6c65c17fa95 (patch)
tree0e6471f6477588f6b4cd365f049cb0746c9bcee1 /src
parentInitial commit (diff)
downloadc-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.c96
-rw-r--r--src/hashtable.h6
-rw-r--r--src/main.c34
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);