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
void copyInEdges(NGHolder &g, NFAVertex from, NFAVertex to,
const ue2::unordered_set<NFAVertex> &rverts) {
void copyInEdges(NGHolder &g, NFAVertex from, NFAVertex to) {
for (const auto &e : in_edges_range(from, g)) {
NFAVertex u = source(e, g);
if (contains(rverts, u)) {
continue;
}
add_edge_if_not_present(u, to, g[e], g);
}
}
static
void copyOutEdges(NGHolder &g, NFAVertex from, NFAVertex to,
const ue2::unordered_set<NFAVertex> &rverts) {
void copyOutEdges(NGHolder &g, NFAVertex from, NFAVertex to) {
for (const auto &e : out_edges_range(from, g)) {
NFAVertex t = target(e, g);
if (contains(rverts, t)) {
continue;
}
add_edge_if_not_present(to, t, g[e], 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
void replaceRegion(NGHolder &g, const RegionInfo &ri,
size_t *verticesAdded, size_t *verticesRemoved) {
@ -284,19 +289,17 @@ void replaceRegion(NGHolder &g, const RegionInfo &ri,
add_edge(verts.back(), verts.back(), g);
}
// Set of vertices in region, for quick lookups.
const ue2::unordered_set<NFAVertex> rverts(ri.vertices.begin(),
ri.vertices.end());
removeInteriorEdges(g, ri);
for (size_t i = 0; i < replacementSize; i++) {
NFAVertex v_new = verts[i];
for (auto v_old : ri.vertices) {
if (i == 0) {
copyInEdges(g, v_old, v_new, rverts);
copyInEdges(g, v_old, v_new);
}
if (i + 1 >= ri.minWidth) {
copyOutEdges(g, v_old, v_new, rverts);
copyOutEdges(g, v_old, v_new);
}
}
}