mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-09-29 19:24:25 +03:00
allow some prefixes that may squash the literal match to run eagerly
This commit is contained in:
@@ -979,6 +979,46 @@ char nfaExecCastle0_inAccept(const struct NFA *n, ReportID report,
|
||||
return castleInAccept(c, q, report, q_cur_offset(q));
|
||||
}
|
||||
|
||||
char nfaExecCastle0_inAnyAccept(const struct NFA *n, struct mq *q) {
|
||||
assert(n && q);
|
||||
assert(n->type == CASTLE_NFA_0);
|
||||
DEBUG_PRINTF("entry\n");
|
||||
|
||||
const struct Castle *c = getImplNfa(n);
|
||||
const u64a offset = q_cur_offset(q);
|
||||
DEBUG_PRINTF("offset=%llu\n", offset);
|
||||
|
||||
if (c->exclusive) {
|
||||
u8 *active = (u8 *)q->streamState;
|
||||
u8 *groups = active + c->groupIterOffset;
|
||||
for (u32 i = mmbit_iterate(groups, c->numGroups, MMB_INVALID);
|
||||
i != MMB_INVALID; i = mmbit_iterate(groups, c->numGroups, i)) {
|
||||
u8 *cur = active + i * c->activeIdxSize;
|
||||
const u32 activeIdx = partial_load_u32(cur, c->activeIdxSize);
|
||||
DEBUG_PRINTF("subcastle %u\n", activeIdx);
|
||||
const struct SubCastle *sub = getSubCastle(c, activeIdx);
|
||||
if (subCastleInAccept(c, q, sub->report, offset, activeIdx)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c->exclusive != PURE_EXCLUSIVE) {
|
||||
const u8 *active = (const u8 *)q->streamState + c->activeOffset;
|
||||
for (u32 i = mmbit_iterate(active, c->numRepeats, MMB_INVALID);
|
||||
i != MMB_INVALID; i = mmbit_iterate(active, c->numRepeats, i)) {
|
||||
DEBUG_PRINTF("subcastle %u\n", i);
|
||||
const struct SubCastle *sub = getSubCastle(c, i);
|
||||
if (subCastleInAccept(c, q, sub->report, offset, i)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char nfaExecCastle0_queueInitState(UNUSED const struct NFA *n, struct mq *q) {
|
||||
assert(n && q);
|
||||
assert(n->type == CASTLE_NFA_0);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -44,6 +44,7 @@ char nfaExecCastle0_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecCastle0_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecCastle0_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecCastle0_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecCastle0_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecCastle0_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
|
@@ -1048,6 +1048,14 @@ char nfaExecGough16_inAccept(const struct NFA *n, ReportID report,
|
||||
return nfaExecMcClellan16_inAccept(n, report, q);
|
||||
}
|
||||
|
||||
char nfaExecGough8_inAnyAccept(const struct NFA *n, struct mq *q) {
|
||||
return nfaExecMcClellan8_inAnyAccept(n, q);
|
||||
}
|
||||
|
||||
char nfaExecGough16_inAnyAccept(const struct NFA *n, struct mq *q) {
|
||||
return nfaExecMcClellan16_inAnyAccept(n, q);
|
||||
}
|
||||
|
||||
static
|
||||
char goughCheckEOD(const struct NFA *nfa, u16 s,
|
||||
const struct gough_som_info *som,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -46,6 +46,7 @@ char nfaExecGough8_Q2(const struct NFA *n, struct mq *q, s64a end);
|
||||
char nfaExecGough8_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecGough8_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecGough8_inAccept(const struct NFA *n, ReportID report, struct mq *q);
|
||||
char nfaExecGough8_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecGough8_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecGough8_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -68,6 +69,7 @@ char nfaExecGough16_Q2(const struct NFA *n, struct mq *q, s64a end);
|
||||
char nfaExecGough16_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecGough16_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecGough16_inAccept(const struct NFA *n, ReportID report, struct mq *q);
|
||||
char nfaExecGough16_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecGough16_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecGough16_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -46,6 +46,7 @@ char nfaExecLbrDot_Q2(const struct NFA *n, struct mq *q, s64a end);
|
||||
char nfaExecLbrDot_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecLbrDot_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrDot_inAccept(const struct NFA *n, ReportID report, struct mq *q);
|
||||
char nfaExecLbrDot_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrDot_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrDot_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -66,6 +67,7 @@ char nfaExecLbrVerm_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecLbrVerm_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrVerm_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecLbrVerm_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrVerm_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrVerm_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -86,6 +88,7 @@ char nfaExecLbrNVerm_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecLbrNVerm_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrNVerm_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecLbrNVerm_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrNVerm_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrNVerm_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -106,6 +109,7 @@ char nfaExecLbrShuf_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecLbrShuf_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrShuf_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecLbrShuf_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrShuf_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrShuf_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -126,6 +130,7 @@ char nfaExecLbrTruf_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecLbrTruf_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrTruf_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecLbrTruf_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrTruf_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecLbrTruf_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -94,6 +94,15 @@ char JOIN(ENGINE_EXEC_NAME, _inAccept)(const struct NFA *nfa,
|
||||
return lbrInAccept(l, lstate, q->streamState, offset, report);
|
||||
}
|
||||
|
||||
char JOIN(ENGINE_EXEC_NAME, _inAnyAccept)(const struct NFA *nfa, struct mq *q) {
|
||||
assert(nfa && q);
|
||||
assert(isLbrType(nfa->type));
|
||||
DEBUG_PRINTF("entry\n");
|
||||
|
||||
const struct lbr_common *l = getImplNfa(nfa);
|
||||
return JOIN(ENGINE_EXEC_NAME, _inAccept)(nfa, l->report, q);
|
||||
}
|
||||
|
||||
char JOIN(ENGINE_EXEC_NAME, _queueInitState)(const struct NFA *nfa,
|
||||
struct mq *q) {
|
||||
assert(nfa && q);
|
||||
|
@@ -60,6 +60,7 @@ extern "C"
|
||||
char gf_name##_reportCurrent(const struct NFA *n, struct mq *q); \
|
||||
char gf_name##_inAccept(const struct NFA *n, ReportID report, \
|
||||
struct mq *q); \
|
||||
char gf_name##_inAnyAccept(const struct NFA *n, struct mq *q); \
|
||||
char gf_name##_queueInitState(const struct NFA *n, struct mq *q); \
|
||||
char gf_name##_initCompressedState(const struct NFA *n, u64a offset, \
|
||||
void *state, u8 key); \
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -40,6 +40,7 @@
|
||||
#define TESTEOD_FN JOIN(moNfaTestEod, SIZE)
|
||||
#define TESTEOD_REV_FN JOIN(moNfaRevTestEod, SIZE)
|
||||
#define LIMEX_INACCEPT_FN JOIN(limexInAccept, SIZE)
|
||||
#define LIMEX_INANYACCEPT_FN JOIN(limexInAnyAccept, SIZE)
|
||||
#define EXPIRE_ESTATE_FN JOIN(limexExpireExtendedState, SIZE)
|
||||
#define REPORTCURRENT_FN JOIN(moNfaReportCurrent, SIZE)
|
||||
#define INITIAL_FN JOIN(moNfaInitial, SIZE)
|
||||
@@ -374,11 +375,32 @@ char LIMEX_INACCEPT_FN(const IMPL_NFA_T *limex, STATE_T state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static really_inline
|
||||
char LIMEX_INANYACCEPT_FN(const IMPL_NFA_T *limex, STATE_T state,
|
||||
union RepeatControl *repeat_ctrl, char *repeat_state,
|
||||
u64a offset) {
|
||||
assert(limex);
|
||||
|
||||
const STATE_T acceptMask = LOAD_STATE(&limex->accept);
|
||||
STATE_T accstate = AND_STATE(state, acceptMask);
|
||||
|
||||
// Are we in an accept state?
|
||||
if (ISZERO_STATE(accstate)) {
|
||||
DEBUG_PRINTF("no accept states are on\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SQUASH_UNTUG_BR_FN(limex, repeat_ctrl, repeat_state, offset, &accstate);
|
||||
|
||||
return ISNONZERO_STATE(accstate);
|
||||
}
|
||||
|
||||
#undef TESTEOD_FN
|
||||
#undef TESTEOD_REV_FN
|
||||
#undef REPORTCURRENT_FN
|
||||
#undef EXPIRE_ESTATE_FN
|
||||
#undef LIMEX_INACCEPT_FN
|
||||
#undef LIMEX_INANYACCEPT_FN
|
||||
#undef INITIAL_FN
|
||||
#undef TOP_FN
|
||||
#undef TOPN_FN
|
||||
|
@@ -1008,7 +1008,8 @@ void findMaskedCompressionStates(const build_info &args,
|
||||
// Suffixes and outfixes can mask out leaf states, which should all be
|
||||
// accepts. Right now we can only do this when there is nothing in initDs,
|
||||
// as we switch that on unconditionally in the expand call.
|
||||
if (generates_callbacks(h) && !hasInitDsStates(h, args.state_ids)) {
|
||||
if (!inspects_states_for_accepts(h)
|
||||
&& !hasInitDsStates(h, args.state_ids)) {
|
||||
NFAStateSet nonleaf(args.num_states);
|
||||
for (const auto &e : edges_range(h)) {
|
||||
u32 from = args.state_ids.at(source(e, h));
|
||||
|
@@ -650,7 +650,27 @@ char JOIN(LIMEX_API_ROOT, _Q2)(const struct NFA *n, struct mq *q, s64a end) {
|
||||
ep = MIN(ep, end_abs);
|
||||
assert(ep >= sp);
|
||||
|
||||
assert(sp >= offset); // We no longer do history buffer scans here.
|
||||
if (sp < offset) {
|
||||
DEBUG_PRINTF("HISTORY BUFFER SCAN\n");
|
||||
assert(offset - sp <= q->hlength);
|
||||
u64a local_ep = MIN(offset, ep);
|
||||
u64a final_look = 0;
|
||||
/* we are starting inside the history buffer */
|
||||
if (STREAMFIRST_FN(limex, q->history + q->hlength + sp - offset,
|
||||
local_ep - sp, &ctx, sp,
|
||||
&final_look) == MO_HALT_MATCHING) {
|
||||
DEBUG_PRINTF("final_look:%llu sp:%llu end_abs:%llu "
|
||||
"offset:%llu\n", final_look, sp, end_abs, offset);
|
||||
assert(q->cur);
|
||||
q->cur--;
|
||||
q->items[q->cur].type = MQE_START;
|
||||
q->items[q->cur].location = sp + final_look - offset;
|
||||
STORE_STATE(q->state, LOAD_STATE(&ctx.s));
|
||||
return MO_MATCHES_PENDING;
|
||||
}
|
||||
|
||||
sp = local_ep;
|
||||
}
|
||||
|
||||
if (sp >= ep) {
|
||||
goto scan_done;
|
||||
@@ -868,6 +888,21 @@ char JOIN(LIMEX_API_ROOT, _inAccept)(const struct NFA *nfa,
|
||||
offset, report);
|
||||
}
|
||||
|
||||
char JOIN(LIMEX_API_ROOT, _inAnyAccept)(const struct NFA *nfa, struct mq *q) {
|
||||
assert(nfa && q);
|
||||
assert(q->state && q->streamState);
|
||||
|
||||
const IMPL_NFA_T *limex = getImplNfa(nfa);
|
||||
union RepeatControl *repeat_ctrl =
|
||||
getRepeatControlBase(q->state, sizeof(STATE_T));
|
||||
char *repeat_state = q->streamState + limex->stateSize;
|
||||
STATE_T state = LOAD_STATE(q->state);
|
||||
u64a offset = q->offset + q_last_loc(q) + 1;
|
||||
|
||||
return JOIN(limexInAnyAccept, SIZE)(limex, state, repeat_ctrl, repeat_state,
|
||||
offset);
|
||||
}
|
||||
|
||||
enum nfa_zombie_status JOIN(LIMEX_API_ROOT, _zombie_status)(
|
||||
const struct NFA *nfa,
|
||||
struct mq *q,
|
||||
|
@@ -850,7 +850,7 @@ char nfaExecMcClellan8_reportCurrent(const struct NFA *n, struct mq *q) {
|
||||
}
|
||||
|
||||
char nfaExecMcClellan16_reportCurrent(const struct NFA *n, struct mq *q) {
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
NfaCallback cb = q->cb;
|
||||
void *ctxt = q->context;
|
||||
u16 s = *(u16 *)q->state;
|
||||
@@ -905,7 +905,7 @@ char nfaExecMcClellan8_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q) {
|
||||
assert(n && q);
|
||||
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
u8 s = *(u8 *)q->state;
|
||||
DEBUG_PRINTF("checking accepts for %hhu\n", s);
|
||||
if (s < m->accept_limit_8) {
|
||||
@@ -915,25 +915,45 @@ char nfaExecMcClellan8_inAccept(const struct NFA *n, ReportID report,
|
||||
return mcclellanHasAccept(m, get_aux(m, s), report);
|
||||
}
|
||||
|
||||
char nfaExecMcClellan8_inAnyAccept(const struct NFA *n, struct mq *q) {
|
||||
assert(n && q);
|
||||
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
u8 s = *(u8 *)q->state;
|
||||
DEBUG_PRINTF("checking accepts for %hhu\n", s);
|
||||
assert(s < m->accept_limit_8 || get_aux(m, s)->accept);
|
||||
|
||||
return s >= m->accept_limit_8;
|
||||
}
|
||||
|
||||
char nfaExecMcClellan16_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q) {
|
||||
assert(n && q);
|
||||
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
u16 s = *(u16 *)q->state;
|
||||
DEBUG_PRINTF("checking accepts for %hu\n", s);
|
||||
|
||||
return mcclellanHasAccept(m, get_aux(m, s), report);
|
||||
}
|
||||
|
||||
char nfaExecMcClellan16_inAnyAccept(const struct NFA *n, struct mq *q) {
|
||||
assert(n && q);
|
||||
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
u16 s = *(u16 *)q->state;
|
||||
DEBUG_PRINTF("checking accepts for %hu\n", s);
|
||||
|
||||
return !!get_aux(m, s)->accept;
|
||||
}
|
||||
|
||||
char nfaExecMcClellan8_Q2(const struct NFA *n, struct mq *q, s64a end) {
|
||||
u64a offset = q->offset;
|
||||
const u8 *buffer = q->buffer;
|
||||
NfaCallback cb = q->cb;
|
||||
void *context = q->context;
|
||||
assert(n->type == MCCLELLAN_NFA_8);
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
const u8 *hend = q->history + q->hlength;
|
||||
|
||||
return nfaExecMcClellan8_Q2i(n, offset, buffer, hend, cb, context, q,
|
||||
@@ -947,7 +967,7 @@ char nfaExecMcClellan16_Q2(const struct NFA *n, struct mq *q, s64a end) {
|
||||
NfaCallback cb = q->cb;
|
||||
void *context = q->context;
|
||||
assert(n->type == MCCLELLAN_NFA_16);
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
const u8 *hend = q->history + q->hlength;
|
||||
|
||||
return nfaExecMcClellan16_Q2i(n, offset, buffer, hend, cb, context, q,
|
||||
@@ -961,7 +981,7 @@ char nfaExecMcClellan8_QR(const struct NFA *n, struct mq *q, ReportID report) {
|
||||
NfaCallback cb = q->cb;
|
||||
void *context = q->context;
|
||||
assert(n->type == MCCLELLAN_NFA_8);
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
const u8 *hend = q->history + q->hlength;
|
||||
|
||||
char rv = nfaExecMcClellan8_Q2i(n, offset, buffer, hend, cb, context, q,
|
||||
@@ -980,7 +1000,7 @@ char nfaExecMcClellan16_QR(const struct NFA *n, struct mq *q, ReportID report) {
|
||||
NfaCallback cb = q->cb;
|
||||
void *context = q->context;
|
||||
assert(n->type == MCCLELLAN_NFA_16);
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(n);
|
||||
const struct mcclellan *m = getImplNfa(n);
|
||||
const u8 *hend = q->history + q->hlength;
|
||||
|
||||
char rv = nfaExecMcClellan16_Q2i(n, offset, buffer, hend, cb, context, q,
|
||||
@@ -996,7 +1016,7 @@ char nfaExecMcClellan16_QR(const struct NFA *n, struct mq *q, ReportID report) {
|
||||
|
||||
char nfaExecMcClellan8_initCompressedState(const struct NFA *nfa, u64a offset,
|
||||
void *state, UNUSED u8 key) {
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(nfa);
|
||||
const struct mcclellan *m = getImplNfa(nfa);
|
||||
u8 s = offset ? m->start_floating : m->start_anchored;
|
||||
if (s) {
|
||||
*(u8 *)state = s;
|
||||
@@ -1007,7 +1027,7 @@ char nfaExecMcClellan8_initCompressedState(const struct NFA *nfa, u64a offset,
|
||||
|
||||
char nfaExecMcClellan16_initCompressedState(const struct NFA *nfa, u64a offset,
|
||||
void *state, UNUSED u8 key) {
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(nfa);
|
||||
const struct mcclellan *m = getImplNfa(nfa);
|
||||
u16 s = offset ? m->start_floating : m->start_anchored;
|
||||
if (s) {
|
||||
unaligned_store_u16(state, s);
|
||||
@@ -1019,7 +1039,7 @@ char nfaExecMcClellan16_initCompressedState(const struct NFA *nfa, u64a offset,
|
||||
void nfaExecMcClellan8_SimpStream(const struct NFA *nfa, char *state,
|
||||
const u8 *buf, char top, size_t start_off,
|
||||
size_t len, NfaCallback cb, void *ctxt) {
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(nfa);
|
||||
const struct mcclellan *m = getImplNfa(nfa);
|
||||
|
||||
u8 s = top ? m->start_anchored : *(u8 *)state;
|
||||
|
||||
@@ -1037,7 +1057,7 @@ void nfaExecMcClellan8_SimpStream(const struct NFA *nfa, char *state,
|
||||
void nfaExecMcClellan16_SimpStream(const struct NFA *nfa, char *state,
|
||||
const u8 *buf, char top, size_t start_off,
|
||||
size_t len, NfaCallback cb, void *ctxt) {
|
||||
const struct mcclellan *m = (const struct mcclellan *)getImplNfa(nfa);
|
||||
const struct mcclellan *m = getImplNfa(nfa);
|
||||
|
||||
u16 s = top ? m->start_anchored : unaligned_load_u16(state);
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -47,6 +47,7 @@ char nfaExecMcClellan8_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecMcClellan8_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMcClellan8_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecMcClellan8_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMcClellan8_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMcClellan8_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -70,6 +71,7 @@ char nfaExecMcClellan16_QR(const struct NFA *n, struct mq *q, ReportID report);
|
||||
char nfaExecMcClellan16_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMcClellan16_inAccept(const struct NFA *n, ReportID report,
|
||||
struct mq *q);
|
||||
char nfaExecMcClellan16_inAnyAccept(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMcClellan16_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMcClellan16_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
|
@@ -395,4 +395,36 @@ dstate_id_t get_sds_or_proxy(const raw_dfa &raw) {
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
bool can_die_early(const raw_dfa &raw, dstate_id_t s,
|
||||
map<dstate_id_t, u32> &visited, u32 age_limit) {
|
||||
if (contains(visited, s) && visited[s] >= age_limit) {
|
||||
/* we have already visited (or are in the process of visiting) here with
|
||||
* a looser limit. */
|
||||
return false;
|
||||
}
|
||||
visited[s] = age_limit;
|
||||
|
||||
if (s == DEAD_STATE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (age_limit == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &next : raw.states[s].next) {
|
||||
if (can_die_early(raw, next, visited, age_limit - 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool can_die_early(const raw_dfa &raw, u32 age_limit) {
|
||||
map<dstate_id_t, u32> visited;
|
||||
return can_die_early(raw, raw.start_anchored, visited, age_limit);
|
||||
}
|
||||
|
||||
} // namespace ue2
|
||||
|
@@ -57,6 +57,8 @@ size_t hash_dfa(const raw_dfa &rdfa);
|
||||
|
||||
dstate_id_t get_sds_or_proxy(const raw_dfa &raw);
|
||||
|
||||
bool can_die_early(const raw_dfa &raw, u32 age_limit);
|
||||
|
||||
} // namespace ue2
|
||||
|
||||
#endif
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Intel Corporation
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -36,7 +36,6 @@ struct NFA;
|
||||
|
||||
char nfaExecMpv0_Q(const struct NFA *n, struct mq *q, s64a end);
|
||||
char nfaExecMpv0_reportCurrent(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMpv0_inAccept(const struct NFA *n, ReportID report, struct mq *q);
|
||||
char nfaExecMpv0_queueInitState(const struct NFA *n, struct mq *q);
|
||||
char nfaExecMpv0_initCompressedState(const struct NFA *n, u64a offset,
|
||||
void *state, u8 key);
|
||||
@@ -47,6 +46,7 @@ char nfaExecMpv0_expandState(const struct NFA *nfa, void *dest, const void *src,
|
||||
|
||||
#define nfaExecMpv0_testEOD NFA_API_NO_IMPL
|
||||
#define nfaExecMpv0_inAccept NFA_API_NO_IMPL
|
||||
#define nfaExecMpv0_inAnyAccept NFA_API_NO_IMPL
|
||||
#define nfaExecMpv0_QR NFA_API_NO_IMPL
|
||||
#define nfaExecMpv0_Q2 NFA_API_NO_IMPL /* for non-chained suffixes. */
|
||||
#define nfaExecMpv0_B_Reverse NFA_API_NO_IMPL
|
||||
|
@@ -175,10 +175,16 @@ char nfaReportCurrentMatches(const struct NFA *nfa, struct mq *q);
|
||||
*/
|
||||
char nfaInAcceptState(const struct NFA *nfa, ReportID report, struct mq *q);
|
||||
|
||||
/**
|
||||
* Returns non-zero if the NFA is in any accept state regardless of report
|
||||
* ID.
|
||||
*/
|
||||
char nfaInAnyAcceptState(const struct NFA *nfa, struct mq *q);
|
||||
|
||||
/**
|
||||
* Process the queued commands on the given NFA up to end or the first match.
|
||||
*
|
||||
* Note: This version is meant for rose prefix NFAs:
|
||||
* Note: This version is meant for rose prefix/infix NFAs:
|
||||
* - never uses a callback
|
||||
* - loading of state at a point in history is not special cased
|
||||
*
|
||||
@@ -187,9 +193,9 @@ char nfaInAcceptState(const struct NFA *nfa, ReportID report, struct mq *q);
|
||||
* end with some variant of end. The location field of the events must
|
||||
* be monotonically increasing. If not all the data was processed during
|
||||
* the call, the queue is updated to reflect the remaining work.
|
||||
* @param report we are interested in, if set at the end of the scan returns
|
||||
* @ref MO_MATCHES_PENDING. If no report is desired, MO_INVALID_IDX should
|
||||
* be passed in.
|
||||
* @param report we are interested in. If the given report will be raised at
|
||||
* the end location, the function returns @ref MO_MATCHES_PENDING. If no
|
||||
* match information is desired, MO_INVALID_IDX should be passed in.
|
||||
* @return @ref MO_ALIVE if the nfa is still active with no matches pending,
|
||||
* and @ref MO_MATCHES_PENDING if there are matches pending, 0 if not
|
||||
* alive
|
||||
|
@@ -228,7 +228,6 @@ char nfaQueueExecToMatch(const struct NFA *nfa, struct mq *q, s64a end) {
|
||||
|
||||
assert(q);
|
||||
assert(end >= 0);
|
||||
assert(q->context);
|
||||
assert(q->state);
|
||||
assert(q->cur < q->end);
|
||||
assert(q->end <= MAX_MQE_LEN);
|
||||
@@ -285,6 +284,11 @@ char nfaInAcceptState(const struct NFA *nfa, ReportID report, struct mq *q) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char nfaInAnyAcceptState(const struct NFA *nfa, struct mq *q) {
|
||||
DISPATCH_BY_NFA_TYPE(_inAnyAccept(nfa, q));
|
||||
return 0;
|
||||
}
|
||||
|
||||
char nfaQueueExecRose(const struct NFA *nfa, struct mq *q, ReportID r) {
|
||||
DEBUG_PRINTF("nfa=%p\n", nfa);
|
||||
#ifdef DEBUG
|
||||
|
@@ -47,6 +47,7 @@ enum nfa_kind {
|
||||
NFA_OUTFIX, //!< "outfix" nfa not triggered by external events
|
||||
NFA_OUTFIX_RAW, //!< "outfix", but with unmanaged reports
|
||||
NFA_REV_PREFIX, //! reverse running prefixes (for som)
|
||||
NFA_EAGER_PREFIX, //!< rose prefix that is also run up to matches
|
||||
};
|
||||
|
||||
/** \brief True if this kind of engine is triggered by a top event. */
|
||||
@@ -63,8 +64,10 @@ bool is_triggered(enum nfa_kind k) {
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief True if this kind of engine generates callback events when it
|
||||
* enters accept states.
|
||||
* \brief True if this kind of engine generates actively checks for accept
|
||||
* states either to halt matching or to raise a callback. Only these engines
|
||||
* generated with this property should call nfaQueueExec() or
|
||||
* nfaQueueExecToMatch().
|
||||
*/
|
||||
inline
|
||||
bool generates_callbacks(enum nfa_kind k) {
|
||||
@@ -73,6 +76,24 @@ bool generates_callbacks(enum nfa_kind k) {
|
||||
case NFA_OUTFIX:
|
||||
case NFA_OUTFIX_RAW:
|
||||
case NFA_REV_PREFIX:
|
||||
case NFA_EAGER_PREFIX:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief True if this kind of engine has its state inspected to see if it is in
|
||||
* an accept state. Engines generated with this property will commonly call
|
||||
* nfaQueueExecRose(), nfaInAcceptState(), and nfaInAnyAcceptState().
|
||||
*/
|
||||
inline
|
||||
bool inspects_states_for_accepts(enum nfa_kind k) {
|
||||
switch (k) {
|
||||
case NFA_PREFIX:
|
||||
case NFA_INFIX:
|
||||
case NFA_EAGER_PREFIX:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user