commit 88948fefefb839a1038e8d06a14220a917be57db Author: SowinskiBraeden Date: Wed Jul 22 11:26:51 2026 -0700 begin kvtable diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..36f971e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin/* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/inc/kv.h b/inc/kv.h new file mode 100644 index 0000000..94cd1bb --- /dev/null +++ b/inc/kv.h @@ -0,0 +1,22 @@ +#ifndef KV_H +#define KV_H + +#include + +typedef struct +{ + char *key; + char *val; +} kv_entry_t; + +typedef struct +{ + size_t capacity; + size_t count; + kv_entry_t *entries; +} kv_t; + +kv_t *kv_init(size_t capacity); +int kv_put(kv_t *db, char *key, char *val); + +#endif diff --git a/src/kv.c b/src/kv.c new file mode 100644 index 0000000..8de4dd7 --- /dev/null +++ b/src/kv.c @@ -0,0 +1,88 @@ +#include +#include +#include + +#define TOMBSTONE 0x1 + +size_t hash(char *val, int capacity) +{ + size_t hash = 0x13371337deadbeef; + + while (*val) + { + hash ^= *val; + hash = hash << 8; + hash += *val; + + val++; + } + + return hash % capacity; +} + +// fn kv_put +// params: +// - db: a pointer to the db +// - key: pointer to the key value +// - val: pointer to the value +// returns: index of the key, or -1 on error, -2 on not found +int kv_put(kv_t *db, char *key, char *val) +{ + if (!db || !key || !val) return -1; + + size_t index = hash(key, db->capacity); + + for (int i = 0; i < db->capacity - 1; ++i) + { + size_t idx = (index + i) % db->capacity; + kv_entry_t *e = &db->entries[idx]; + + if (e->key && + e->key != (void*)TOMBSTONE && + !strcmp(e->key, key)) + { + char *newval = strdup(val); + if (!newval) return -1; + e->val = newval; + return idx; + } + + if (!e->key || e->key == (void*)TOMBSTONE) + { + char *newkey = strdup(key); + char *newval = strdup(val); + if (!newval || !newkey) + { + free(newkey); + free(newval); + return -1; + } + e->key = newkey; + e->val = newval; + db->count++; + return idx; + } + } + + return -2; +} + +kv_t *kv_init(size_t capacity) +{ + if (capacity == 0) return NULL; + + kv_t *table = malloc(sizeof(kv_t)); + if (table == NULL) return NULL; + + table->capacity = capacity; + table->count = 0; + + table->entries = calloc(sizeof(kv_entry_t), capacity); + if (table->entries == NULL) + { + free(table); + return NULL; + } + + return table; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..2204e24 --- /dev/null +++ b/src/main.c @@ -0,0 +1,21 @@ +#include +#include + +int main(void) +{ + kv_t *table = kv_init(1024); + printf("%p\n", table); + printf("%ld\n", table->capacity); + + kv_put(table, "hello", "world"); + kv_put(table, "hello", "people"); + kv_put(table, "goodbye", "world"); + + for (int i = 0; i < table->capacity; ++i) + { + if (table->entries[i].key) + { + printf("[%d] %s: %s\n", i, table->entries[i].key, table->entries[i].val); + } + } +}