summaryrefslogtreecommitdiff
path: root/c_src/permdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'c_src/permdb.c')
-rw-r--r--c_src/permdb.c86
1 files changed, 21 insertions, 65 deletions
diff --git a/c_src/permdb.c b/c_src/permdb.c
index e12ef6b..77a249c 100644
--- a/c_src/permdb.c
+++ b/c_src/permdb.c
@@ -29,7 +29,7 @@ static const int bitsperlevel = 2;
static const int keylen = 32;
struct permdb_object {
- Hashtab *nodecache;
+ struct nodecache *nodecache;
struct nodecache *dirtynodes;
buffered_file *datafile;
buffered_file *indexfile;
@@ -50,47 +50,14 @@ struct nodecache {
UT_hash_handle hh;
};
-static int
-comparenodes(void *a_v, void *b_v)
-{
- struct nodecache *a = (struct nodecache *)a_v;
- struct nodecache *b = (struct nodecache *)b_v;
-
- //fprintf(stderr, "comparing %s and %s\n", a->key, b->key);
-
- return strcmp(a->key, b->key);
-}
-
-static unsigned
-hashnode(void *node_v)
-{
- struct nodecache *node = (struct nodecache *)node_v;
-
- unsigned hash = 0;
-
- for (int i = 0; node->key[i]; i++) {
- unsigned oldhighest = hash >> 30;
- hash <<= 2;
- hash |= oldhighest;
- hash ^= (node->key[i] & 0x3);
- }
-
- //fprintf(stderr, "hashing (%p) %s to %u\n", node, node->key, hash);
- return hash;
-}
-
static node_object
get_node_from_cache(permdb_object *state, const char *key)
{
#if DEBUG_CACHE
fprintf(stderr, "getting cache key %s, ", key);
#endif
- struct nodecache *lookupnode = malloc(sizeof(struct nodecache));
- lookupnode->key = strdup(key);
- //fprintf(stderr, "sending in lookup node %p: ", lookupnode);
- //print_hex(lookupnode, sizeof(struct nodecache) + strlen(key) + 1);
- struct nodecache *node = (struct nodecache *)hashtabsearch(state->nodecache, lookupnode);
- free(lookupnode);
+ struct nodecache *node;
+ HASH_FIND(hh, state->nodecache, key, strlen(key), node);
if (node == NULL) {
#if DEBUG_CACHE
fprintf(stderr, "found nothing in cache\n");
@@ -133,10 +100,17 @@ put_node_in_cache(permdb_object *state, const char *key, node_object value)
fprintf(stderr, "putting cache key %s: ", key);
print_hex(&value, sizeof(node_object));
#endif
- struct nodecache *node = malloc(sizeof(struct nodecache));
- node->key = strdup(key);
+ struct nodecache *node;
+ HASH_FIND(hh, state->nodecache, key, strlen(key), node);
+ if (node) {
+ node->value = value;
+ return;
+ }
+
+ node = malloc(sizeof(struct nodecache));
node->value = value;
- hashtabaddreplace(state->nodecache, node);
+ node->key = strdup(key);
+ HASH_ADD(hh, state->nodecache, key[0], strlen(node->key), node);
}
static void
@@ -159,24 +133,15 @@ put_node_in_dirtynodes(permdb_object *state, const char *key, node_object value)
HASH_ADD(hh, state->dirtynodes, key[0], strlen(node->key), node);
}
-static int
-true_cond(void *ptr, void *arg)
-{
- return TRUE;
-}
-
-static int
-free_hash_node(void *ptr, void *arg)
-{
- free(ptr);
- return 0;
-}
-
void
delete_all_nodes_in_cache(permdb_object *state)
{
- hashtabforeach(state->nodecache, free_hash_node, NULL);
- hashtabcleantab(state->nodecache, true_cond, NULL);
+ struct nodecache *node, *tmp;
+ HASH_ITER(hh, state->nodecache, node, tmp) {
+ HASH_DEL(state->nodecache, node);
+ free(node->key);
+ free(node);
+ }
}
static void
@@ -188,8 +153,6 @@ delete_all_dirty_nodes(permdb_object *state)
free(node->key);
free(node);
}
- //hashtabforeach(state->dirtynodes, free_hash_node, NULL);
- //hashtabcleantab(state->dirtynodes, true_cond, NULL);
}
static const uint64_t index_file_cookie = 0xb7e16b02ba8a6d1b;
@@ -227,12 +190,7 @@ datafile_add_header(buffered_file *file)
void
initial_node(permdb_object *state)
{
- //char *key = "";
put_node_in_dirtynodes(state, "", nullnode);
- //struct nodecache *node = malloc(sizeof(struct nodecache) + strlen(key) + 1);
- //strcpy(node->key, key);
- //node->value = nullnode;
- //hashtabaddreplace(state->dirtynodes, node);
}
int
@@ -450,8 +408,8 @@ permdb_alloc(const char *dbpath)
free(idxpath);
- state->nodecache = hashtabnewf(1000000, comparenodes, hashnode, HASHTAB_GROW);
- state->dirtynodes = NULL;//hashtabnewf(1000000, comparenodes, hashnode, HASHTAB_GROW);
+ state->nodecache = NULL;
+ state->dirtynodes = NULL;
state->error = NULL;
if (bf_total_length(state->datafile) == 0 && bf_total_length(state->indexfile) == 0) {
#if DEBUG_WRITE
@@ -491,8 +449,6 @@ permdb_free(permdb_object *state)
bf_close(state->indexfile);
delete_all_nodes_in_cache(state);
delete_all_dirty_nodes(state);
- //hashtabrelease(state->dirtynodes);
- hashtabrelease(state->nodecache);
free(state);
}