Merge branch 'fix-cache-hit-skip'

This commit is contained in:
Sven M. Hallberg 2012-06-02 02:52:22 +02:00
commit 12e296fc9a
2 changed files with 25 additions and 16 deletions

View file

@ -34,6 +34,15 @@ static guint djbhash(const uint8_t *buf, size_t len) {
return hash;
}
// short-hand for constructing HCachedResult's
static HCachedResult *cached_result(const HParseState *state, HParseResult *result)
{
HCachedResult *ret = a_new(HCachedResult, 1);
ret->result = result;
ret->input_stream = state->input_stream;
return ret;
}
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);
@ -45,7 +54,7 @@ HParserCacheValue* recall(HParserCacheKey *k, HParseState *state) {
HParseResult *tmp = a_new(HParseResult, 1);
tmp->ast = NULL; tmp->arena = state->arena;
HParserCacheValue *ret = a_new(HParserCacheValue, 1);
ret->value_type = PC_RIGHT; ret->right = tmp;
ret->value_type = PC_RIGHT; ret->right = cached_result(state, tmp);
return ret;
}
if (g_slist_find(head->eval_set, k->parser)) {
@ -58,7 +67,7 @@ HParserCacheValue* recall(HParserCacheKey *k, HParseState *state) {
if (!cached)
cached = a_new(HParserCacheValue, 1);
cached->value_type = PC_RIGHT;
cached->right = tmp_res;
cached->right = cached_result(state, tmp_res);
}
return cached;
}
@ -93,7 +102,7 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head)
HParserCacheValue *old_cached = g_hash_table_lookup(state->cache, k);
if (!old_cached || PC_LEFT == old_cached->value_type)
errx(1, "impossible match");
HParseResult *old_res = old_cached->right;
HParseResult *old_res = old_cached->right->result;
// reset the eval_set of the head of the recursion at each beginning of growth
head->eval_set = head->involved_set;
@ -108,7 +117,7 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head)
if ((old_res->ast->index < tmp_res->ast->index) ||
(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 = tmp_res;
v->value_type = PC_RIGHT; v->right = cached_result(state, tmp_res);
g_hash_table_replace(state->cache, k, v);
return grow(k, state, head);
} else {
@ -116,7 +125,7 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head)
g_hash_table_remove(state->recursion_heads, k);
HParserCacheValue *cached = g_hash_table_lookup(state->cache, k);
if (cached && PC_RIGHT == cached->value_type) {
return cached->right;
return cached->right->result;
} else {
errx(1, "impossible match");
}
@ -136,7 +145,7 @@ HParseResult* lr_answer(HParserCacheKey *k, HParseState *state, HLeftRec *growab
else {
// update cache
HParserCacheValue *v = a_new(HParserCacheValue, 1);
v->value_type = PC_RIGHT; v->right = growable->seed;
v->value_type = PC_RIGHT; v->right = cached_result(state, growable->seed);
g_hash_table_replace(state->cache, k, v);
if (!growable->seed)
return NULL;
@ -194,7 +203,7 @@ HParseResult* h_do_parse(const HParser* parser, HParseState *state) {
// setupLR, used below, mutates the LR to have a head if appropriate, so we check to see if we have one
if (NULL == base->head) {
HParserCacheValue *right = a_new(HParserCacheValue, 1);
right->value_type = PC_RIGHT; right->right = tmp_res;
right->value_type = PC_RIGHT; right->right = cached_result(state, tmp_res);
g_hash_table_replace(state->cache, key, right);
return tmp_res;
} else {
@ -208,14 +217,8 @@ HParseResult* h_do_parse(const HParser* parser, HParseState *state) {
setupLR(parser, state, m->left);
return m->left->seed; // BUG: this might not be correct
} else {
HParseResult *res = m->right;
// skip over the previously-parsed input
long long offs = res->bit_length + state->input_stream.bit_offset;
state->input_stream.index += offs >> 3;
state->input_stream.bit_offset = offs & 7;
return res;
state->input_stream = m->right->input_stream;
return m->right->result;
}
}
}

View file

@ -108,6 +108,12 @@ typedef struct HLeftRec_ {
HRecursionHead *head;
} HLeftRec;
/* Result and remaining input, for rerunning from a cached position. */
typedef struct HCachedResult_ {
HParseResult *result;
HInputStream input_stream;
} HCachedResult;
/* Tagged union for values in the cache: either HLeftRec's (Left) or
* HParseResult's (Right).
*/
@ -115,7 +121,7 @@ typedef struct HParserCacheValue_t {
HParserCacheValueType value_type;
union {
HLeftRec *left;
HParseResult *right;
HCachedResult *right;
};
} HParserCacheValue;