diff options
author | Ivan Blinkov <ivan@blinkov.ru> | 2022-02-10 16:47:10 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:10 +0300 |
commit | 1aeb9a455974457866f78722ad98114bafc84e8a (patch) | |
tree | e4340eaf1668684d83a0a58c36947c5def5350ad /contrib/libs/hyperscan/src/rose/rose_build_add.cpp | |
parent | bd5ef432f5cfb1e18851381329d94665a4c22470 (diff) | |
download | ydb-1aeb9a455974457866f78722ad98114bafc84e8a.tar.gz |
Restoring authorship annotation for Ivan Blinkov <ivan@blinkov.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/hyperscan/src/rose/rose_build_add.cpp')
-rw-r--r-- | contrib/libs/hyperscan/src/rose/rose_build_add.cpp | 542 |
1 files changed, 271 insertions, 271 deletions
diff --git a/contrib/libs/hyperscan/src/rose/rose_build_add.cpp b/contrib/libs/hyperscan/src/rose/rose_build_add.cpp index 4929c95fce..b3fe94b597 100644 --- a/contrib/libs/hyperscan/src/rose/rose_build_add.cpp +++ b/contrib/libs/hyperscan/src/rose/rose_build_add.cpp @@ -55,9 +55,9 @@ #include "util/container.h" #include "util/dump_charclass.h" #include "util/graph_range.h" -#include "util/insertion_ordered.h" +#include "util/insertion_ordered.h" #include "util/make_unique.h" -#include "util/noncopyable.h" +#include "util/noncopyable.h" #include "util/order_check.h" #include "util/report_manager.h" #include "util/ue2string.h" @@ -77,7 +77,7 @@ namespace ue2 { /** * \brief Data used by most of the construction code in this file. */ -struct RoseBuildData : noncopyable { +struct RoseBuildData : noncopyable { RoseBuildData(const RoseInGraph &ig_in, bool som_in) : ig(ig_in), som(som_in) {} @@ -86,7 +86,7 @@ struct RoseBuildData : noncopyable { /** Edges we've transformed (in \ref transformAnchoredLiteralOverlap) which * require ANCH history to prevent overlap. */ - unordered_set<RoseInEdge> anch_history_edges; + unordered_set<RoseInEdge> anch_history_edges; /** True if we're tracking Start of Match. */ bool som; @@ -111,7 +111,7 @@ RoseVertex createVertex(RoseBuildImpl *build, u32 literalId, u32 min_offset, g[v].min_offset = min_offset; g[v].max_offset = max_offset; - DEBUG_PRINTF("insert vertex %zu into literal %u's vertex set\n", g[v].index, + DEBUG_PRINTF("insert vertex %zu into literal %u's vertex set\n", g[v].index, literalId); g[v].literals.insert(literalId); build->literal_info[literalId].vertices.insert(v); @@ -122,7 +122,7 @@ RoseVertex createVertex(RoseBuildImpl *build, u32 literalId, u32 min_offset, RoseVertex createVertex(RoseBuildImpl *build, const RoseVertex parent, u32 minBound, u32 maxBound, u32 literalId, size_t literalLength, - const flat_set<ReportID> &reports) { + const flat_set<ReportID> &reports) { assert(parent != RoseGraph::null_vertex()); RoseGraph &g = build->g; @@ -132,7 +132,7 @@ RoseVertex createVertex(RoseBuildImpl *build, const RoseVertex parent, /* fill in report information */ g[v].reports.insert(reports.begin(), reports.end()); - RoseEdge e = add_edge(parent, v, g); + RoseEdge e = add_edge(parent, v, g); DEBUG_PRINTF("adding edge (%u, %u) to parent\n", minBound, maxBound); g[e].minBound = minBound; @@ -159,10 +159,10 @@ RoseVertex createAnchoredVertex(RoseBuildImpl *build, u32 literalId, RoseGraph &g = build->g; RoseVertex v = createVertex(build, literalId, min_offset, max_offset); - DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].index, + DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].index, literalId); - RoseEdge e = add_edge(build->anchored_root, v, g); + RoseEdge e = add_edge(build->anchored_root, v, g); g[e].minBound = min_offset; g[e].maxBound = max_offset; @@ -173,7 +173,7 @@ static RoseVertex duplicate(RoseBuildImpl *build, RoseVertex v) { RoseGraph &g = build->g; RoseVertex w = add_vertex(g[v], g); - DEBUG_PRINTF("added vertex %zu\n", g[w].index); + DEBUG_PRINTF("added vertex %zu\n", g[w].index); for (auto lit_id : g[w].literals) { build->literal_info[lit_id].vertices.insert(w); @@ -182,7 +182,7 @@ RoseVertex duplicate(RoseBuildImpl *build, RoseVertex v) { for (const auto &e : in_edges_range(v, g)) { RoseVertex s = source(e, g); add_edge(s, w, g[e], g); - DEBUG_PRINTF("added edge (%zu,%zu)\n", g[s].index, g[w].index); + DEBUG_PRINTF("added edge (%zu,%zu)\n", g[s].index, g[w].index); } return w; @@ -191,7 +191,7 @@ RoseVertex duplicate(RoseBuildImpl *build, RoseVertex v) { namespace { struct created_key { explicit created_key(const RoseInEdgeProps &trep) - : prefix(trep.graph.get()), lag(trep.graph_lag) { + : prefix(trep.graph.get()), lag(trep.graph_lag) { } bool operator<(const created_key &b) const { const created_key &a = *this; @@ -218,7 +218,7 @@ RoseRoleHistory selectHistory(const RoseBuildImpl &tbi, const RoseBuildData &bd, const bool has_bounds = g[e].minBound || (g[e].maxBound != ROSE_BOUND_INF); DEBUG_PRINTF("edge %zu->%zu, bounds=[%u,%u], fixed_u=%d, prefix=%d\n", - g[u].index, g[v].index, g[e].minBound, g[e].maxBound, + g[u].index, g[v].index, g[e].minBound, g[e].maxBound, (int)g[u].fixedOffset(), (int)g[v].left); if (g[v].left) { @@ -277,8 +277,8 @@ void createVertices(RoseBuildImpl *tbi, if (prefix_graph) { g[w].left.graph = prefix_graph; - if (edge_props.dfa) { - g[w].left.dfa = edge_props.dfa; + if (edge_props.dfa) { + g[w].left.dfa = edge_props.dfa; } g[w].left.haig = edge_props.haig; g[w].left.lag = prefix_lag; @@ -296,19 +296,19 @@ void createVertices(RoseBuildImpl *tbi, if (bd.som && !g[w].left.haig) { /* no prefix - som based on literal start */ assert(!prefix_graph); - g[w].som_adjust = tbi->literals.at(literalId).elength(); + g[w].som_adjust = tbi->literals.at(literalId).elength(); DEBUG_PRINTF("set som_adjust to %u\n", g[w].som_adjust); } - DEBUG_PRINTF(" adding new vertex index=%zu\n", tbi->g[w].index); + DEBUG_PRINTF(" adding new vertex index=%zu\n", tbi->g[w].index); vertex_map[iv].push_back(w); } else { w = created[key]; } - RoseVertex p = pv.first; + RoseVertex p = pv.first; - RoseEdge e = add_edge(p, w, g); + RoseEdge e = add_edge(p, w, g); DEBUG_PRINTF("adding edge (%u,%u) to parent\n", edge_props.minBound, edge_props.maxBound); g[e].minBound = edge_props.minBound; @@ -334,7 +334,7 @@ void createVertices(RoseBuildImpl *tbi, u32 ghostId = tbi->literal_info[literalId].undelayed_id; DEBUG_PRINTF("creating delay ghost vertex, id=%u\n", ghostId); assert(ghostId != literalId); - assert(tbi->literals.at(ghostId).delay == 0); + assert(tbi->literals.at(ghostId).delay == 0); // Adjust offsets, removing delay. u32 ghost_min = min_offset, ghost_max = max_offset; @@ -346,7 +346,7 @@ void createVertices(RoseBuildImpl *tbi, for (const auto &pv : parents) { const RoseInEdgeProps &edge_props = bd.ig[pv.second]; - RoseEdge e = add_edge(pv.first, g_v, tbi->g); + RoseEdge e = add_edge(pv.first, g_v, tbi->g); g[e].minBound = edge_props.minBound; g[e].maxBound = edge_props.maxBound; g[e].history = selectHistory(*tbi, bd, pv.second, e); @@ -363,7 +363,7 @@ void createVertices(RoseBuildImpl *tbi, /* ensure the holder does not accept any paths which do not end with lit */ static void removeFalsePaths(NGHolder &g, const ue2_literal &lit) { - DEBUG_PRINTF("strip '%s'\n", dumpString(lit).c_str()); + DEBUG_PRINTF("strip '%s'\n", dumpString(lit).c_str()); set<NFAVertex> curr, next; curr.insert(g.accept); curr.insert(g.acceptEod); @@ -371,7 +371,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) { for (auto it = lit.rbegin(), ite = lit.rend(); it != ite; ++it) { next.clear(); for (auto curr_v : curr) { - DEBUG_PRINTF("handling %zu\n", g[curr_v].index); + DEBUG_PRINTF("handling %zu\n", g[curr_v].index); vector<NFAVertex> next_cand; insert(&next_cand, next_cand.end(), inv_adjacent_vertices(curr_v, g)); @@ -389,7 +389,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) { const CharReach &cr = g[v].char_reach; if (!overlaps(*it, cr)) { - DEBUG_PRINTF("false edge %zu\n", g[v].index); + DEBUG_PRINTF("false edge %zu\n", g[v].index); continue; } @@ -397,7 +397,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) { clone_in_edges(g, v, v2); add_edge(v2, curr_v, g); g[v2].char_reach &= *it; - DEBUG_PRINTF("next <- %zu\n", g[v2].index); + DEBUG_PRINTF("next <- %zu\n", g[v2].index); next.insert(v2); } } @@ -406,7 +406,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) { } pruneUseless(g); - clearReports(g); + clearReports(g); assert(in_degree(g.accept, g) || in_degree(g.acceptEod, g) > 1); assert(allMatchStatesHaveReports(g)); @@ -545,7 +545,7 @@ void findRoseLiteralMask(const NGHolder &h, const u32 lag, vector<u8> &msk, next.clear(); CharReach cr; for (auto v : curr) { - DEBUG_PRINTF("vertex %zu, reach %s\n", h[v].index, + DEBUG_PRINTF("vertex %zu, reach %s\n", h[v].index, describeClass(h[v].char_reach).c_str()); cr |= h[v].char_reach; insert(&next, inv_adjacent_vertices(v, h)); @@ -640,96 +640,96 @@ floating: } static -unique_ptr<NGHolder> makeRoseEodPrefix(const NGHolder &h, RoseBuildImpl &build, - map<flat_set<ReportID>, ReportID> &remap) { +unique_ptr<NGHolder> makeRoseEodPrefix(const NGHolder &h, RoseBuildImpl &build, + map<flat_set<ReportID>, ReportID> &remap) { assert(generates_callbacks(h)); - assert(!in_degree(h.accept, h)); - auto gg = cloneHolder(h); - NGHolder &g = *gg; - g.kind = is_triggered(h) ? NFA_INFIX : NFA_PREFIX; + assert(!in_degree(h.accept, h)); + auto gg = cloneHolder(h); + NGHolder &g = *gg; + g.kind = is_triggered(h) ? NFA_INFIX : NFA_PREFIX; // Move acceptEod edges over to accept. vector<NFAEdge> dead; - for (const auto &e : in_edges_range(g.acceptEod, g)) { - NFAVertex u = source(e, g); - if (u == g.accept) { + for (const auto &e : in_edges_range(g.acceptEod, g)) { + NFAVertex u = source(e, g); + if (u == g.accept) { continue; } - add_edge_if_not_present(u, g.accept, g); + add_edge_if_not_present(u, g.accept, g); dead.push_back(e); - - if (!contains(remap, g[u].reports)) { - remap[g[u].reports] = build.getNewNfaReport(); - } - - g[u].reports = { remap[g[u].reports] }; + + if (!contains(remap, g[u].reports)) { + remap[g[u].reports] = build.getNewNfaReport(); + } + + g[u].reports = { remap[g[u].reports] }; } - remove_edges(dead, g); - return gg; -} - -static -u32 getEodEventID(RoseBuildImpl &build) { - // Allocate the EOD event if it hasn't been already. - if (build.eod_event_literal_id == MO_INVALID_IDX) { - build.eod_event_literal_id = build.getLiteralId({}, 0, ROSE_EVENT); - } - - return build.eod_event_literal_id; -} - -static -void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u, - const NGHolder &h) { - assert(!build.isInETable(u)); - - RoseGraph &g = build.g; - map<flat_set<ReportID>, ReportID> report_remap; - shared_ptr<NGHolder> eod_leftfix - = makeRoseEodPrefix(h, build, report_remap); - - u32 eod_event = getEodEventID(build); - - for (const auto &report_mapping : report_remap) { - RoseVertex v = add_vertex(g); - g[v].literals.insert(eod_event); - build.literal_info[eod_event].vertices.insert(v); - - g[v].left.graph = eod_leftfix; - g[v].left.leftfix_report = report_mapping.second; - g[v].left.lag = 0; - RoseEdge e1 = add_edge(u, v, g); - g[e1].minBound = 0; - g[e1].maxBound = ROSE_BOUND_INF; - g[v].min_offset = add_rose_depth(g[u].min_offset, - findMinWidth(*g[v].left.graph)); - g[v].max_offset = ROSE_BOUND_INF; - - depth max_width = findMaxWidth(*g[v].left.graph); - if (u != build.root && max_width.is_finite() - && (!build.isAnyStart(u) || isPureAnchored(*g[v].left.graph))) { - g[e1].maxBound = max_width; - g[v].max_offset = add_rose_depth(g[u].max_offset, max_width); - } - - g[e1].history = ROSE_ROLE_HISTORY_NONE; // handled by prefix - RoseVertex w = add_vertex(g); - g[w].eod_accept = true; - g[w].reports = report_mapping.first; - g[w].min_offset = g[v].min_offset; - g[w].max_offset = g[v].max_offset; - RoseEdge e = add_edge(v, w, g); - g[e].minBound = 0; - g[e].maxBound = 0; - /* No need to set history as the event is only delivered at the last - * byte anyway - no need to invalidate stale entries. */ - g[e].history = ROSE_ROLE_HISTORY_NONE; - DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index); - } + remove_edges(dead, g); + return gg; } static +u32 getEodEventID(RoseBuildImpl &build) { + // Allocate the EOD event if it hasn't been already. + if (build.eod_event_literal_id == MO_INVALID_IDX) { + build.eod_event_literal_id = build.getLiteralId({}, 0, ROSE_EVENT); + } + + return build.eod_event_literal_id; +} + +static +void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u, + const NGHolder &h) { + assert(!build.isInETable(u)); + + RoseGraph &g = build.g; + map<flat_set<ReportID>, ReportID> report_remap; + shared_ptr<NGHolder> eod_leftfix + = makeRoseEodPrefix(h, build, report_remap); + + u32 eod_event = getEodEventID(build); + + for (const auto &report_mapping : report_remap) { + RoseVertex v = add_vertex(g); + g[v].literals.insert(eod_event); + build.literal_info[eod_event].vertices.insert(v); + + g[v].left.graph = eod_leftfix; + g[v].left.leftfix_report = report_mapping.second; + g[v].left.lag = 0; + RoseEdge e1 = add_edge(u, v, g); + g[e1].minBound = 0; + g[e1].maxBound = ROSE_BOUND_INF; + g[v].min_offset = add_rose_depth(g[u].min_offset, + findMinWidth(*g[v].left.graph)); + g[v].max_offset = ROSE_BOUND_INF; + + depth max_width = findMaxWidth(*g[v].left.graph); + if (u != build.root && max_width.is_finite() + && (!build.isAnyStart(u) || isPureAnchored(*g[v].left.graph))) { + g[e1].maxBound = max_width; + g[v].max_offset = add_rose_depth(g[u].max_offset, max_width); + } + + g[e1].history = ROSE_ROLE_HISTORY_NONE; // handled by prefix + RoseVertex w = add_vertex(g); + g[w].eod_accept = true; + g[w].reports = report_mapping.first; + g[w].min_offset = g[v].min_offset; + g[w].max_offset = g[v].max_offset; + RoseEdge e = add_edge(v, w, g); + g[e].minBound = 0; + g[e].maxBound = 0; + /* No need to set history as the event is only delivered at the last + * byte anyway - no need to invalidate stale entries. */ + g[e].history = ROSE_ROLE_HISTORY_NONE; + DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index); + } +} + +static void doRoseAcceptVertex(RoseBuildImpl *tbi, const vector<pair<RoseVertex, RoseInEdge> > &parents, RoseInVertex iv, const RoseBuildData &bd) { @@ -742,22 +742,22 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi, RoseVertex u = pv.first; const RoseInEdgeProps &edge_props = bd.ig[pv.second]; - /* We need to duplicate the parent vertices if: - * - * 1) It already has a suffix, etc as we are going to add the specified - * suffix, etc to the parents and we do not want to overwrite the - * existing information. - * - * 2) We are making the an EOD accept and the vertex already has other - * out-edges - The LAST_BYTE history used for EOD accepts is - * incompatible with normal successors. As accepts are processed last we - * do not need to worry about other normal successors being added later. - */ + /* We need to duplicate the parent vertices if: + * + * 1) It already has a suffix, etc as we are going to add the specified + * suffix, etc to the parents and we do not want to overwrite the + * existing information. + * + * 2) We are making the an EOD accept and the vertex already has other + * out-edges - The LAST_BYTE history used for EOD accepts is + * incompatible with normal successors. As accepts are processed last we + * do not need to worry about other normal successors being added later. + */ if (g[u].suffix || !g[u].reports.empty() - || (ig[iv].type == RIV_ACCEPT_EOD && out_degree(u, g) - && !edge_props.graph) + || (ig[iv].type == RIV_ACCEPT_EOD && out_degree(u, g) + && !edge_props.graph) || (!isLeafNode(u, g) && !tbi->isAnyStart(u))) { - DEBUG_PRINTF("duplicating for parent %zu\n", g[u].index); + DEBUG_PRINTF("duplicating for parent %zu\n", g[u].index); assert(!tbi->isAnyStart(u)); u = duplicate(tbi, u); g[u].suffix.reset(); @@ -767,56 +767,56 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi, assert(!g[u].suffix); if (ig[iv].type == RIV_ACCEPT) { assert(!tbi->isAnyStart(u)); - if (edge_props.dfa) { - DEBUG_PRINTF("adding early dfa suffix to i%zu\n", g[u].index); - g[u].suffix.rdfa = edge_props.dfa; + if (edge_props.dfa) { + DEBUG_PRINTF("adding early dfa suffix to i%zu\n", g[u].index); + g[u].suffix.rdfa = edge_props.dfa; g[u].suffix.dfa_min_width = findMinWidth(*edge_props.graph); g[u].suffix.dfa_max_width = findMaxWidth(*edge_props.graph); } else if (edge_props.graph) { - DEBUG_PRINTF("adding suffix to i%zu\n", g[u].index); + DEBUG_PRINTF("adding suffix to i%zu\n", g[u].index); g[u].suffix.graph = edge_props.graph; assert(g[u].suffix.graph->kind == NFA_SUFFIX); /* TODO: set dfa_(min|max)_width */ } else if (edge_props.haig) { - DEBUG_PRINTF("adding suffaig to i%zu\n", g[u].index); + DEBUG_PRINTF("adding suffaig to i%zu\n", g[u].index); g[u].suffix.haig = edge_props.haig; } else { - DEBUG_PRINTF("adding boring accept to i%zu\n", g[u].index); + DEBUG_PRINTF("adding boring accept to i%zu\n", g[u].index); assert(!g[u].eod_accept); g[u].reports = ig[iv].reports; } } else { assert(ig[iv].type == RIV_ACCEPT_EOD); - assert(!edge_props.haig); - - if (!edge_props.graph) { - RoseVertex w = add_vertex(g); - g[w].eod_accept = true; - g[w].reports = ig[iv].reports; - g[w].min_offset = g[u].min_offset; - g[w].max_offset = g[u].max_offset; - RoseEdge e = add_edge(u, w, g); - g[e].minBound = 0; - g[e].maxBound = 0; - g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE; - DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index); - continue; - } - - const NGHolder &h = *edge_props.graph; - assert(!in_degree(h.accept, h)); - assert(generates_callbacks(h)); - - if (tbi->isInETable(u)) { - assert(h.kind == NFA_SUFFIX); + assert(!edge_props.haig); + + if (!edge_props.graph) { + RoseVertex w = add_vertex(g); + g[w].eod_accept = true; + g[w].reports = ig[iv].reports; + g[w].min_offset = g[u].min_offset; + g[w].max_offset = g[u].max_offset; + RoseEdge e = add_edge(u, w, g); + g[e].minBound = 0; + g[e].maxBound = 0; + g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE; + DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index); + continue; + } + + const NGHolder &h = *edge_props.graph; + assert(!in_degree(h.accept, h)); + assert(generates_callbacks(h)); + + if (tbi->isInETable(u)) { + assert(h.kind == NFA_SUFFIX); assert(!tbi->isAnyStart(u)); /* etable can't/shouldn't use eod event */ - DEBUG_PRINTF("adding suffix to i%zu\n", g[u].index); + DEBUG_PRINTF("adding suffix to i%zu\n", g[u].index); g[u].suffix.graph = edge_props.graph; continue; } - makeEodEventLeftfix(*tbi, u, h); + makeEodEventLeftfix(*tbi, u, h); } } } @@ -917,8 +917,8 @@ bool suitableForEod(const RoseInGraph &ig, vector<RoseInVertex> topo, ENSURE_AT_LEAST(&v_depth, (u32)max_width); } - if (v_depth == ROSE_BOUND_INF - || v_depth > cc.grey.maxHistoryAvailable) { + if (v_depth == ROSE_BOUND_INF + || v_depth > cc.grey.maxHistoryAvailable) { DEBUG_PRINTF("not suitable for eod table %u\n", v_depth); return false; } @@ -932,13 +932,13 @@ bool suitableForEod(const RoseInGraph &ig, vector<RoseInVertex> topo, } static -void shift_accepts_to_end(const RoseInGraph &ig, - vector<RoseInVertex> &topo_order) { - stable_partition(begin(topo_order), end(topo_order), - [&](RoseInVertex v){ return !is_any_accept(v, ig); }); -} - -static +void shift_accepts_to_end(const RoseInGraph &ig, + vector<RoseInVertex> &topo_order) { + stable_partition(begin(topo_order), end(topo_order), + [&](RoseInVertex v){ return !is_any_accept(v, ig); }); +} + +static void populateRoseGraph(RoseBuildImpl *tbi, RoseBuildData &bd) { const RoseInGraph &ig = bd.ig; @@ -950,7 +950,7 @@ void populateRoseGraph(RoseBuildImpl *tbi, RoseBuildData &bd) { map<RoseInVertex, vector<RoseVertex> > vertex_map; vector<RoseInVertex> v_order = topo_order(ig); - shift_accepts_to_end(ig, v_order); + shift_accepts_to_end(ig, v_order); u32 eod_space_required; bool use_eod_table = suitableForEod(ig, v_order, &eod_space_required, @@ -963,7 +963,7 @@ void populateRoseGraph(RoseBuildImpl *tbi, RoseBuildData &bd) { || ig[v_order.front()].type == RIV_ANCHORED_START); for (RoseInVertex iv : v_order) { - DEBUG_PRINTF("vertex %zu\n", ig[iv].index); + DEBUG_PRINTF("vertex %zu\n", ig[iv].index); if (ig[iv].type == RIV_START) { DEBUG_PRINTF("is root\n"); @@ -982,7 +982,7 @@ void populateRoseGraph(RoseBuildImpl *tbi, RoseBuildData &bd) { const vector<RoseVertex> &images = vertex_map[u]; // We should have no dupes. - assert(set<RoseVertex>(images.begin(), images.end()).size() + assert(set<RoseVertex>(images.begin(), images.end()).size() == images.size()); for (auto v_image : images) { @@ -1032,8 +1032,8 @@ bool empty(const GraphT &g) { } static -bool canImplementGraph(NGHolder &h, bool prefilter, const ReportManager &rm, - const CompileContext &cc) { +bool canImplementGraph(NGHolder &h, bool prefilter, const ReportManager &rm, + const CompileContext &cc) { if (isImplementableNFA(h, &rm, cc)) { return true; } @@ -1106,7 +1106,7 @@ u32 maxAvailableDelay(const ue2_literal &pred_key, const ue2_literal &lit_key) { } static -u32 findMaxSafeDelay(const RoseInGraph &ig, RoseInVertex u, RoseInVertex v) { +u32 findMaxSafeDelay(const RoseInGraph &ig, RoseInVertex u, RoseInVertex v) { // First, check the overlap constraints on (u,v). size_t max_delay; if (ig[v].type == RIV_LITERAL) { @@ -1504,10 +1504,10 @@ bool validateKinds(const RoseInGraph &g) { } #endif -bool RoseBuildImpl::addRose(const RoseInGraph &ig, bool prefilter) { +bool RoseBuildImpl::addRose(const RoseInGraph &ig, bool prefilter) { DEBUG_PRINTF("trying to rose\n"); assert(validateKinds(ig)); - assert(hasCorrectlyNumberedVertices(ig)); + assert(hasCorrectlyNumberedVertices(ig)); if (::ue2::empty(ig)) { assert(0); @@ -1523,38 +1523,38 @@ bool RoseBuildImpl::addRose(const RoseInGraph &ig, bool prefilter) { transformAnchoredLiteralOverlap(in, bd, cc); transformSuffixDelay(in, cc); - renumber_vertices(in); - assert(validateKinds(in)); + renumber_vertices(in); + assert(validateKinds(in)); - insertion_ordered_map<NGHolder *, vector<RoseInEdge>> graphs; + insertion_ordered_map<NGHolder *, vector<RoseInEdge>> graphs; for (const auto &e : edges_range(in)) { if (!in[e].graph) { - assert(!in[e].dfa); - assert(!in[e].haig); + assert(!in[e].dfa); + assert(!in[e].haig); continue; // no graph } - if (in[e].haig || in[e].dfa) { - /* Early DFAs/Haigs are always implementable (we've already built - * the raw DFA). */ + if (in[e].haig || in[e].dfa) { + /* Early DFAs/Haigs are always implementable (we've already built + * the raw DFA). */ continue; } NGHolder *h = in[e].graph.get(); - - assert(isCorrectlyTopped(*h)); + + assert(isCorrectlyTopped(*h)); graphs[h].push_back(e); } vector<RoseInEdge> graph_edges; - for (const auto &m : graphs) { - NGHolder *h = m.first; - if (!canImplementGraph(*h, prefilter, rm, cc)) { + for (const auto &m : graphs) { + NGHolder *h = m.first; + if (!canImplementGraph(*h, prefilter, rm, cc)) { return false; } - insert(&graph_edges, graph_edges.end(), m.second); + insert(&graph_edges, graph_edges.end(), m.second); } /* we are now past the point of no return. We can start making irreversible @@ -1569,7 +1569,7 @@ bool RoseBuildImpl::addRose(const RoseInGraph &ig, bool prefilter) { if (!generates_callbacks(whatRoseIsThis(in, e)) && in[target(e, in)].type != RIV_ACCEPT_EOD) { - set_report(h, getNewNfaReport()); + set_report(h, getNewNfaReport()); } } @@ -1612,7 +1612,7 @@ bool roseCheckRose(const RoseInGraph &ig, bool prefilter, return false; } - vector<NGHolder *> graphs; + vector<NGHolder *> graphs; for (const auto &e : edges_range(ig)) { if (!ig[e].graph) { @@ -1624,11 +1624,11 @@ bool roseCheckRose(const RoseInGraph &ig, bool prefilter, continue; } - graphs.push_back(ig[e].graph.get()); + graphs.push_back(ig[e].graph.get()); } - for (const auto &g : graphs) { - if (!canImplementGraph(*g, prefilter, rm, cc)) { + for (const auto &g : graphs) { + if (!canImplementGraph(*g, prefilter, rm, cc)) { return false; } } @@ -1637,7 +1637,7 @@ bool roseCheckRose(const RoseInGraph &ig, bool prefilter, } void RoseBuildImpl::add(bool anchored, bool eod, const ue2_literal &lit, - const flat_set<ReportID> &reports) { + const flat_set<ReportID> &reports) { assert(!reports.empty()); if (cc.grey.floodAsPuffette && !anchored && !eod && is_flood(lit) && @@ -1672,7 +1672,7 @@ static u32 findMaxBAWidth(const NGHolder &h) { // Must be bi-anchored: no out-edges from startDs (other than its // self-loop), no in-edges to accept. - if (out_degree(h.startDs, h) > 1 || in_degree(h.accept, h)) { + if (out_degree(h.startDs, h) > 1 || in_degree(h.accept, h)) { return ROSE_BOUND_INF; } depth d = findMaxWidth(h); @@ -1694,70 +1694,70 @@ void populateOutfixInfo(OutfixInfo &outfix, const NGHolder &h, populateReverseAccelerationInfo(outfix.rev_info, h); } -static -bool addEodOutfix(RoseBuildImpl &build, const NGHolder &h) { - map<flat_set<ReportID>, ReportID> report_remap; - shared_ptr<NGHolder> eod_leftfix - = makeRoseEodPrefix(h, build, report_remap); - - bool nfa_ok = isImplementableNFA(h, &build.rm, build.cc); - - /* TODO: check if early dfa is possible */ - - if (!nfa_ok) { - DEBUG_PRINTF("could not build as NFA\n"); - return false; - } - - u32 eod_event = getEodEventID(build); - - auto &g = build.g; - for (const auto &report_mapping : report_remap) { - RoseVertex v = add_vertex(g); - g[v].literals.insert(eod_event); - build.literal_info[eod_event].vertices.insert(v); - - g[v].left.graph = eod_leftfix; - g[v].left.leftfix_report = report_mapping.second; - g[v].left.lag = 0; - RoseEdge e1 = add_edge(build.anchored_root, v, g); - g[e1].minBound = 0; - g[e1].maxBound = ROSE_BOUND_INF; - g[v].min_offset = findMinWidth(*eod_leftfix); - g[v].max_offset = ROSE_BOUND_INF; - - depth max_width = findMaxWidth(*g[v].left.graph); - if (max_width.is_finite() && isPureAnchored(*eod_leftfix)) { - g[e1].maxBound = max_width; - g[v].max_offset = max_width; - } - - g[e1].history = ROSE_ROLE_HISTORY_NONE; // handled by prefix - RoseVertex w = add_vertex(g); - g[w].eod_accept = true; - g[w].reports = report_mapping.first; - g[w].min_offset = g[v].min_offset; - g[w].max_offset = g[v].max_offset; - RoseEdge e = add_edge(v, w, g); - g[e].minBound = 0; - g[e].maxBound = 0; - g[e].history = ROSE_ROLE_HISTORY_NONE; - DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index); - } - - return true; -} - +static +bool addEodOutfix(RoseBuildImpl &build, const NGHolder &h) { + map<flat_set<ReportID>, ReportID> report_remap; + shared_ptr<NGHolder> eod_leftfix + = makeRoseEodPrefix(h, build, report_remap); + + bool nfa_ok = isImplementableNFA(h, &build.rm, build.cc); + + /* TODO: check if early dfa is possible */ + + if (!nfa_ok) { + DEBUG_PRINTF("could not build as NFA\n"); + return false; + } + + u32 eod_event = getEodEventID(build); + + auto &g = build.g; + for (const auto &report_mapping : report_remap) { + RoseVertex v = add_vertex(g); + g[v].literals.insert(eod_event); + build.literal_info[eod_event].vertices.insert(v); + + g[v].left.graph = eod_leftfix; + g[v].left.leftfix_report = report_mapping.second; + g[v].left.lag = 0; + RoseEdge e1 = add_edge(build.anchored_root, v, g); + g[e1].minBound = 0; + g[e1].maxBound = ROSE_BOUND_INF; + g[v].min_offset = findMinWidth(*eod_leftfix); + g[v].max_offset = ROSE_BOUND_INF; + + depth max_width = findMaxWidth(*g[v].left.graph); + if (max_width.is_finite() && isPureAnchored(*eod_leftfix)) { + g[e1].maxBound = max_width; + g[v].max_offset = max_width; + } + + g[e1].history = ROSE_ROLE_HISTORY_NONE; // handled by prefix + RoseVertex w = add_vertex(g); + g[w].eod_accept = true; + g[w].reports = report_mapping.first; + g[w].min_offset = g[v].min_offset; + g[w].max_offset = g[v].max_offset; + RoseEdge e = add_edge(v, w, g); + g[e].minBound = 0; + g[e].maxBound = 0; + g[e].history = ROSE_ROLE_HISTORY_NONE; + DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index); + } + + return true; +} + bool RoseBuildImpl::addOutfix(const NGHolder &h) { DEBUG_PRINTF("%zu vertices, %zu edges\n", num_vertices(h), num_edges(h)); - /* TODO: handle more than one report */ - if (!in_degree(h.accept, h) - && all_reports(h).size() == 1 - && addEodOutfix(*this, h)) { - return true; - } - + /* TODO: handle more than one report */ + if (!in_degree(h.accept, h) + && all_reports(h).size() == 1 + && addEodOutfix(*this, h)) { + return true; + } + const u32 nfa_states = isImplementableNFA(h, &rm, cc); if (nfa_states) { DEBUG_PRINTF("implementable as an NFA in %u states\n", nfa_states); @@ -1802,12 +1802,12 @@ bool RoseBuildImpl::addOutfix(const NGHolder &h, const raw_som_dfa &haig) { bool RoseBuildImpl::addOutfix(const raw_puff &rp) { if (!mpv_outfix) { - mpv_outfix = std::make_unique<OutfixInfo>(MpvProto()); + mpv_outfix = std::make_unique<OutfixInfo>(MpvProto()); } - auto *mpv = mpv_outfix->mpv(); - assert(mpv); - mpv->puffettes.push_back(rp); + auto *mpv = mpv_outfix->mpv(); + assert(mpv); + mpv->puffettes.push_back(rp); mpv_outfix->maxBAWidth = ROSE_BOUND_INF; /* not ba */ mpv_outfix->minWidth = min(mpv_outfix->minWidth, depth(rp.repeats)); @@ -1827,12 +1827,12 @@ bool RoseBuildImpl::addOutfix(const raw_puff &rp) { bool RoseBuildImpl::addChainTail(const raw_puff &rp, u32 *queue_out, u32 *event_out) { if (!mpv_outfix) { - mpv_outfix = std::make_unique<OutfixInfo>(MpvProto()); + mpv_outfix = std::make_unique<OutfixInfo>(MpvProto()); } - auto *mpv = mpv_outfix->mpv(); - assert(mpv); - mpv->triggered_puffettes.push_back(rp); + auto *mpv = mpv_outfix->mpv(); + assert(mpv); + mpv->triggered_puffettes.push_back(rp); mpv_outfix->maxBAWidth = ROSE_BOUND_INF; /* not ba */ mpv_outfix->minWidth = min(mpv_outfix->minWidth, depth(rp.repeats)); @@ -1844,7 +1844,7 @@ bool RoseBuildImpl::addChainTail(const raw_puff &rp, u32 *queue_out, * the caller */ *queue_out = mpv_outfix->get_queue(qif); - *event_out = MQE_TOP_FIRST + mpv->triggered_puffettes.size() - 1; + *event_out = MQE_TOP_FIRST + mpv->triggered_puffettes.size() - 1; return true; /* failure is not yet an option */ } @@ -1858,9 +1858,9 @@ bool prepAcceptForAddAnchoredNFA(RoseBuildImpl &tbi, const NGHolder &w, map<ReportID, u32> &allocated_reports, flat_set<u32> &added_lit_ids) { const depth max_anchored_depth(tbi.cc.grey.maxAnchoredRegion); - const size_t index = w[u].index; - assert(index < vertexDepths.size()); - const DepthMinMax &d = vertexDepths.at(index); + const size_t index = w[u].index; + assert(index < vertexDepths.size()); + const DepthMinMax &d = vertexDepths.at(index); for (const auto &int_report : w[u].reports) { assert(int_report != MO_INVALID_IDX); @@ -1902,20 +1902,20 @@ void removeAddedLiterals(RoseBuildImpl &tbi, const flat_set<u32> &lit_ids) { return; } - DEBUG_PRINTF("remove last %zu literals\n", lit_ids.size()); - + DEBUG_PRINTF("remove last %zu literals\n", lit_ids.size()); + // lit_ids should be a contiguous range. assert(lit_ids.size() == *lit_ids.rbegin() - *lit_ids.begin() + 1); - assert(*lit_ids.rbegin() == tbi.literals.size() - 1); + assert(*lit_ids.rbegin() == tbi.literals.size() - 1); - assert(all_of_in(lit_ids, [&](u32 lit_id) { - return lit_id < tbi.literal_info.size() && - tbi.literals.at(lit_id).table == ROSE_ANCHORED && - tbi.literal_info[lit_id].vertices.empty(); - })); + assert(all_of_in(lit_ids, [&](u32 lit_id) { + return lit_id < tbi.literal_info.size() && + tbi.literals.at(lit_id).table == ROSE_ANCHORED && + tbi.literal_info[lit_id].vertices.empty(); + })); - tbi.literals.erase_back(lit_ids.size()); - assert(tbi.literals.size() == *lit_ids.begin()); + tbi.literals.erase_back(lit_ids.size()); + assert(tbi.literals.size() == *lit_ids.begin()); // lit_ids should be at the end of tbi.literal_info. assert(tbi.literal_info.size() == *lit_ids.rbegin() + 1); @@ -1923,7 +1923,7 @@ void removeAddedLiterals(RoseBuildImpl &tbi, const flat_set<u32> &lit_ids) { } bool RoseBuildImpl::addAnchoredAcyclic(const NGHolder &h) { - auto vertexDepths = calcDepthsFrom(h, h.start); + auto vertexDepths = calcDepthsFrom(h, h.start); map<NFAVertex, set<u32> > reportMap; /* NFAVertex -> literal ids */ map<u32, DepthMinMax> depthMap; /* literal id -> min/max depth */ |