From b2a3e6dc5cf7c987c1f2ac1349d26ad76fb55d3c Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Sun, 14 Feb 2016 00:24:02 +0100 Subject: Complete conversion to uthash --- c_src/permdb.c | 86 ++++++++++++++-------------------------------------------- 1 file changed, 21 insertions(+), 65 deletions(-) (limited to 'c_src') 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); } -- cgit v1.1