ng_prefilter.cpp: remove interior edges first

This allows us to avoid looking them up while we're in copyOutEdges(),
halves time on large cases.
This commit is contained in:
Justin Viiret 2017-07-04 13:22:09 +10:00 committed by Matthew Barr
parent 2fba9bd16c
commit b454ab6484

View File

@ -213,27 +213,17 @@ map<u32, RegionInfo> findRegionInfo(const NGHolder &h,
} }
static static
void copyInEdges(NGHolder &g, NFAVertex from, NFAVertex to, void copyInEdges(NGHolder &g, NFAVertex from, NFAVertex to) {
const ue2::unordered_set<NFAVertex> &rverts) {
for (const auto &e : in_edges_range(from, g)) { for (const auto &e : in_edges_range(from, g)) {
NFAVertex u = source(e, g); NFAVertex u = source(e, g);
if (contains(rverts, u)) {
continue;
}
add_edge_if_not_present(u, to, g[e], g); add_edge_if_not_present(u, to, g[e], g);
} }
} }
static static
void copyOutEdges(NGHolder &g, NFAVertex from, NFAVertex to, void copyOutEdges(NGHolder &g, NFAVertex from, NFAVertex to) {
const ue2::unordered_set<NFAVertex> &rverts) {
for (const auto &e : out_edges_range(from, g)) { for (const auto &e : out_edges_range(from, g)) {
NFAVertex t = target(e, g); NFAVertex t = target(e, g);
if (contains(rverts, t)) {
continue;
}
add_edge_if_not_present(to, t, g[e], g); add_edge_if_not_present(to, t, g[e], g);
if (is_any_accept(t, g)) { if (is_any_accept(t, g)) {
@ -243,6 +233,21 @@ void copyOutEdges(NGHolder &g, NFAVertex from, NFAVertex to,
} }
} }
static
void removeInteriorEdges(NGHolder &g, const RegionInfo &ri) {
// Set of vertices in region, for quick lookups.
const unordered_set<NFAVertex> rverts(ri.vertices.begin(),
ri.vertices.end());
auto is_interior_in_edge = [&](const NFAEdge &e) {
return contains(rverts, source(e, g));
};
for (auto v : ri.vertices) {
remove_in_edge_if(v, is_interior_in_edge, g);
}
}
static static
void replaceRegion(NGHolder &g, const RegionInfo &ri, void replaceRegion(NGHolder &g, const RegionInfo &ri,
size_t *verticesAdded, size_t *verticesRemoved) { size_t *verticesAdded, size_t *verticesRemoved) {
@ -284,19 +289,17 @@ void replaceRegion(NGHolder &g, const RegionInfo &ri,
add_edge(verts.back(), verts.back(), g); add_edge(verts.back(), verts.back(), g);
} }
// Set of vertices in region, for quick lookups. removeInteriorEdges(g, ri);
const ue2::unordered_set<NFAVertex> rverts(ri.vertices.begin(),
ri.vertices.end());
for (size_t i = 0; i < replacementSize; i++) { for (size_t i = 0; i < replacementSize; i++) {
NFAVertex v_new = verts[i]; NFAVertex v_new = verts[i];
for (auto v_old : ri.vertices) { for (auto v_old : ri.vertices) {
if (i == 0) { if (i == 0) {
copyInEdges(g, v_old, v_new, rverts); copyInEdges(g, v_old, v_new);
} }
if (i + 1 >= ri.minWidth) { if (i + 1 >= ri.minWidth) {
copyOutEdges(g, v_old, v_new, rverts); copyOutEdges(g, v_old, v_new);
} }
} }
} }