hwlmcb_rv_t roseReport(const struct RoseEngine *t, struct hs_scratch *scratch,
u64a end, ReportID onmatch, s32 offset_adjust,
u32 ekey) {
- assert(!t->needsCatchup || end == scratch->tctxt.minMatchOffset);
DEBUG_PRINTF("firing callback onmatch=%u, end=%llu\n", onmatch, end);
updateLastMatchOffset(&scratch->tctxt, end);
}
static rose_inline
-void roseHandleSom(UNUSED const struct RoseEngine *t,
- struct hs_scratch *scratch, const struct som_operation *sr,
+void roseHandleSom(struct hs_scratch *scratch, const struct som_operation *sr,
u64a end) {
DEBUG_PRINTF("end=%llu, minMatchOffset=%llu\n", end,
scratch->tctxt.minMatchOffset);
- assert(!t->needsCatchup || end == scratch->tctxt.minMatchOffset);
updateLastMatchOffset(&scratch->tctxt, end);
handleSomInternal(scratch, sr, end);
}
hwlmcb_rv_t roseReportSom(const struct RoseEngine *t,
struct hs_scratch *scratch, u64a start, u64a end,
ReportID onmatch, s32 offset_adjust, u32 ekey) {
- assert(!t->needsCatchup || end == scratch->tctxt.minMatchOffset);
DEBUG_PRINTF("firing som callback onmatch=%u, start=%llu, end=%llu\n",
onmatch, start, end);
updateLastMatchOffset(&scratch->tctxt, end);
}
static rose_inline
-void roseHandleSomSom(UNUSED const struct RoseEngine *t,
- struct hs_scratch *scratch,
+void roseHandleSomSom(struct hs_scratch *scratch,
const struct som_operation *sr, u64a start, u64a end) {
DEBUG_PRINTF("start=%llu, end=%llu, minMatchOffset=%llu\n", start, end,
scratch->tctxt.minMatchOffset);
- assert(!t->needsCatchup || end == scratch->tctxt.minMatchOffset);
updateLastMatchOffset(&scratch->tctxt, end);
setSomFromSomAware(scratch, sr, start, end);
}
PROGRAM_CASE(REPORT_SOM_INT) {
updateSeqPoint(tctxt, end, from_mpv);
- roseHandleSom(t, scratch, &ri->som, end);
+ roseHandleSom(scratch, &ri->som, end);
work_done = 1;
}
PROGRAM_NEXT_INSTRUCTION
PROGRAM_CASE(REPORT_SOM_AWARE) {
updateSeqPoint(tctxt, end, from_mpv);
- roseHandleSomSom(t, scratch, &ri->som, som, end);
+ roseHandleSomSom(scratch, &ri->som, som, end);
work_done = 1;
}
PROGRAM_NEXT_INSTRUCTION
* RoseEngine. */
RoseEngineBlob engine_blob;
- /** \brief True if reports need CATCH_UP instructions, to catch up anchored
- * matches, suffixes, outfixes etc. */
- bool needs_catchup = false;
+ /** \brief True if reports need CATCH_UP instructions to catch up suffixes,
+ * outfixes etc. */
+ bool needs_catchup;
/** \brief True if this Rose engine has an MPV engine. */
bool needs_mpv_catchup = false;
}
/**
- * \brief True if this Rose engine needs to run a catch up whenever a report is
- * generated.
+ * \brief True if this Rose engine needs to run a catch up whenever a literal
+ * report is generated.
*
* Catch up is necessary if there are output-exposed engines (suffixes,
- * outfixes) or an anchored table (anchored literals, acyclic DFAs).
+ * outfixes).
*/
static
-bool needsCatchup(const RoseBuildImpl &build,
- const vector<raw_dfa> &anchored_dfas) {
+bool needsCatchup(const RoseBuildImpl &build) {
+ /* Note: we could be more selective about when we need to generate catch up
+ * instructions rather than just a boolean yes/no - for instance, if we know
+ * that a role can only match before the point that an outfix/suffix could
+ * match, we do not strictly need a catchup instruction.
+ *
+ * However, this would add a certain amount of complexity to the
+ * catchup logic and would likely have limited applicability - how many
+ * reporting roles have a fixed max offset and how much time is spent on
+ * catchup for these cases?
+ */
+
if (!build.outfixes.empty()) {
+ /* TODO: check that they have non-eod reports */
DEBUG_PRINTF("has outfixes\n");
return true;
}
- if (!anchored_dfas.empty()) {
- DEBUG_PRINTF("has anchored dfas\n");
- return true;
- }
const RoseGraph &g = build.g;
for (auto v : vertices_range(g)) {
- if (build.root == v) {
- continue;
- }
- if (build.anchored_root == v) {
- continue;
- }
if (g[v].suffix) {
+ /* TODO: check that they have non-eod reports */
DEBUG_PRINTF("vertex %zu has suffix\n", g[v].index);
return true;
}
-
}
DEBUG_PRINTF("no need for catch-up on report\n");
RoseProgram makeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
ProgramBuild &prog_build, u32 lit_id,
const vector<RoseEdge> &lit_edges,
- bool is_anchored_program) {
+ bool is_anchored_replay_program) {
const auto &g = build.g;
DEBUG_PRINTF("lit id=%u, %zu lit edges\n", lit_id, lit_edges.size());
makeGroupSquashInstruction(build, lit_id, root_block);
// Literal may be anchored and need to be recorded.
- if (!is_anchored_program) {
+ if (!is_anchored_replay_program) {
makeRecordAnchoredInstruction(build, prog_build, lit_id, root_block);
}
RoseProgram makeLiteralProgram(const RoseBuildImpl &build, build_context &bc,
ProgramBuild &prog_build, u32 lit_id,
const map<u32, vector<RoseEdge>> &lit_edge_map,
- bool is_anchored_program) {
+ bool is_anchored_replay_program) {
const vector<RoseEdge> no_edges;
DEBUG_PRINTF("lit_id=%u\n", lit_id);
}
return makeLiteralProgram(build, bc, prog_build, lit_id, *edges_ptr,
- is_anchored_program);
+ is_anchored_replay_program);
}
/**
u32 floatingMinLiteralMatchOffset
= findMinFloatingLiteralMatch(*this, anchored_dfas);
bc.longLitLengthThreshold = longLitLengthThreshold;
- bc.needs_catchup = needsCatchup(*this, anchored_dfas);
+ bc.needs_catchup = needsCatchup(*this);
recordResources(bc.resources, *this, fragments);
if (!anchored_dfas.empty()) {
bc.resources.has_anchored = true;
proto.somLocationCount = ssm.numSomSlots();
proto.somLocationFatbitSize = fatbit_size(proto.somLocationCount);
- proto.needsCatchup = bc.needs_catchup ? 1 : 0;
-
proto.runtimeImpl = pickRuntimeImpl(*this, bc.resources,
proto.outfixEndQueue);
proto.mpvTriggeredByLeaf = anyEndfixMpvTriggers(*this);