diff --git a/src/datastructures.c b/src/datastructures.c index 0cd5d0e4ad84c661fae65110ddd4de29d4d99d06..756ba8f03eee48da912fc1684698086117f46ac0 100644 --- a/src/datastructures.c +++ b/src/datastructures.c @@ -3,6 +3,7 @@ #include "allocator.h" #include <assert.h> #include <malloc.h> +#include <string.h> // {{{ counted arrays @@ -97,14 +98,14 @@ void h_slist_free(HSlist *slist) { h_arena_free(slist->arena, slist); } -HHashTable* h_hashtable_new(HArena *arena) { +HHashTable* h_hashtable_new(HArena *arena, HEqualFunc equalFunc, HHashFunc hashFunc) { HHashTable *ht = h_arena_malloc(arena, sizeof(HHashTable*)); ht->hashFunc = hashFunc; ht->equalFunc = equalFunc; ht->capacity = 64; // to start; should be tuned later... ht->used = 0; ht->contents = h_arena_malloc(arena, sizeof(HHashTableEntry) * ht->capacity); - memset(ht->contents, sizeof(HHashTableEntry) * ht->capacity); + memset(ht->contents, 0, sizeof(HHashTableEntry) * ht->capacity); return ht; } @@ -127,14 +128,14 @@ void* h_hashtable_get(HHashTable* ht, void* key) { void h_hashtable_put(HHashTable* ht, void* key, void* value) { // # Start with a rebalancing - h_hashtable_ensure_capacity(ht, ht->used + 1); + //h_hashtable_ensure_capacity(ht, ht->used + 1); HHashValue hashval = ht->hashFunc(key); #ifdef CONSISTENCY_CHECK assert((ht->capacity & (ht->capacity - 1)) == 0); // capacity is a power of 2 #endif - hte = &ht->contents[hashval & (ht->capacity - 1)]; + HHashTableEntry *hte = &ht->contents[hashval & (ht->capacity - 1)]; if (hte->key != NULL) { do { if (hte->hashval == hashval && ht->equalFunc(key, hte->key)) @@ -195,7 +196,7 @@ void h_hashtable_del(HHashTable* ht, void* key) { } } void h_hashtable_free(HHashTable* ht) { - for (i = 0; i < ht->capacity; i++) { + for (size_t i = 0; i < ht->capacity; i++) { HHashTableEntry *hten, *hte = &ht->contents[i]; // FIXME: Free key and value hte = hte->next; diff --git a/src/hammer.c b/src/hammer.c index 0946044b6343a5c428ea946abd2f4cff902023f1..3eab2d722266f8ce52a7e219c3dddb77d19c2d30 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -74,8 +74,8 @@ static inline HParseResult* perform_lowlevel_parse(HParseState *state, const HPa } HParserCacheValue* recall(HParserCacheKey *k, HParseState *state) { - HParserCacheValue *cached = g_hash_table_lookup(state->cache, k); - HRecursionHead *head = g_hash_table_lookup(state->recursion_heads, k); + HParserCacheValue *cached = h_hashtable_get(state->cache, k); + HRecursionHead *head = h_hashtable_get(state->recursion_heads, k); if (!head) { // No heads found return cached; } else { // Some heads found @@ -126,8 +126,8 @@ void setupLR(const HParser *p, HParseState *state, HLeftRec *rec_detect) { HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head) { // Store the head into the recursion_heads - g_hash_table_replace(state->recursion_heads, k, head); - HParserCacheValue *old_cached = g_hash_table_lookup(state->cache, k); + h_hashtable_put(state->recursion_heads, k, head); + HParserCacheValue *old_cached = h_hashtable_get(state->cache, k); if (!old_cached || PC_LEFT == old_cached->value_type) errx(1, "impossible match"); HParseResult *old_res = old_cached->right->result; @@ -141,12 +141,12 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head) (old_res->ast->index == tmp_res->ast->index && old_res->ast->bit_offset < tmp_res->ast->bit_offset)) { HParserCacheValue *v = a_new(HParserCacheValue, 1); v->value_type = PC_RIGHT; v->right = cached_result(state, tmp_res); - g_hash_table_replace(state->cache, k, v); + h_hashtable_put(state->cache, k, v); return grow(k, state, head); } else { // we're done with growing, we can remove data from the recursion head - g_hash_table_remove(state->recursion_heads, k); - HParserCacheValue *cached = g_hash_table_lookup(state->cache, k); + h_hashtable_del(state->recursion_heads, k); + HParserCacheValue *cached = h_hashtable_get(state->cache, k); if (cached && PC_RIGHT == cached->value_type) { return cached->right->result; } else { @@ -154,7 +154,7 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head) } } } else { - g_hash_table_remove(state->recursion_heads, k); + h_hashtable_del(state->recursion_heads, k); return old_res; } } @@ -169,7 +169,7 @@ HParseResult* lr_answer(HParserCacheKey *k, HParseState *state, HLeftRec *growab // update cache HParserCacheValue *v = a_new(HParserCacheValue, 1); v->value_type = PC_RIGHT; v->right = cached_result(state, growable->seed); - g_hash_table_replace(state->cache, k, v); + h_hashtable_put(state->cache, k, v); if (!growable->seed) return NULL; else @@ -194,7 +194,7 @@ HParseResult* h_do_parse(const HParser* parser, HParseState *state) { // cache it HParserCacheValue *dummy = a_new(HParserCacheValue, 1); dummy->value_type = PC_LEFT; dummy->left = base; - g_hash_table_replace(state->cache, key, dummy); + h_hashtable_put(state->cache, key, dummy); // parse the input HParseResult *tmp_res = perform_lowlevel_parse(state, parser); // the base variable has passed equality tests with the cache @@ -203,7 +203,7 @@ HParseResult* h_do_parse(const HParser* parser, HParseState *state) { if (NULL == base->head) { HParserCacheValue *right = a_new(HParserCacheValue, 1); right->value_type = PC_RIGHT; right->right = cached_result(state, tmp_res); - g_hash_table_replace(state->cache, key, right); + h_hashtable_put(state->cache, key, right); return tmp_res; } else { base->seed = tmp_res; @@ -242,8 +242,8 @@ HParseResult* h_parse(const HParser* parser, const uint8_t* input, size_t length // Set up a parse state... HArena * arena = h_new_arena(0); HParseState *parse_state = a_new_(arena, HParseState, 1); - parse_state->cache = g_hash_table_new(cache_key_hash, // hash_func - cache_key_equal);// key_equal_func + parse_state->cache = h_hashtable_new(arena, cache_key_equal, // key_equal_func + cache_key_hash); // hash_func parse_state->input_stream.input = input; parse_state->input_stream.index = 0; parse_state->input_stream.bit_offset = 8; // bit big endian @@ -251,14 +251,14 @@ HParseResult* h_parse(const HParser* parser, const uint8_t* input, size_t length parse_state->input_stream.endianness = BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN; parse_state->input_stream.length = length; parse_state->lr_stack = h_slist_new(arena); - parse_state->recursion_heads = g_hash_table_new(cache_key_hash, - cache_key_equal); + parse_state->recursion_heads = h_hashtable_new(arena, cache_key_equal, + cache_key_hash); parse_state->arena = arena; HParseResult *res = h_do_parse(parser, parse_state); h_slist_free(parse_state->lr_stack); - g_hash_table_destroy(parse_state->recursion_heads); + h_hashtable_free(parse_state->recursion_heads); // tear down the parse state - g_hash_table_destroy(parse_state->cache); + h_hashtable_free(parse_state->cache); if (!res) h_delete_arena(parse_state->arena); diff --git a/src/internal.h b/src/internal.h index 1636c866db78fd08e696effd8a956017acc23cdb..6c68d8ba80194ca2df3efa038800d036273e6d2c 100644 --- a/src/internal.h +++ b/src/internal.h @@ -52,6 +52,25 @@ typedef struct HSlist_ { struct HArena_ *arena; } HSlist; +typedef unsigned int HHashValue; +typedef HHashValue (*HHashFunc)(const void* key); +typedef bool (*HEqualFunc)(const void* key1, const void* key2); + +typedef struct HHashTableEntry_ { + struct HHashTableEntry_ *next; + void* key; + void* value; + HHashValue hashval; +} HHashTableEntry; + +typedef struct HHashTable_ { + HHashTableEntry *contents; + HHashFunc hashFunc; + HEqualFunc equalFunc; + size_t capacity; + size_t used; + HArena *arena; +} HHashTable; /* The state of the parser. * @@ -65,11 +84,11 @@ typedef struct HSlist_ { */ struct HParseState_ { - GHashTable *cache; + HHashTable *cache; HInputStream input_stream; HArena * arena; HSlist *lr_stack; - GHashTable *recursion_heads; + HHashTable *recursion_heads; }; /* The (location, parser) tuple used to key the cache. @@ -172,26 +191,7 @@ bool h_slist_find(HSlist *slist, const void* item); HSlist* h_slist_remove_all(HSlist *slist, const void* item); void h_slist_free(HSlist *slist); -typedef unsigned int HHashValue; -typedef HHashValue (*HHashFunc)(const void* key); -typedef bool (*HEqualFunc)(const void* key1, const void* key2); - -typedef struct HHashTableEntry_ { - struct HHashTableEntry_ *next; - void* key; - void* value; - HHashValue hashval; -} HHashTableEntry; - -typedef struct HHashTable_ { - HHashTableEntry *contents; - HHashFunc hashFunc; - HEqualFunc equalFunc; - int capacity; - int used; -} HHashTable; - -HHashTable* h_hashtable_new(HArena *arena, ); +HHashTable* h_hashtable_new(HArena *arena, HEqualFunc equalFunc, HHashFunc hashFunc); void* h_hashtable_get(HHashTable* ht, void* key); void h_hashtable_put(HHashTable* ht, void* key, void* value); int h_hashtable_present(HHashTable* ht, void* key);