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