From 1fad82273542b57719f84ab754ec373576483053 Mon Sep 17 00:00:00 2001 From: Justin Viiret Date: Wed, 25 Jan 2017 11:29:45 +1100 Subject: [PATCH] violet: use bitset to speed up poisonFromSuccessor --- src/nfagraph/ng_violet.cpp | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/nfagraph/ng_violet.cpp b/src/nfagraph/ng_violet.cpp index 6ca6f187..1cf3b716 100644 --- a/src/nfagraph/ng_violet.cpp +++ b/src/nfagraph/ng_violet.cpp @@ -69,6 +69,7 @@ #include #include #include +#include #include #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 > curr; + using EdgeSet = boost::dynamic_bitset<>; + + const size_t edge_count = num_edges(h); + EdgeSet bad_edges(edge_count); + + unordered_map 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 > next; + unordered_map 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); + } } }