static rose_inline void recordAnchoredLiteralMatch(const struct RoseEngine *t, struct hs_scratch *scratch, u32 literal_id, u64a end) { assert(end); struct fatbit **anchoredLiteralRows = getAnchoredLiteralLog(scratch); DEBUG_PRINTF("record %u @ %llu\n", literal_id, end); if (!bf64_set(&scratch->al_log_sum, end - 1)) { // first time, clear row DEBUG_PRINTF("clearing %llu/%u\n", end - 1, t->anchored_count); fatbit_clear(anchoredLiteralRows[end - 1]); } u32 rel_idx = literal_id - t->anchored_base_id; DEBUG_PRINTF("record %u @ %llu index %u/%u\n", literal_id, end, rel_idx, t->anchored_count); assert(rel_idx < t->anchored_count); fatbit_set(anchoredLiteralRows[end - 1], t->anchored_count, rel_idx); }
static really_inline hwlmcb_rv_t flushAnchoredLiteralAtLoc(const struct RoseEngine *t, struct hs_scratch *scratch, u32 curr_loc) { struct RoseContext *tctxt = &scratch->tctxt; struct fatbit *curr_row = getAnchoredLiteralLog(scratch)[curr_loc - 1]; u32 region_width = t->anchored_count; DEBUG_PRINTF("report matches at curr loc\n"); for (u32 it = fatbit_iterate(curr_row, region_width, MMB_INVALID); it != MMB_INVALID; it = fatbit_iterate(curr_row, region_width, it)) { DEBUG_PRINTF("it = %u/%u\n", it, region_width); u32 literal_id = t->anchored_base_id + it; rose_group old_groups = tctxt->groups; DEBUG_PRINTF("ANCH REPLAY MATCH id=%u offset=%u\n", literal_id, curr_loc); hwlmcb_rv_t rv = roseProcessMatch(t, scratch, curr_loc, 0, literal_id); DEBUG_PRINTF("DONE groups=0x%016llx\n", tctxt->groups); /* anchored literals can't safely set groups. * However we may be setting groups that successors already * have worked out that we don't need to match the group */ DEBUG_PRINTF("groups in %016llx out %016llx\n", old_groups, tctxt->groups); tctxt->groups &= old_groups; if (rv == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; } } /* clear row; does not invalidate iteration */ bf64_unset(&scratch->al_log_sum, curr_loc - 1); return HWLM_CONTINUE_MATCHING; }