]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
ng_calc_components: filter vertices from ug
authorJustin Viiret <justin.viiret@intel.com>
Tue, 21 Mar 2017 02:09:53 +0000 (13:09 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Wed, 26 Apr 2017 05:18:13 +0000 (15:18 +1000)
src/nfagraph/ng_calc_components.cpp
src/nfagraph/ng_util.h

index a7d8dd69a0c3d7353f02c08116ea389cc976244b..e06893665c3d485e00da0edcbecb9ecab5d2aa85 100644 (file)
@@ -64,6 +64,7 @@
 #include <vector>
 
 #include <boost/graph/connected_components.hpp>
+#include <boost/graph/filtered_graph.hpp>
 
 using namespace std;
 
@@ -219,28 +220,6 @@ vector<NFAEdge> findShellEdges(const NGHolder &g,
     return shell_edges;
 }
 
-static
-void removeVertices(const flat_set<NFAVertex> &verts, NFAUndirectedGraph &ug,
-                   ue2::unordered_map<NFAVertex, NFAUndirectedVertex> &old2new,
-                   ue2::unordered_map<NFAUndirectedVertex, NFAVertex> &new2old) {
-    for (auto v : verts) {
-        assert(contains(old2new, v));
-        auto uv = old2new.at(v);
-        clear_vertex(uv, ug);
-        remove_vertex(uv, ug);
-        old2new.erase(v);
-        new2old.erase(uv);
-    }
-}
-
-static
-void renumberVertices(NFAUndirectedGraph &ug) {
-    u32 vertexIndex = 0;
-    for (auto uv : vertices_range(ug)) {
-        put(boost::vertex_index, ug, uv, vertexIndex++);
-    }
-}
-
 /**
  * Common code called by calc- and recalc- below. Splits the given holder into
  * one or more connected components, adding them to the comps deque.
@@ -286,15 +265,21 @@ void splitIntoComponents(unique_ptr<NGHolder> g,
         new2old.emplace(m.second, m.first);
     }
 
-    // Remove shells from undirected graph and renumber so we have dense
-    // vertex indices.
-    removeVertices(head_shell, ug, old2new, new2old);
-    removeVertices(tail_shell, ug, old2new, new2old);
-    renumberVertices(ug);
+    // Filter shell vertices from undirected graph.
+    unordered_set<NFAUndirectedVertex> shell_undir_vertices;
+    for (auto v : head_shell) {
+        shell_undir_vertices.insert(old2new.at(v));
+    }
+    for (auto v : tail_shell) {
+        shell_undir_vertices.insert(old2new.at(v));
+    }
+    auto filtered_ug = boost::make_filtered_graph(
+        ug, boost::keep_all(), make_bad_vertex_filter(&shell_undir_vertices));
 
+    // Actually run the connected components algorithm.
     map<NFAUndirectedVertex, u32> split_components;
     const u32 num = connected_components(
-        ug, boost::make_assoc_property_map(split_components));
+        filtered_ug, boost::make_assoc_property_map(split_components));
 
     assert(num > 0);
     if (num == 1 && shell_edges.empty()) {
index f3fa1354fa864e1216b9e532bda78e6c128e0842..1d3a6f325ea83e2f4f04f2d517a291df919ba951 100644 (file)
@@ -124,6 +124,22 @@ bad_edge_filter<EdgeSet> make_bad_edge_filter(const EdgeSet *e) {
     return bad_edge_filter<EdgeSet>(e);
 }
 
+/** \brief vertex graph filter. */
+template<typename VertexSet>
+struct bad_vertex_filter {
+    bad_vertex_filter() = default;
+    explicit bad_vertex_filter(const VertexSet *bad_v) : bad_vertices(bad_v) {}
+    bool operator()(const typename VertexSet::value_type &v) const {
+        return !contains(*bad_vertices, v); /* keep vertices not in bad set */
+    }
+    const VertexSet *bad_vertices = nullptr;
+};
+
+template<typename VertexSet>
+bad_vertex_filter<VertexSet> make_bad_vertex_filter(const VertexSet *v) {
+    return bad_vertex_filter<VertexSet>(v);
+}
+
 /** Visitor that records back edges */
 template <typename BackEdgeSet>
 class BackEdges : public boost::default_dfs_visitor {