violet: use bitset to speed up poisonFromSuccessor

This commit is contained in:
Justin Viiret 2017-01-25 11:29:45 +11:00 committed by Matthew Barr
parent bbd64f98ae
commit 1fad822735

View File

@ -69,6 +69,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <boost/core/noncopyable.hpp> #include <boost/core/noncopyable.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/range/adaptor/map.hpp> #include <boost/range/adaptor/map.hpp>
#define STAGE_DEBUG_PRINTF DEBUG_PRINTF #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", DEBUG_PRINTF("poisoning holder of size %zu, succ len %zu\n",
num_vertices(h), succ.length()); 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)) { 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 (auto it = succ.rbegin(); it != succ.rend(); ++it) {
for (const auto &path : curr) { for (const auto &path : curr) {
NFAVertex u = path.first; NFAVertex u = path.first;
const auto &path_set = path.second; const auto &path_set = path.second;
if (u == h.start && overhang_ok) { if (u == h.start && overhang_ok) {
DEBUG_PRINTF("poisoning early %zu [overhang]\n", DEBUG_PRINTF("poisoning early %zu [overhang]\n",
path_set.size()); path_set.count());
insert(&bad, path_set); bad_edges |= path_set;
continue; continue;
} }
if (overlaps(h[u].char_reach, *it)) { if (overlaps(h[u].char_reach, *it)) {
for (const auto &e : in_edges_range(u, h)) { for (const auto &e : in_edges_range(u, h)) {
auto &new_path_set = next[source(e, h)]; auto &new_path_set = next[source(e, h)];
insert(&new_path_set, path_set); if (new_path_set.empty()) {
new_path_set.insert(e); 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()); assert(overhang_ok || !curr.empty());
for (const auto &path : curr) { for (const auto &path : curr) {
insert(&bad, path.second); bad_edges |= path.second;
DEBUG_PRINTF("poisoning %zu vertices\n", path.second.size()); 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);
}
} }
} }