]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
violet: use bitset to speed up poisonFromSuccessor
authorJustin Viiret <justin.viiret@intel.com>
Wed, 25 Jan 2017 00:29:45 +0000 (11:29 +1100)
committerMatthew Barr <matthew.barr@intel.com>
Wed, 26 Apr 2017 04:46:42 +0000 (14:46 +1000)
src/nfagraph/ng_violet.cpp

index 6ca6f187ff6040b5fc4103a5417f89232445f9f2..1cf3b7163e58bfd8443287284346bcb6277eb0b5 100644 (file)
@@ -69,6 +69,7 @@
 #include <utility>
 #include <vector>
 #include <boost/core/noncopyable.hpp>
+#include <boost/dynamic_bitset.hpp>
 #include <boost/range/adaptor/map.hpp>
 
 #define STAGE_DEBUG_PRINTF DEBUG_PRINTF
@@ -718,27 +719,39 @@ void poisonFromSuccessor(const NGHolder &h, const ue2_literal &succ,
     DEBUG_PRINTF("poisoning holder of size %zu, succ len %zu\n",
                  num_vertices(h), succ.length());
 
-    map<NFAVertex, flat_set<NFAEdge> > curr;
+    using EdgeSet = boost::dynamic_bitset<>;
+
+    const size_t edge_count = num_edges(h);
+    EdgeSet bad_edges(edge_count);
+
+    unordered_map<NFAVertex, EdgeSet> curr;
     for (const auto &e : in_edges_range(h.accept, h)) {
-        curr[source(e, h)].insert(e);
+        auto &path_set = curr[source(e, h)];
+        if (path_set.empty()) {
+            path_set.resize(edge_count);
+        }
+        path_set.set(h[e].index);
     }
 
-    map<NFAVertex, flat_set<NFAEdge> > next;
+    unordered_map<NFAVertex, EdgeSet> next;
     for (auto it = succ.rbegin(); it != succ.rend(); ++it) {
         for (const auto &path : curr) {
             NFAVertex u = path.first;
             const auto &path_set = path.second;
             if (u == h.start && overhang_ok) {
                 DEBUG_PRINTF("poisoning early %zu [overhang]\n",
-                             path_set.size());
-                insert(&bad, path_set);
+                             path_set.count());
+                bad_edges |= path_set;
                 continue;
             }
             if (overlaps(h[u].char_reach, *it)) {
                 for (const auto &e : in_edges_range(u, h)) {
                     auto &new_path_set = next[source(e, h)];
-                    insert(&new_path_set, path_set);
-                    new_path_set.insert(e);
+                    if (new_path_set.empty()) {
+                        new_path_set.resize(edge_count);
+                    }
+                    new_path_set |= path_set;
+                    new_path_set.set(h[e].index);
                 }
             }
         }
@@ -750,8 +763,14 @@ void poisonFromSuccessor(const NGHolder &h, const ue2_literal &succ,
 
     assert(overhang_ok || !curr.empty());
     for (const auto &path : curr) {
-        insert(&bad, path.second);
-        DEBUG_PRINTF("poisoning %zu vertices\n", path.second.size());
+        bad_edges |= path.second;
+        DEBUG_PRINTF("poisoning %zu vertices\n", path.second.count());
+    }
+
+    for (const auto &e : edges_range(h)) {
+        if (bad_edges.test(h[e].index)) {
+            bad.insert(e);
+        }
     }
 }