begin kvtable
This commit is contained in:
5 files changed
+132
No files matched your search
@@ -0,0 +1 @@
|
||||
bin/*
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef KV_H
|
||||
#define KV_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
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
|
||||
@@ -0,0 +1,88 @@
|
||||
#include <kv.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
#include <kv.h>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user