summary refs log tree commit diff
path: root/lib/hashtable.c
diff options
context:
space:
mode:
authorBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-04 00:02:56 +0100
committerBaitinq <manuelpalenzuelamerino@gmail.com>2025-01-04 00:02:56 +0100
commit9034899b3e8158cb35d3d62a64082ce67c72d669 (patch)
tree44126a758f06f6cb7372138561be6e7c475b03fe /lib/hashtable.c
parentswitch compiler to zig (diff)
downloadc-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.c119
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;
+}