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);