diff --git a/src/report.h b/src/report.h index 2fff3b9a..b5d9af03 100644 --- a/src/report.h +++ b/src/report.h @@ -290,7 +290,7 @@ int roseAdaptor_i(u64a offset, ReportID id, struct hs_scratch *scratch, exit: if (halt) { DEBUG_PRINTF("callback requested to terminate matches\n"); - ci->broken = BROKEN_FROM_USER; + ci->status |= STATUS_TERMINATED; return MO_HALT_MATCHING; } @@ -354,7 +354,7 @@ int roseDeliverReport(u64a offset, ReportID id, struct hs_scratch *scratch, to_offset, flags, ci->userContext); if (halt) { DEBUG_PRINTF("callback requested to terminate matches\n"); - ci->broken = BROKEN_FROM_USER; + ci->status |= STATUS_TERMINATED; return MO_HALT_MATCHING; } @@ -455,7 +455,7 @@ int roseSomAdaptor_i(u64a from_offset, u64a to_offset, ReportID id, exit: if (halt) { DEBUG_PRINTF("callback requested to terminate matches\n"); - ci->broken = BROKEN_FROM_USER; + ci->status |= STATUS_TERMINATED; return MO_HALT_MATCHING; } @@ -515,7 +515,7 @@ int roseDeliverSomReport(u64a from_offset, u64a to_offset, ReportID id, if (halt) { DEBUG_PRINTF("callback requested to terminate matches\n"); - ci->broken = BROKEN_FROM_USER; + ci->status |= STATUS_TERMINATED; return MO_HALT_MATCHING; } diff --git a/src/rose/block.c b/src/rose/block.c index 3d4a008d..98dee627 100644 --- a/src/rose/block.c +++ b/src/rose/block.c @@ -258,9 +258,7 @@ void roseBlockExec_i(const struct RoseEngine *t, struct hs_scratch *scratch, } exit:; - u8 dummy_delay_mask = 0; - if (cleanUpDelayed(length, 0, tctxt, &dummy_delay_mask) - == HWLM_TERMINATE_MATCHING) { + if (cleanUpDelayed(length, 0, scratch) == HWLM_TERMINATE_MATCHING) { return; } diff --git a/src/rose/eod.c b/src/rose/eod.c index ade45727..91e59521 100644 --- a/src/rose/eod.c +++ b/src/rose/eod.c @@ -98,8 +98,7 @@ hwlmcb_rv_t roseEodRunMatcher(const struct RoseEngine *t, u64a offset, hwlmExec(etable, eod_data, eod_len, adj, roseCallback, tctxt, tctxt->groups); // We may need to fire delayed matches - u8 dummy_delay_mask = 0; - return cleanUpDelayed(0, offset, tctxt, &dummy_delay_mask); + return cleanUpDelayed(0, offset, scratch); } static rose_inline diff --git a/src/rose/init.c b/src/rose/init.c index 1ec520c3..511eafe4 100644 --- a/src/rose/init.c +++ b/src/rose/init.c @@ -45,10 +45,7 @@ static really_inline void init_rstate(const struct RoseEngine *t, char *state) { // Set runtime state: we take our initial groups from the RoseEngine. DEBUG_PRINTF("setting initial groups to 0x%016llx\n", t->initialGroups); - struct RoseRuntimeState *rstate = getRuntimeState(state); storeGroups(t, state, t->initialGroups); - rstate->flags = 0; - rstate->broken = NOT_BROKEN; } static really_inline diff --git a/src/rose/match.h b/src/rose/match.h index 2b6dfb5d..7d00e2ac 100644 --- a/src/rose/match.h +++ b/src/rose/match.h @@ -237,12 +237,13 @@ hwlmcb_rv_t flushQueuedLiterals(struct RoseContext *tctxt, u64a end) { } static really_inline -hwlmcb_rv_t cleanUpDelayed(size_t length, u64a offset, struct RoseContext *tctxt, - u8 *status) { - if (can_stop_matching(tctxtToScratch(tctxt))) { +hwlmcb_rv_t cleanUpDelayed(size_t length, u64a offset, + struct hs_scratch *scratch) { + if (can_stop_matching(scratch)) { return HWLM_TERMINATE_MATCHING; } + struct RoseContext *tctxt = &scratch->tctxt; if (flushQueuedLiterals(tctxt, length + offset) == HWLM_TERMINATE_MATCHING) { return HWLM_TERMINATE_MATCHING; @@ -250,9 +251,9 @@ hwlmcb_rv_t cleanUpDelayed(size_t length, u64a offset, struct RoseContext *tctxt if (tctxt->filledDelayedSlots) { DEBUG_PRINTF("dirty\n"); - *status |= DELAY_FLOAT_DIRTY; + scratch->core_info.status |= STATUS_DELAY_DIRTY; } else { - *status &= ~DELAY_FLOAT_DIRTY; + scratch->core_info.status &= ~STATUS_DELAY_DIRTY; } tctxt->filledDelayedSlots = 0; diff --git a/src/rose/program_runtime.h b/src/rose/program_runtime.h index 1e1356e1..766b18a8 100644 --- a/src/rose/program_runtime.h +++ b/src/rose/program_runtime.h @@ -211,9 +211,7 @@ hwlmcb_rv_t roseHaltIfExhausted(const struct RoseEngine *t, struct hs_scratch *scratch) { struct core_info *ci = &scratch->core_info; if (isAllExhausted(t, ci->exhaustionVector)) { - if (!ci->broken) { - ci->broken = BROKEN_EXHAUSTED; - } + ci->status |= STATUS_EXHAUSTED; scratch->tctxt.groups = 0; DEBUG_PRINTF("all exhausted, termination requested\n"); return HWLM_TERMINATE_MATCHING; diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index 275f61d0..c067b6a3 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -561,9 +561,9 @@ void fillStateOffsets(const RoseBuildImpl &tbi, u32 rolesWithStateCount, RoseStateOffsets *so) { u32 curr_offset = 0; - // First, runtime state (stores per-stream state, like whether we need a + // First, runtime status (stores per-stream state, like whether we need a // delay rebuild or have been told to halt matching.) - curr_offset += sizeof(RoseRuntimeState); + curr_offset += sizeof(u8); // Role state storage. curr_offset += mmbit_size(rolesWithStateCount); @@ -4433,7 +4433,7 @@ aligned_unique_ptr RoseBuildImpl::buildFinalEngine(u32 minWidth) { &stateOffsets); scatter_plan_raw state_scatter; - buildStateScatterPlan(sizeof(RoseRuntimeState), bc.numStates, + buildStateScatterPlan(sizeof(u8), bc.numStates, activeLeftCount, rosePrefixCount, stateOffsets, cc.streaming, activeArrayCount, outfixBeginQueue, outfixEndQueue, &state_scatter); diff --git a/src/rose/rose_dump.cpp b/src/rose/rose_dump.cpp index adf73726..e803b8c4 100644 --- a/src/rose/rose_dump.cpp +++ b/src/rose/rose_dump.cpp @@ -865,7 +865,6 @@ void roseDumpText(const RoseEngine *t, FILE *f) { t->historyRequired); fprintf(f, " - exhaustion vector : %u bytes\n", (t->ekeyCount + 7) / 8); fprintf(f, " - role state mmbit : %u bytes\n", t->stateSize); - fprintf(f, " - runtime state : %zu bytes\n", sizeof(RoseRuntimeState)); fprintf(f, " - floating matcher : %u bytes\n", t->floatingStreamState); fprintf(f, " - active array : %u bytes\n", mmbit_size(t->activeArrayCount)); diff --git a/src/rose/rose_internal.h b/src/rose/rose_internal.h index 326887da..0d6c96e9 100644 --- a/src/rose/rose_internal.h +++ b/src/rose/rose_internal.h @@ -48,8 +48,6 @@ typedef u64a rose_group; #define MAX_DELAY (DELAY_SLOT_COUNT - 1) #define DELAY_MASK (DELAY_SLOT_COUNT - 1) -#define DELAY_FLOAT_DIRTY (1U << 7) /* delay literal matched in history */ - // Direct report stuff #define LITERAL_DR_FLAG (1U << 31) #define LITERAL_MDR_FLAG ((1U << 30) | (1U << 31)) @@ -214,7 +212,7 @@ struct NfaInfo { * * State not covered by this structure includes: * - * -# the RoseRuntimeState structure + * -# the first byte, containing the status bitmask * -# the role state multibit */ struct RoseStateOffsets { @@ -476,12 +474,6 @@ struct RoseEngine { struct scatter_full_plan state_init; }; -// Rose runtime state -struct RoseRuntimeState { - u8 flags; /* high bit true if delay rebuild needed */ - u8 broken; /* user has requested that we stop matching */ -}; - struct ALIGN_CL_DIRECTIVE anchored_matcher_info { u32 next_offset; /* relative to this, 0 for end */ u32 state_offset; /* relative to anchorState */ diff --git a/src/rose/runtime.h b/src/rose/runtime.h index a8587538..414ad78f 100644 --- a/src/rose/runtime.h +++ b/src/rose/runtime.h @@ -55,14 +55,6 @@ #define rose_inline really_inline -/** \brief Fetch runtime state ptr. */ -static really_inline -struct RoseRuntimeState *getRuntimeState(char *state) { - struct RoseRuntimeState *rs = (struct RoseRuntimeState *)(state); - assert(ISALIGNED_N(rs, 8)); - return rs; -} - static really_inline const void *getByOffset(const struct RoseEngine *t, u32 offset) { assert(offset < t->size); @@ -71,7 +63,7 @@ const void *getByOffset(const struct RoseEngine *t, u32 offset) { static really_inline void *getRoleState(char *state) { - return state + sizeof(struct RoseRuntimeState); + return state + sizeof(u8); // status flags } /** \brief Fetch the active array for suffix nfas. */ diff --git a/src/rose/stream.c b/src/rose/stream.c index 476c4f7c..9b739489 100644 --- a/src/rose/stream.c +++ b/src/rose/stream.c @@ -393,7 +393,7 @@ void roseSaveNfaStreamState(const struct RoseEngine *t, char *state, static rose_inline void ensureStreamNeatAndTidy(const struct RoseEngine *t, char *state, struct hs_scratch *scratch, size_t length, - u64a offset, u8 delay_rb_status) { + u64a offset) { struct RoseContext *tctxt = &scratch->tctxt; if (roseCatchUpTo(t, state, length + scratch->core_info.buf_offset, scratch, @@ -406,8 +406,6 @@ void ensureStreamNeatAndTidy(const struct RoseEngine *t, char *state, roseFlushLastByteHistory(t, state, offset + length, tctxt); tctxt->lastEndOffset = offset + length; storeGroups(t, state, tctxt->groups); - struct RoseRuntimeState *rstate = getRuntimeState(state); - rstate->flags = delay_rb_status; } static really_inline @@ -418,6 +416,8 @@ void do_rebuild(const struct RoseEngine *t, const struct HWLM *ftable, const u8 *buf = scratch->core_info.hbuf + scratch->core_info.hlen - len; DEBUG_PRINTF("BEGIN FLOATING REBUILD over %zu bytes\n", len); + scratch->core_info.status &= ~STATUS_DELAY_DIRTY; + hwlmExec(ftable, buf, len, 0, roseDelayRebuildCallback, scratch, scratch->tctxt.groups); assert(!can_stop_matching(scratch)); @@ -446,7 +446,6 @@ void roseStreamExec(const struct RoseEngine *t, struct hs_scratch *scratch, } char *state = scratch->core_info.state; - struct RoseRuntimeState *rstate = getRuntimeState(state); struct RoseContext *tctxt = &scratch->tctxt; tctxt->mpv_inactive = 0; @@ -475,8 +474,6 @@ void roseStreamExec(const struct RoseEngine *t, struct hs_scratch *scratch, streamInitSufPQ(t, state, scratch); } - u8 delay_rb_status = rstate->flags; - u32 alen = t->anchoredDistance > offset ? MIN(length + offset, t->anchoredDistance) - offset : 0; @@ -507,12 +504,13 @@ void roseStreamExec(const struct RoseEngine *t, struct hs_scratch *scratch, size_t hlength = scratch->core_info.hlen; - char rebuild = hlength && (delay_rb_status & DELAY_FLOAT_DIRTY) - && (t->maxFloatingDelayedMatch == ROSE_BOUND_INF - || offset < t->maxFloatingDelayedMatch); + char rebuild = hlength && + (scratch->core_info.status & STATUS_DELAY_DIRTY) && + (t->maxFloatingDelayedMatch == ROSE_BOUND_INF || + offset < t->maxFloatingDelayedMatch); DEBUG_PRINTF("**rebuild %hhd status %hhu mfdm %u, offset %llu\n", - rebuild, delay_rb_status, t->maxFloatingDelayedMatch, - offset); + rebuild, scratch->core_info.status, + t->maxFloatingDelayedMatch, offset); if (!flen) { if (rebuild) { /* rebuild floating delayed match stuff */ @@ -552,17 +550,16 @@ void roseStreamExec(const struct RoseEngine *t, struct hs_scratch *scratch, flush_delay_and_exit: DEBUG_PRINTF("flushing floating\n"); - if (cleanUpDelayed(length, offset, tctxt, &delay_rb_status) - == HWLM_TERMINATE_MATCHING) { + if (cleanUpDelayed(length, offset, scratch) == HWLM_TERMINATE_MATCHING) { return; } exit: DEBUG_PRINTF("CLEAN UP TIME\n"); if (!can_stop_matching(scratch)) { - ensureStreamNeatAndTidy(t, state, scratch, length, offset, - delay_rb_status); + ensureStreamNeatAndTidy(t, state, scratch, length, offset); } - DEBUG_PRINTF("DONE STREAMING SCAN, dirty = %hhu\n", delay_rb_status); + DEBUG_PRINTF("DONE STREAMING SCAN, status = %u\n", + scratch->core_info.status); return; } diff --git a/src/runtime.c b/src/runtime.c index e38434fd..24ee90f0 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -119,7 +119,8 @@ static really_inline void populateCoreInfo(struct hs_scratch *s, const struct RoseEngine *rose, char *state, match_event_handler onEvent, void *userCtx, const char *data, size_t length, const u8 *history, - size_t hlen, u64a offset, UNUSED unsigned int flags) { + size_t hlen, u64a offset, u8 status, + UNUSED unsigned int flags) { assert(rose); s->core_info.userContext = userCtx; s->core_info.userCallback = onEvent ? onEvent : null_onEvent; @@ -127,7 +128,7 @@ void populateCoreInfo(struct hs_scratch *s, const struct RoseEngine *rose, s->core_info.state = state; /* required for chained queues + evec */ s->core_info.exhaustionVector = state + rose->stateOffsets.exhausted; - s->core_info.broken = NOT_BROKEN; + s->core_info.status = status; s->core_info.buf = (const u8 *)data; s->core_info.len = length; s->core_info.hbuf = history; @@ -140,33 +141,22 @@ void populateCoreInfo(struct hs_scratch *s, const struct RoseEngine *rose, s->deduper.som_log_dirty = 1; /* som logs have not been cleared */ } -/** \brief Query whether this stream is broken. - * - * A broken stream is one on which scanning has stopped, either because the - * user has told us to (via the return value from a match callback) or because - * we have exhausted all reports. - * - * \return NOT_BROKEN, BROKEN_FROM_USER or BROKEN_EXHAUSTED. - */ +#define STATUS_VALID_BITS \ + (STATUS_TERMINATED | STATUS_EXHAUSTED | STATUS_DELAY_DIRTY) + +/** \brief Retrieve status bitmask from stream state. */ static really_inline -u8 getBroken(const char *state) { - const struct RoseRuntimeState *ts = (const void *)state; - assert(ts->broken == NOT_BROKEN || ts->broken == BROKEN_FROM_USER - || ts->broken == BROKEN_EXHAUSTED); - return ts->broken; +u8 getStreamStatus(const char *state) { + u8 status = *(const u8 *)state; + assert((status & ~STATUS_VALID_BITS) == 0); + return status; } -/** \brief Mark this stream with the given broken flag. - * - * Possible values: NOT_BROKEN, BROKEN_FROM_USER, BROKEN_EXHAUSTED. - */ +/** \brief Store status bitmask to stream state. */ static really_inline -void setBroken(char *state, u8 broken) { - DEBUG_PRINTF("set broken=%d\n", broken); - assert(broken == NOT_BROKEN || broken == BROKEN_FROM_USER - || broken == BROKEN_EXHAUSTED); - struct RoseRuntimeState *ts = (void *)state; - ts->broken = broken; +void setStreamStatus(char *state, u8 status) { + assert((status & ~STATUS_VALID_BITS) == 0); + *(u8 *)state = status; } static really_inline @@ -585,7 +575,7 @@ hs_error_t hs_scan(const hs_database_t *db, const char *data, unsigned length, /* populate core info in scratch */ populateCoreInfo(scratch, rose, scratch->bstate, onEvent, userCtx, data, - length, NULL, 0, 0, flags); + length, NULL, 0, 0, 0, flags); clearEvec(scratch->core_info.exhaustionVector, rose); @@ -707,6 +697,7 @@ void init_stream(struct hs_stream *s, const struct RoseEngine *rose) { char *state = getMultiState(s); + setStreamStatus(state, 0); roseInitState(rose, state); clearEvec((char *)state + rose->stateOffsets.exhausted, rose); @@ -754,11 +745,9 @@ hs_error_t hs_open_stream(const hs_database_t *db, UNUSED unsigned flags, static really_inline void rawEodExec(hs_stream_t *id, hs_scratch_t *scratch) { const struct RoseEngine *rose = id->rose; - u8 broken = scratch->core_info.broken; - if (broken) { + if (can_stop_matching(scratch)) { DEBUG_PRINTF("stream already broken\n"); - assert(broken == BROKEN_FROM_USER || broken == BROKEN_EXHAUSTED); return; } @@ -774,11 +763,9 @@ void rawEodExec(hs_stream_t *id, hs_scratch_t *scratch) { static never_inline void soleOutfixEodExec(hs_stream_t *id, hs_scratch_t *scratch) { const struct RoseEngine *t = id->rose; - u8 broken = scratch->core_info.broken; - if (broken) { + if (can_stop_matching(scratch)) { DEBUG_PRINTF("stream already broken\n"); - assert(broken == BROKEN_FROM_USER || broken == BROKEN_EXHAUSTED); return; } @@ -817,15 +804,16 @@ void report_eod_matches(hs_stream_t *id, hs_scratch_t *scratch, const struct RoseEngine *rose = id->rose; char *state = getMultiState(id); + u8 status = getStreamStatus(state); - if (getBroken(state)) { + if (status == STATUS_TERMINATED || status == STATUS_EXHAUSTED) { DEBUG_PRINTF("stream is broken, just freeing storage\n"); return; } populateCoreInfo(scratch, rose, state, onEvent, context, NULL, 0, getHistory(state, rose, id->offset), - getHistoryAmount(rose, id->offset), id->offset, 0); + getHistoryAmount(rose, id->offset), id->offset, status, 0); if (rose->somLocationCount) { loadSomFromStream(scratch, id->offset); @@ -861,8 +849,7 @@ void report_eod_matches(hs_stream_t *id, hs_scratch_t *scratch, int halt = flushStoredSomMatches(scratch, ~0ULL); if (halt) { DEBUG_PRINTF("told to stop matching\n"); - scratch->core_info.broken = BROKEN_FROM_USER; - DEBUG_PRINTF("broken = %hhd\n", scratch->core_info.broken); + scratch->core_info.status |= STATUS_TERMINATED; } } } @@ -931,8 +918,7 @@ static really_inline void rawStreamExec(struct hs_stream *stream_state, struct hs_scratch *scratch) { assert(stream_state); assert(scratch); - - assert(!getBroken(getMultiState(stream_state))); + assert(!can_stop_matching(scratch)); DEBUG_PRINTF("::: streaming rose ::: offset = %llu len = %zu\n", stream_state->offset, scratch->core_info.len); @@ -944,7 +930,7 @@ void rawStreamExec(struct hs_stream *stream_state, struct hs_scratch *scratch) { if (!told_to_stop_matching(scratch) && isAllExhausted(rose, scratch->core_info.exhaustionVector)) { DEBUG_PRINTF("stream exhausted\n"); - scratch->core_info.broken = BROKEN_EXHAUSTED; + scratch->core_info.status = STATUS_EXHAUSTED; } } @@ -953,9 +939,9 @@ void pureLiteralStreamExec(struct hs_stream *stream_state, struct hs_scratch *scratch) { assert(stream_state); assert(scratch); + assert(!can_stop_matching(scratch)); char *state = getMultiState(stream_state); - assert(!getBroken(state)); const struct RoseEngine *rose = stream_state->rose; const struct HWLM *ftable = getFLiteralMatcher(rose); @@ -982,7 +968,7 @@ void pureLiteralStreamExec(struct hs_stream *stream_state, if (!told_to_stop_matching(scratch) && isAllExhausted(rose, scratch->core_info.exhaustionVector)) { DEBUG_PRINTF("stream exhausted\n"); - scratch->core_info.broken = BROKEN_EXHAUSTED; + scratch->core_info.status |= STATUS_EXHAUSTED; } } @@ -991,6 +977,7 @@ void soleOutfixStreamExec(struct hs_stream *stream_state, struct hs_scratch *scratch) { assert(stream_state); assert(scratch); + assert(!can_stop_matching(scratch)); const struct RoseEngine *t = stream_state->rose; assert(t->outfixEndQueue == 1); @@ -1017,7 +1004,7 @@ void soleOutfixStreamExec(struct hs_stream *stream_state, if (nfaQueueExec(q->nfa, q, scratch->core_info.len)) { nfaQueueCompressState(nfa, q, scratch->core_info.len); } else if (!told_to_stop_matching(scratch)) { - scratch->core_info.broken = BROKEN_EXHAUSTED; + scratch->core_info.status |= STATUS_EXHAUSTED; } } @@ -1033,13 +1020,12 @@ hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data, const struct RoseEngine *rose = id->rose; char *state = getMultiState(id); - u8 broken = getBroken(state); - if (broken) { + u8 status = getStreamStatus(state); + if (status & (STATUS_TERMINATED | STATUS_EXHAUSTED)) { DEBUG_PRINTF("stream is broken, halting scan\n"); - if (broken == BROKEN_FROM_USER) { + if (status & STATUS_TERMINATED) { return HS_SCAN_TERMINATED; } else { - assert(broken == BROKEN_EXHAUSTED); return HS_SUCCESS; } } @@ -1049,14 +1035,13 @@ hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data, // cases here. if (unlikely(length == 0)) { DEBUG_PRINTF("zero length block\n"); - assert(getBroken(state) != BROKEN_FROM_USER); return HS_SUCCESS; } u32 historyAmount = getHistoryAmount(rose, id->offset); populateCoreInfo(scratch, rose, state, onEvent, context, data, length, getHistory(state, rose, id->offset), historyAmount, - id->offset, flags); + id->offset, status, flags); assert(scratch->core_info.hlen <= id->offset && scratch->core_info.hlen <= rose->historyRequired); @@ -1069,14 +1054,13 @@ hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data, if (!id->offset && rose->boundary.reportZeroOffset) { DEBUG_PRINTF("zero reports\n"); processReportList(rose, rose->boundary.reportZeroOffset, 0, scratch); - broken = scratch->core_info.broken; - if (unlikely(broken)) { + if (unlikely(can_stop_matching(scratch))) { DEBUG_PRINTF("stream is broken, halting scan\n"); - setBroken(state, broken); - if (broken == BROKEN_FROM_USER) { + setStreamStatus(state, scratch->core_info.status); + if (told_to_stop_matching(scratch)) { return HS_SCAN_TERMINATED; } else { - assert(broken == BROKEN_EXHAUSTED); + assert(scratch->core_info.status & STATUS_EXHAUSTED); return HS_SUCCESS; } } @@ -1098,22 +1082,21 @@ hs_error_t hs_scan_stream_internal(hs_stream_t *id, const char *data, if (rose->hasSom && !told_to_stop_matching(scratch)) { int halt = flushStoredSomMatches(scratch, ~0ULL); if (halt) { - scratch->core_info.broken = BROKEN_FROM_USER; + scratch->core_info.status |= STATUS_TERMINATED; } } + setStreamStatus(state, scratch->core_info.status); + if (likely(!can_stop_matching(scratch))) { - maintainHistoryBuffer(id->rose, getMultiState(id), data, length); + maintainHistoryBuffer(rose, state, data, length); id->offset += length; /* maintain offset */ if (rose->somLocationCount) { storeSomToStream(scratch, id->offset); } } else if (told_to_stop_matching(scratch)) { - setBroken(state, BROKEN_FROM_USER); return HS_SCAN_TERMINATED; - } else { /* exhausted */ - setBroken(state, BROKEN_EXHAUSTED); } return HS_SUCCESS; diff --git a/src/scratch.h b/src/scratch.h index 150db3f2..e082d2f8 100644 --- a/src/scratch.h +++ b/src/scratch.h @@ -70,17 +70,16 @@ struct catchup_pq { u32 qm_size; /**< current size of the priority queue */ }; +/** \brief Status flag: user requested termination. */ +#define STATUS_TERMINATED (1U << 0) -/** \brief Value indicating a stream is active (not broken). */ -#define NOT_BROKEN 0 +/** \brief Status flag: all possible matches on this stream have + * been raised (i.e. all its exhaustion keys are on.) */ +#define STATUS_EXHAUSTED (1U << 1) -/** \brief Value indicating that the user has requested that matching be - * terminated. */ -#define BROKEN_FROM_USER 1 - -/** \brief Value indicating that all possible matches on this stream have been - * raised (i.e. all its exhaustion keys are on.) */ -#define BROKEN_EXHAUSTED 2 +/** \brief Status flag: Rose requires rebuild as delay literal matched in + * history. */ +#define STATUS_DELAY_DIRTY (1U << 2) /** \brief Core information about the current scan, used everywhere. */ struct core_info { @@ -93,12 +92,12 @@ struct core_info { const struct RoseEngine *rose; char *state; /**< full stream state */ char *exhaustionVector; /**< pointer to evec for this stream */ - char broken; /**< user told us to stop, or exhausted */ const u8 *buf; /**< main scan buffer */ size_t len; /**< length of main scan buffer in bytes */ const u8 *hbuf; /**< history buffer */ size_t hlen; /**< length of history buffer in bytes. */ u64a buf_offset; /**< stream offset, for the base of the buffer */ + u8 status; /**< stream status bitmask, using STATUS_ flags above */ }; /** \brief Rose state information. */ @@ -213,12 +212,12 @@ struct fatbit **getDelaySlots(struct hs_scratch *scratch) { static really_inline char told_to_stop_matching(const struct hs_scratch *scratch) { - return scratch->core_info.broken == BROKEN_FROM_USER; + return scratch->core_info.status & STATUS_TERMINATED; } static really_inline char can_stop_matching(const struct hs_scratch *scratch) { - return scratch->core_info.broken != NOT_BROKEN; + return scratch->core_info.status & (STATUS_TERMINATED | STATUS_EXHAUSTED); } #ifdef __cplusplus diff --git a/src/som/som_runtime.c b/src/som/som_runtime.c index 418fcbab..84eeb601 100644 --- a/src/som/som_runtime.c +++ b/src/som/som_runtime.c @@ -487,7 +487,7 @@ int clearSomLog(struct hs_scratch *scratch, u64a offset, struct fatbit *log, int halt = ci->userCallback(onmatch, from_offset, offset, flags, ci->userContext); if (halt) { - ci->broken = BROKEN_FROM_USER; + ci->status |= STATUS_TERMINATED; return 1; } }