diff --git a/src/report.h b/src/report.h index d037d11b..4a5f401e 100644 --- a/src/report.h +++ b/src/report.h @@ -115,6 +115,42 @@ enum DedupeResult dedupeCatchup(const struct RoseEngine *rose, return DEDUPE_CONTINUE; } +/** \brief Test whether the given key (\a ekey) is set in the exhaustion vector + * \a evec. */ +static really_inline +int isExhausted(const struct RoseEngine *rose, const char *evec, u32 ekey) { + DEBUG_PRINTF("checking exhaustion %p %u\n", evec, ekey); + assert(ekey != INVALID_EKEY); + assert(ekey < rose->ekeyCount); + return mmbit_isset((const u8 *)evec, rose->ekeyCount, ekey); +} + +/** \brief Returns 1 if all exhaustion keys in the bitvector are on. */ +static really_inline +int isAllExhausted(const struct RoseEngine *rose, const char *evec) { + if (!rose->canExhaust) { + return 0; /* pattern set is inexhaustible */ + } + + return mmbit_all((const u8 *)evec, rose->ekeyCount); +} + +/** \brief Mark key \a ekey on in the exhaustion vector. */ +static really_inline +void markAsMatched(const struct RoseEngine *rose, char *evec, u32 ekey) { + DEBUG_PRINTF("marking as exhausted key %u\n", ekey); + assert(ekey != INVALID_EKEY); + assert(ekey < rose->ekeyCount); + mmbit_set((u8 *)evec, rose->ekeyCount, ekey); +} + +/** \brief Clear all keys in the exhaustion vector. */ +static really_inline +void clearEvec(const struct RoseEngine *rose, char *evec) { + DEBUG_PRINTF("clearing evec %p %u\n", evec, rose->ekeyCount); + mmbit_clear((u8 *)evec, rose->ekeyCount); +} + /** * \brief Deliver the given report to the user callback. * diff --git a/src/rose/catchup.c b/src/rose/catchup.c index dba9629e..2460f086 100644 --- a/src/rose/catchup.c +++ b/src/rose/catchup.c @@ -59,6 +59,39 @@ int roseNfaRunProgram(const struct RoseEngine *rose, struct hs_scratch *scratch, return can_stop_matching(scratch) ? MO_HALT_MATCHING : MO_CONTINUE_MATCHING; } +static rose_inline +char roseSuffixInfoIsExhausted(const struct RoseEngine *rose, + const struct NfaInfo *info, + const char *exhausted) { + if (!info->ekeyListOffset) { + return 0; + } + + DEBUG_PRINTF("check exhaustion -> start at %u\n", info->ekeyListOffset); + + /* INVALID_EKEY terminated list */ + const u32 *ekeys = getByOffset(rose, info->ekeyListOffset); + while (*ekeys != INVALID_EKEY) { + DEBUG_PRINTF("check %u\n", *ekeys); + if (!isExhausted(rose, exhausted, *ekeys)) { + DEBUG_PRINTF("not exhausted -> alive\n"); + return 0; + } + ++ekeys; + } + + DEBUG_PRINTF("all ekeys exhausted -> dead\n"); + return 1; +} + +static really_inline +char roseSuffixIsExhausted(const struct RoseEngine *rose, u32 qi, + const char *exhausted) { + DEBUG_PRINTF("check queue %u\n", qi); + const struct NfaInfo *info = getNfaInfoByQueue(rose, qi); + return roseSuffixInfoIsExhausted(rose, info, exhausted); +} + static really_inline void deactivateQueue(const struct RoseEngine *t, u8 *aa, u32 qi, struct hs_scratch *scratch) { diff --git a/src/rose/runtime.h b/src/rose/runtime.h index d4309bfb..f7f6641d 100644 --- a/src/rose/runtime.h +++ b/src/rose/runtime.h @@ -35,7 +35,6 @@ #include "rose_internal.h" #include "scratch.h" -#include "util/exhaust.h" // for isExhausted #include "util/partial_store.h" /* @@ -108,39 +107,6 @@ const u8 *getLeftfixLagTableConst(const struct RoseEngine *t, return (const u8 *)(state + t->stateOffsets.leftfixLagTable); } -static rose_inline -char roseSuffixInfoIsExhausted(const struct RoseEngine *t, - const struct NfaInfo *info, - const char *exhausted) { - if (!info->ekeyListOffset) { - return 0; - } - - DEBUG_PRINTF("check exhaustion -> start at %u\n", info->ekeyListOffset); - - /* INVALID_EKEY terminated list */ - const u32 *ekeys = (const u32 *)((const char *)t + info->ekeyListOffset); - while (*ekeys != INVALID_EKEY) { - DEBUG_PRINTF("check %u\n", *ekeys); - if (!isExhausted(t, exhausted, *ekeys)) { - DEBUG_PRINTF("not exhausted -> alive\n"); - return 0; - } - ++ekeys; - } - - DEBUG_PRINTF("all ekeys exhausted -> dead\n"); - return 1; -} - -static really_inline -char roseSuffixIsExhausted(const struct RoseEngine *t, u32 qi, - const char *exhausted) { - DEBUG_PRINTF("check queue %u\n", qi); - const struct NfaInfo *info = getNfaInfoByQueue(t, qi); - return roseSuffixInfoIsExhausted(t, info, exhausted); -} - static really_inline u32 has_chained_nfas(const struct RoseEngine *t) { return t->outfixBeginQueue; diff --git a/src/util/exhaust.h b/src/util/exhaust.h index b55c52d7..d6f2ac06 100644 --- a/src/util/exhaust.h +++ b/src/util/exhaust.h @@ -33,47 +33,9 @@ #ifndef EXHAUST_H #define EXHAUST_H -#include "rose/rose_internal.h" -#include "util/multibit.h" #include "ue2common.h" /** Index meaning a given exhaustion key is invalid. */ #define INVALID_EKEY (~(u32)0) -/** \brief Test whether the given key (\a ekey) is set in the exhaustion vector - * \a evec. */ -static really_inline -int isExhausted(const struct RoseEngine *t, const char *evec, u32 ekey) { - DEBUG_PRINTF("checking exhaustion %p %u\n", evec, ekey); - assert(ekey != INVALID_EKEY); - assert(ekey < t->ekeyCount); - return mmbit_isset((const u8 *)evec, t->ekeyCount, ekey); -} - -/** \brief Returns 1 if all exhaustion keys in the bitvector are on. */ -static really_inline -int isAllExhausted(const struct RoseEngine *t, const char *evec) { - if (!t->canExhaust) { - return 0; /* pattern set is inexhaustible */ - } - - return mmbit_all((const u8 *)evec, t->ekeyCount); -} - -/** \brief Mark key \a ekey on in the exhaustion vector. */ -static really_inline -void markAsMatched(const struct RoseEngine *t, char *evec, u32 ekey) { - DEBUG_PRINTF("marking as exhausted key %u\n", ekey); - assert(ekey != INVALID_EKEY); - assert(ekey < t->ekeyCount); - mmbit_set((u8 *)evec, t->ekeyCount, ekey); -} - -/** \brief Clear all keys in the exhaustion vector. */ -static really_inline -void clearEvec(const struct RoseEngine *t, char *evec) { - DEBUG_PRINTF("clearing evec %p %u\n", evec, t->ekeyCount); - mmbit_clear((u8 *)evec, t->ekeyCount); -} - #endif