Replaced GHashTable with HHashTable ... which has some problem causing it to segfault.
This commit is contained in:
parent
bc5e2fa754
commit
b44d00ed33
3 changed files with 45 additions and 44 deletions
|
|
@ -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;
|
||||
|
|
|
|||
34
src/hammer.c
34
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue