From: Justin Viiret Date: Wed, 20 Apr 2016 05:37:17 +0000 (+1000) Subject: ng_haig: move logic into base class X-Git-Tag: v4.2.0^2~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea7197571a686c35d857d1669ccc2b880e84ddc5;p=thirdparty%2Fvectorscan.git ng_haig: move logic into base class Move all of the Automaton logic into Automaton_Base, which is templated on its StateSet/StateMap types. --- diff --git a/src/nfagraph/ng_haig.cpp b/src/nfagraph/ng_haig.cpp index 4409924b..8fe4889d 100644 --- a/src/nfagraph/ng_haig.cpp +++ b/src/nfagraph/ng_haig.cpp @@ -111,44 +111,28 @@ void populateAccepts(const NGHolder &g, StateSet *accept, StateSet *acceptEod) { } } +template class Automaton_Base { +public: + using StateSet = typename Automaton_Traits::StateSet; + using StateMap = typename Automaton_Traits::StateMap; + protected: Automaton_Base(const NGHolder &graph_in, - const flat_set &unused_in) - : graph(graph_in), unused(unused_in) { + const flat_set &unused_in, som_type som, + const vector> &triggers, + bool unordered_som) + : graph(graph_in), numStates(num_vertices(graph)), unused(unused_in), + init(Automaton_Traits::init_states(numStates)), + initDS(Automaton_Traits::init_states(numStates)), + squash(Automaton_Traits::init_states(numStates)), + accept(Automaton_Traits::init_states(numStates)), + acceptEod(Automaton_Traits::init_states(numStates)), + toppable(Automaton_Traits::init_states(numStates)), + dead(Automaton_Traits::init_states(numStates)) { calculateAlphabet(graph, alpha, unalpha, &alphasize); assert(alphasize <= ALPHABET_SIZE); - } - -public: - static bool canPrune(const flat_set &) { return false; } - - const NGHolder &graph; - const flat_set &unused; - - array alpha; - array unalpha; - u16 alphasize; - - set done_a; - set done_b; - - u16 start_anchored; - u16 start_floating; -}; -class Automaton_Big : public Automaton_Base { -public: - typedef dynamic_bitset<> StateSet; - typedef map StateMap; - - Automaton_Big(const NGHolder &graph_in, - const flat_set &unused_in, som_type som, - const vector> &triggers, bool unordered_som) - : Automaton_Base(graph_in, unused_in), numStates(num_vertices(graph)), - init(numStates), initDS(numStates), squash(numStates), - accept(numStates), acceptEod(numStates), toppable(numStates), - dead(numStates) { populateInit(graph, unused, &init, &initDS, &v_by_index); populateAccepts(graph, &accept, &acceptEod); @@ -161,6 +145,8 @@ public: start_floating = DEAD_STATE; } + cr_by_index = populateCR(graph, v_by_index, alpha); + if (!unordered_som) { for (const auto &sq : findSquashers(graph, som)) { NFAVertex v = sq.first; @@ -170,16 +156,17 @@ public: } } - cr_by_index = populateCR(graph, v_by_index, alpha); if (is_triggered(graph)) { - markToppableStarts(graph, unused, false, triggers, &toppable); + dynamic_bitset<> temp(numStates); + markToppableStarts(graph, unused, false, triggers, &temp); + toppable = Automaton_Traits::copy_states(temp, numStates); } } private: // Convert an NFAStateSet (as used by the squash code) into a StateSet. StateSet shrinkStateSet(const NFAStateSet &in) const { - StateSet out(dead.size()); + StateSet out = Automaton_Traits::init_states(numStates); for (size_t i = in.find_first(); i != in.npos && i < out.size(); i = in.find_next(i)) { out.set(i); @@ -187,20 +174,6 @@ private: return out; } -public: - void transition(const StateSet &in, StateSet *next) { - transition_graph(*this, v_by_index, in, next); - } - - const vector initial() { - vector rv(1, init); - if (start_floating != DEAD_STATE && start_floating != start_anchored) { - rv.push_back(initDS); - } - return rv; - } - -private: void reports_i(const StateSet &in, bool eod, flat_set &rv) { StateSet acc = in & (eod ? acceptEod : accept); for (size_t i = acc.find_first(); i != StateSet::npos; @@ -213,15 +186,42 @@ private: } public: + void transition(const StateSet &in, StateSet *next) { + transition_graph(*this, v_by_index, in, next); + } + + const vector initial() { + vector rv = {init}; + if (start_floating != DEAD_STATE && start_floating != start_anchored) { + rv.push_back(initDS); + } + return rv; + } + void reports(const StateSet &in, flat_set &rv) { reports_i(in, false, rv); } + void reportsEod(const StateSet &in, flat_set &rv) { reports_i(in, true, rv); } -public: - u32 numStates; + static bool canPrune(const flat_set &) { return false; } + + const NGHolder &graph; + const u32 numStates; + const flat_set &unused; + + array alpha; + array unalpha; + u16 alphasize; + + set done_a; + set done_b; + + u16 start_anchored; + u16 start_floating; + vector v_by_index; vector cr_by_index; /* pre alpha'ed */ StateSet init; @@ -235,101 +235,54 @@ public: StateSet dead; }; -class Automaton_Graph : public Automaton_Base { -public: - typedef bitfield StateSet; - typedef ue2::unordered_map StateMap; +struct Big_Traits { + using StateSet = dynamic_bitset<>; + using StateMap = map; - Automaton_Graph(const NGHolder &graph_in, - const flat_set &unused_in, - som_type som, const vector> &triggers, - bool unordered_som) - : Automaton_Base(graph_in, unused_in) { - populateInit(graph, unused, &init, &initDS, &v_by_index); - populateAccepts(graph, &accept, &acceptEod); + static StateSet init_states(u32 num) { + return StateSet(num); + } - start_anchored = DEAD_STATE + 1; - if (initDS == init) { - start_floating = start_anchored; - } else if (initDS.any()) { - start_floating = start_anchored + 1; - } else { - start_floating = DEAD_STATE; - } + static StateSet copy_states(const dynamic_bitset<> &in, UNUSED u32 num) { + assert(in.size() == num); + return in; + } +}; - if (!unordered_som) { - for (const auto &sq : findSquashers(graph, som)) { - NFAVertex v = sq.first; - u32 vert_id = graph[v].index; - squash.set(vert_id); - squash_mask[vert_id] = shrinkStateSet(sq.second); - } - } +class Automaton_Big : public Automaton_Base { +public: + Automaton_Big(const NGHolder &graph_in, + const flat_set &unused_in, som_type som, + const vector> &triggers, bool unordered_som) + : Automaton_Base(graph_in, unused_in, som, triggers, unordered_som) {} +}; - cr_by_index = populateCR(graph, v_by_index, alpha); - if (is_triggered(graph)) { - dynamic_bitset<> temp(NFA_STATE_LIMIT); - markToppableStarts(graph, unused, false, triggers, &temp); - toppable = bitfield(temp); - } +struct Graph_Traits { + using StateSet = bitfield; + using StateMap = ue2::unordered_map; + + static StateSet init_states(UNUSED u32 num) { + assert(num <= NFA_STATE_LIMIT); + return StateSet(); } -private: - // Convert an NFAStateSet (as used by the squash code) into a StateSet. - StateSet shrinkStateSet(const NFAStateSet &in) const { - StateSet out; + static StateSet copy_states(const dynamic_bitset<> &in, u32 num) { + StateSet out = init_states(num); for (size_t i = in.find_first(); i != in.npos && i < out.size(); i = in.find_next(i)) { out.set(i); } return out; } +}; +class Automaton_Graph : public Automaton_Base { public: - void transition(const StateSet &in, StateSet *next) { - transition_graph(*this, v_by_index, in, next); - } - - const vector initial() { - vector rv(1, init); - if (start_floating != DEAD_STATE && start_floating != start_anchored) { - rv.push_back(initDS); - } - return rv; - } - -private: - void reports_i(const StateSet &in, bool eod, flat_set &rv) { - StateSet acc = in & (eod ? acceptEod : accept); - for (size_t i = acc.find_first(); i != StateSet::npos; - i = acc.find_next(i)) { - NFAVertex v = v_by_index[i]; - DEBUG_PRINTF("marking report\n"); - const auto &my_reports = graph[v].reports; - rv.insert(my_reports.begin(), my_reports.end()); - } - } - -public: - void reports(const StateSet &in, flat_set &rv) { - reports_i(in, false, rv); - } - void reportsEod(const StateSet &in, flat_set &rv) { - reports_i(in, true, rv); - } - -public: - vector v_by_index; - vector cr_by_index; /* pre alpha'ed */ - StateSet init; - StateSet initDS; - StateSet squash; /* states which allow us to mask out other states */ - StateSet accept; - StateSet acceptEod; - StateSet toppable; /* states which are allowed to be on when a top arrives, - * triggered dfas only */ - map squash_mask; - StateSet dead; + Automaton_Graph(const NGHolder &graph_in, + const flat_set &unused_in, som_type som, + const vector> &triggers, + bool unordered_som) + : Automaton_Base(graph_in, unused_in, som, triggers, unordered_som) {} }; class Automaton_Haig_Merge {