Introduce custom adjacency-list based graph

This commit is contained in:
Alex Coyte
2016-08-24 16:12:51 +10:00
committed by Matthew Barr
parent 05683655cb
commit e1e9010cac
92 changed files with 3730 additions and 1812 deletions

View File

@@ -203,6 +203,7 @@ static
bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
const u32 comp_id) {
const CompileContext &cc = ng.cc;
assert(hasCorrectlyNumberedVertices(g));
DEBUG_PRINTF("expr=%u, comp=%u: %zu vertices, %zu edges\n",
w.expressionIndex, comp_id, num_vertices(g), num_edges(g));

View File

@@ -202,7 +202,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
}
if (!isStartNode(dotV, g.start, g, true)) {
DEBUG_PRINTF("fleeing: vertex %u has other preds\n", g[dotV].index);
DEBUG_PRINTF("fleeing: vertex %zu has other preds\n", g[dotV].index);
return;
}
@@ -249,7 +249,7 @@ void reformAnchoredRepeatsComponent(NGHolder &g,
remove_edge(g.start, v, g);
}
DEBUG_PRINTF("removing vertex %u\n", g[dotV].index);
DEBUG_PRINTF("removing vertex %zu\n", g[dotV].index);
clear_vertex(dotV, g);
dead.insert(dotV);
compAnchoredStarts.erase(dotV);
@@ -313,14 +313,15 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
}
// A self-loop indicates that this is a '.+' or '.*'
DEBUG_PRINTF("self-loop detected on %u\n", g[dotV].index);
DEBUG_PRINTF("self-loop detected on %zu\n", g[dotV].index);
*startEnd = depth::infinity();
remove_edge(dotV, dotV, g);
return;
}
if (!isStartNode(dotV, g.startDs, g, true)) {
DEBUG_PRINTF("fleeing: vertex %u has other preds\n", g[dotV].index);
DEBUG_PRINTF("fleeing: vertex %zu has other preds\n",
g[dotV].index);
return;
}
@@ -362,14 +363,14 @@ void reformUnanchoredRepeatsComponent(NGHolder &g,
compUnanchoredStarts.clear();
for (auto t : adjacent_vertices_range(dotV, g)) {
if (t != dotV) {
DEBUG_PRINTF("connecting sds -> %u\n", g[t].index);
DEBUG_PRINTF("connecting sds -> %zu\n", g[t].index);
add_edge(g.startDs, t, g);
add_edge(g.start, t, g);
compUnanchoredStarts.insert(t);
}
}
DEBUG_PRINTF("removing vertex %u\n", g[dotV].index);
DEBUG_PRINTF("removing vertex %zu\n", g[dotV].index);
dead.insert(dotV);
clear_vertex(dotV, g);
compUnanchoredStarts.erase(dotV);
@@ -416,7 +417,7 @@ bool gatherParticipants(const NGHolder &g,
if (isOptionalDot(t, v, g)) {
// another dot; bail if we've seen it once already
if (dots.find(t) != dots.end()) {
DEBUG_PRINTF("cycle detected at vertex %u\n", g[t].index);
DEBUG_PRINTF("cycle detected at vertex %zu\n", g[t].index);
return false;
}
dots.insert(t);
@@ -432,7 +433,7 @@ bool gatherParticipants(const NGHolder &g,
for (auto w : adjacent_vertices_range(v, g)) {
succ.insert(w);
if (!edge(start, w, g).second) {
DEBUG_PRINTF("failing, vertex %u does not have edge from start\n",
DEBUG_PRINTF("failing, vertex %zu does not have edge from start\n",
g[w].index);
return false;
}
@@ -474,7 +475,7 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
return;
}
initialDot = v;
DEBUG_PRINTF("initial dot vertex is %u\n", g[v].index);
DEBUG_PRINTF("initial dot vertex is %zu\n", g[v].index);
}
}
@@ -507,12 +508,8 @@ void collapseVariableDotRepeat(NGHolder &g, NFAVertex start,
}
assert(startEnd->is_reachable());
// For determinism, copy and sort our successor vertices.
deque<NFAVertex> s(succ.begin(), succ.end());
sort(s.begin(), s.end(), make_index_ordering(g));
// Connect our successor vertices to both start and startDs.
for (auto v : s) {
for (auto v : succ) {
add_edge_if_not_present(g.start, v, g);
add_edge_if_not_present(g.startDs, v, g);
}
@@ -637,8 +634,8 @@ void restoreLeadingDots(NGHolder &g, const depth &startBegin,
}
addDotsBetween(g, root, rhs, startBegin, startEnd);
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
}
// Entry point.

View File

@@ -101,7 +101,7 @@ vector<NFAEdge> getAsserts(const NGHolder &g) {
static
void addToSplit(const NGHolder &g, NFAVertex v, map<u32, NFAVertex> *to_split) {
DEBUG_PRINTF("%u needs splitting\n", g[v].index);
DEBUG_PRINTF("%zu needs splitting\n", g[v].index);
to_split->emplace(g[v].index, v);
}
@@ -194,7 +194,7 @@ void setReportId(ReportManager &rm, NGWrapper &g, NFAVertex v, s32 adj) {
Report ir = rm.getBasicInternalReport(g, adj);
g[v].reports.insert(rm.getInternalId(ir));
DEBUG_PRINTF("set report id for vertex %u, adj %d\n", g[v].index, adj);
DEBUG_PRINTF("set report id for vertex %zu, adj %d\n", g[v].index, adj);
}
static
@@ -224,7 +224,7 @@ void splitVertex(ReportManager &rm, NGWrapper &g, NFAVertex v, bool ucp) {
assert(v != g.start);
assert(v != g.accept);
assert(v != g.acceptEod);
DEBUG_PRINTF("partitioning vertex %u ucp:%d\n", g[v].index, (int)ucp);
DEBUG_PRINTF("partitioning vertex %zu ucp:%d\n", g[v].index, (int)ucp);
CharReach cr_word = ucp ? CHARREACH_WORD_UCP_PRE : CHARREACH_WORD;
CharReach cr_nonword = ucp ? CHARREACH_NONWORD_UCP_PRE : CHARREACH_NONWORD;
@@ -267,8 +267,8 @@ void resolveEdges(ReportManager &rm, NGWrapper &g, set<NFAEdge> *dead) {
bool impassable = true;
bool ucp = flags & UCP_ASSERT_FLAGS;
DEBUG_PRINTF("resolving edge %u->%u (flags=0x%x, ucp=%d)\n", g[u].index,
g[v].index, flags, (int)ucp);
DEBUG_PRINTF("resolving edge %zu->%zu (flags=0x%x, ucp=%d)\n",
g[u].index, g[v].index, flags, (int)ucp);
while (flags && impassable) {
u32 flag = 1U << findAndClearLSB_32(&flags);
switch (flag) {
@@ -482,12 +482,12 @@ void resolveAsserts(ReportManager &rm, NGWrapper &g) {
resolveEdges(rm, g, &dead);
remove_edges(dead, g);
g.renumberVertices();
renumber_vertices(g);
pruneUseless(g);
pruneEmptyVertices(g);
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
clearReports(g);
}
@@ -552,7 +552,7 @@ void ensureCodePointStart(ReportManager &rm, NGWrapper &g) {
add_edge(g.start, v_4, g);
add_edge(g.startDs, v_4, g);
remove_edge(orig, g);
g.renumberEdges();
renumber_edges(g);
clearReports(g);
}
}

View File

@@ -132,7 +132,7 @@ NFAVertex NFABuilderImpl::getVertex(Position pos) const {
assert(id2vertex.size() >= pos);
const NFAVertex v = id2vertex[pos];
assert(v != NGHolder::null_vertex());
assert(graph->g[v].index == pos);
assert((*graph)[v].index == pos);
return v;
}
@@ -147,7 +147,7 @@ void NFABuilderImpl::addVertex(Position pos) {
id2vertex.resize(pos + 1);
}
id2vertex[pos] = v;
graph->g[v].index = pos;
(*graph)[v].index = pos;
}
unique_ptr<NGWrapper> NFABuilderImpl::getGraph() {
@@ -177,22 +177,22 @@ void NFABuilderImpl::setNodeReportID(Position pos, int offsetAdjust) {
void NFABuilderImpl::addCharReach(Position pos, const CharReach &cr) {
NFAVertex v = getVertex(pos);
graph->g[v].char_reach |= cr;
(*graph)[v].char_reach |= cr;
}
void NFABuilderImpl::setAssertFlag(Position pos, u32 flag) {
NFAVertex v = getVertex(pos);
graph->g[v].assert_flags |= flag;
(*graph)[v].assert_flags |= flag;
}
u32 NFABuilderImpl::getAssertFlag(Position pos) {
NFAVertex v = getVertex(pos);
return graph->g[v].assert_flags;
return (*graph)[v].assert_flags;
}
pair<NFAEdge, bool> NFABuilderImpl::addEdge(NFAVertex u, NFAVertex v) {
// assert that the edge doesn't already exist
assert(edge(u, v, graph->g).second == false);
assert(edge(u, v, *graph).second == false);
pair<NFAEdge, bool> e = add_edge(u, v, *graph);
assert(e.second);
@@ -209,16 +209,16 @@ void NFABuilderImpl::addEdge(Position startPos, Position endPos) {
if ((u == graph->start || u == graph->startDs) && v == graph->startDs) {
/* standard special -> special edges already exist */
assert(edge(u, v, graph->g).second == true);
assert(edge(u, v, *graph).second == true);
return;
}
assert(edge(u, v, graph->g).second == false);
assert(edge(u, v, *graph).second == false);
addEdge(u, v);
}
bool NFABuilderImpl::hasEdge(Position startPos, Position endPos) const {
return edge(getVertex(startPos), getVertex(endPos), graph->g).second;
return edge(getVertex(startPos), getVertex(endPos), *graph).second;
}
Position NFABuilderImpl::getStart() const {
@@ -252,7 +252,7 @@ Position NFABuilderImpl::makePositions(size_t nPositions) {
}
void NFABuilderImpl::cloneRegion(Position first, Position last, unsigned posOffset) {
NFAGraph &g = graph->g;
NGHolder &g = *graph;
assert(posOffset > 0);
// walk the nodes between first and last and copy their vertex properties

View File

@@ -162,7 +162,7 @@ flat_set<NFAVertex> findHeadShell(const NGHolder &g,
}
for (UNUSED auto v : shell) {
DEBUG_PRINTF("shell: %u\n", g[v].index);
DEBUG_PRINTF("shell: %zu\n", g[v].index);
}
return shell;
@@ -184,7 +184,7 @@ flat_set<NFAVertex> findTailShell(const NGHolder &g,
}
for (UNUSED auto v : shell) {
DEBUG_PRINTF("shell: %u\n", g[v].index);
DEBUG_PRINTF("shell: %zu\n", g[v].index);
}
return shell;
@@ -209,7 +209,8 @@ vector<NFAEdge> findShellEdges(const NGHolder &g,
if ((is_special(u, g) || contains(head_shell, u)) &&
(is_special(v, g) || contains(tail_shell, v))) {
DEBUG_PRINTF("edge (%u,%u) is a shell edge\n", g[u].index, g[v].index);
DEBUG_PRINTF("edge (%zu,%zu) is a shell edge\n", g[u].index,
g[v].index);
shell_edges.push_back(e);
}
}
@@ -275,9 +276,8 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
NFAUndirectedGraph ug;
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> old2new;
ue2::unordered_map<u32, NFAVertex> newIdx2old;
createUnGraph(g.g, true, true, ug, old2new, newIdx2old);
createUnGraph(g, true, true, ug, old2new);
// Construct reverse mapping.
ue2::unordered_map<NFAUndirectedVertex, NFAVertex> new2old;
@@ -313,7 +313,7 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
assert(contains(new2old, uv));
NFAVertex v = new2old.at(uv);
verts[c].push_back(v);
DEBUG_PRINTF("vertex %u is in comp %u\n", g[v].index, c);
DEBUG_PRINTF("vertex %zu is in comp %u\n", g[v].index, c);
}
ue2::unordered_map<NFAVertex, NFAVertex> v_map; // temp map for fillHolder
@@ -322,8 +322,9 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
vv.insert(vv.end(), begin(head_shell), end(head_shell));
vv.insert(vv.end(), begin(tail_shell), end(tail_shell));
// Sort by vertex index for determinism.
sort(begin(vv), end(vv), VertexIndexOrdering<NGHolder>(g));
/* Sort for determinism. Still required as NFAUndirectedVertex have
* no deterministic ordering (split_components map). */
sort(begin(vv), end(vv));
auto gc = ue2::make_unique<NGHolder>();
v_map.clear();
@@ -349,9 +350,6 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
vv.insert(vv.end(), begin(head_shell), end(head_shell));
vv.insert(vv.end(), begin(tail_shell), end(tail_shell));
// Sort by vertex index for determinism.
sort(begin(vv), end(vv), VertexIndexOrdering<NGHolder>(g));
auto gc = ue2::make_unique<NGHolder>();
v_map.clear();
fillHolder(gc.get(), g, vv, &v_map);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -99,7 +99,7 @@ class SearchVisitor : public boost::default_dfs_visitor {
template<class Vertex, class Graph>
void discover_vertex(const Vertex &v, const Graph &g) const {
DEBUG_PRINTF("vertex %u\n", g[v].index);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
if (is_special(v, g)) {
DEBUG_PRINTF("start or accept\n");
throw SearchFailed();
@@ -141,24 +141,16 @@ bool searchForward(const Graph &g, const CharReach &reach,
}
static
NFAEdge to_raw(const NFAEdge &e, const NFAGraph &, const NGHolder &) {
NFAEdge to_raw(const NFAEdge &e, const NGHolder &) {
return e;
}
static
NFAEdge to_raw(const reverse_graph<NFAGraph, NFAGraph&>::edge_descriptor &e,
const reverse_graph<NFAGraph, NFAGraph&> &g,
const NGHolder &raw) {
/* clang doesn't seem to like edge_underlying */
NFAVertex t = source(e, g);
NFAVertex s = target(e, g);
assert(edge(s, t, raw).second);
return edge(s, t, raw).first;
NFAEdge to_raw(const reverse_graph<NGHolder, NGHolder &>::edge_descriptor &e,
const reverse_graph<NGHolder, NGHolder &> &g) {
return get(boost::edge_underlying, g, e);
}
/* returns true if we did stuff */
template<class Graph>
static
@@ -185,7 +177,7 @@ bool removeCyclicPathRedundancy(Graph &g, typename Graph::vertex_descriptor v,
continue;
}
DEBUG_PRINTF("- checking u %u\n", g[u].index);
DEBUG_PRINTF("- checking u %zu\n", g[u].index);
// let s be intersection(succ(u), succ(v))
s.clear();
@@ -206,17 +198,18 @@ bool removeCyclicPathRedundancy(Graph &g, typename Graph::vertex_descriptor v,
continue;
}
DEBUG_PRINTF(" - checking w %u\n", g[w].index);
DEBUG_PRINTF(" - checking w %zu\n", g[w].index);
if (searchForward(g, reach, s, w)) {
DEBUG_PRINTF("removing edge (%u,%u)\n",
g[u].index, g[w].index);
/* we are currently iterating over the in-edges of v, so it
would be unwise to remove edges to v. However, */
assert(w != v); /* as v is in s */
remove_edge(to_raw(e_u, g, raw), raw);
did_stuff = true;
if (!searchForward(g, reach, s, w)) {
continue;
}
DEBUG_PRINTF("removing edge (%zu,%zu)\n", g[u].index, g[w].index);
/* we are currently iterating over the in-edges of v, so it
would be unwise to remove edges to v. However, */
assert(w != v); /* as v is in s */
remove_edge(to_raw(e_u, g), raw);
did_stuff = true;
}
}
@@ -233,7 +226,7 @@ bool cyclicPathRedundancyPass(Graph &g, NGHolder &raw) {
continue;
}
DEBUG_PRINTF("examining cyclic vertex %u\n", g[v].index);
DEBUG_PRINTF("examining cyclic vertex %zu\n", g[v].index);
did_stuff |= removeCyclicPathRedundancy(g, v, raw);
}
@@ -242,7 +235,7 @@ bool cyclicPathRedundancyPass(Graph &g, NGHolder &raw) {
bool removeCyclicPathRedundancy(NGHolder &g) {
// Forward pass.
bool f_changed = cyclicPathRedundancyPass(g.g, g);
bool f_changed = cyclicPathRedundancyPass(g, g);
if (f_changed) {
DEBUG_PRINTF("edges removed by forward pass\n");
pruneUseless(g);
@@ -250,8 +243,8 @@ bool removeCyclicPathRedundancy(NGHolder &g) {
// Reverse pass.
DEBUG_PRINTF("REVERSE PASS\n");
typedef reverse_graph<NFAGraph, NFAGraph&> RevGraph;
RevGraph revg(g.g);
typedef reverse_graph<NGHolder, NGHolder &> RevGraph;
RevGraph revg(g);
bool r_changed = cyclicPathRedundancyPass(revg, g);
if (r_changed) {
DEBUG_PRINTF("edges removed by reverse pass\n");

View File

@@ -44,11 +44,14 @@
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/topological_sort.hpp>
#include <boost/graph/property_maps/constant_property_map.hpp>
#include <boost/range/adaptor/reversed.hpp>
using namespace std;
using boost::filtered_graph;
using boost::make_filtered_graph;
using boost::make_constant_property;
using boost::reverse_graph;
using boost::adaptors::reverse;
namespace ue2 {
@@ -122,25 +125,23 @@ private:
template<class GraphT>
static
void findLoopReachable(const GraphT &g, const NFAVertex srcVertex,
void findLoopReachable(const GraphT &g,
const typename GraphT::vertex_descriptor srcVertex,
vector<bool> &deadNodes) {
typedef typename GraphT::edge_descriptor EdgeT;
typedef typename GraphT::vertex_descriptor VertexT;
typedef set<EdgeT> EdgeSet;
EdgeSet deadEdges;
BackEdges<EdgeSet> be(deadEdges);
auto index_map = get(&NFAGraphVertexProps::index, g);
depth_first_search(g, visitor(be).root_vertex(srcVertex).vertex_index_map(
index_map));
depth_first_search(g, visitor(be).root_vertex(srcVertex));
auto af = make_bad_edge_filter(&deadEdges);
auto acyclic_g = make_filtered_graph(g, af);
vector<NFAVertex> topoOrder; /* actually reverse topological order */
vector<VertexT> topoOrder; /* actually reverse topological order */
topoOrder.reserve(deadNodes.size());
topological_sort(acyclic_g, back_inserter(topoOrder),
vertex_index_map(index_map));
topological_sort(acyclic_g, back_inserter(topoOrder));
for (const auto &e : deadEdges) {
u32 srcIdx = g[source(e, g)].index;
@@ -149,8 +150,7 @@ void findLoopReachable(const GraphT &g, const NFAVertex srcVertex,
}
}
for (auto it = topoOrder.rbegin(); it != topoOrder.rend(); ++it) {
NFAVertex v = *it;
for (VertexT v : reverse(topoOrder)) {
for (const auto &e : in_edges_range(v, g)) {
if (deadNodes[g[source(e, g)].index]) {
deadNodes[g[v].index] = true;
@@ -194,22 +194,20 @@ void calcDepthFromSource(const NGHolder &graph, const GraphT &g,
using boost::make_iterator_property_map;
auto min_index_map = get(&NFAGraphVertexProps::index, mindist_g);
auto min_index_map = get(vertex_index, mindist_g);
breadth_first_search(mindist_g, srcVertex,
boost::vertex_index_map(min_index_map).
visitor(make_bfs_visitor(record_distances(
make_iterator_property_map(
dMin.begin(), min_index_map),
make_iterator_property_map(dMin.begin(),
min_index_map),
boost::on_tree_edge()))));
auto max_index_map = get(&NFAGraphVertexProps::index, maxdist_g);
auto max_index_map = get(vertex_index, maxdist_g);
dag_shortest_paths(maxdist_g, srcVertex,
boost::vertex_index_map(max_index_map).
distance_map(make_iterator_property_map(dMax.begin(),
max_index_map)).
weight_map(make_constant_property<EdgeT>(-1)));
distance_map(make_iterator_property_map(dMax.begin(),
max_index_map))
.weight_map(make_constant_property<EdgeT>(-1)));
for (size_t i = 0; i < numVerts; i++) {
if (dMin[i] > DIST_UNREACHABLE) {
@@ -285,14 +283,14 @@ void calcDepths(const NGHolder &g, std::vector<NFAVertexDepth> &depths) {
* reachable from a loop need to be removed
*/
vector<bool> deadNodes(numVertices);
findLoopReachable(g.g, g.start, deadNodes);
findLoopReachable(g, g.start, deadNodes);
DEBUG_PRINTF("doing start\n");
calcAndStoreDepth(g, g.g, g.start, deadNodes, dMin, dMax,
depths, &NFAVertexDepth::fromStart);
calcAndStoreDepth(g, g, g.start, deadNodes, dMin, dMax, depths,
&NFAVertexDepth::fromStart);
DEBUG_PRINTF("doing startds\n");
calcAndStoreDepth(g, g.g, g.startDs, deadNodes, dMin, dMax,
depths, &NFAVertexDepth::fromStartDotStar);
calcAndStoreDepth(g, g, g.startDs, deadNodes, dMin, dMax, depths,
&NFAVertexDepth::fromStartDotStar);
}
void calcDepths(const NGHolder &g, std::vector<NFAVertexRevDepth> &depths) {
@@ -305,8 +303,8 @@ void calcDepths(const NGHolder &g, std::vector<NFAVertexRevDepth> &depths) {
vector<int> dMax;
/* reverse the graph before walking it */
typedef reverse_graph<NFAGraph, const NFAGraph&> RevNFAGraph;
const RevNFAGraph rg(g.g);
typedef reverse_graph<NGHolder, const NGHolder &> RevNFAGraph;
const RevNFAGraph rg(g);
/*
* create a filtered graph for max depth calculations: all nodes/edges
@@ -340,20 +338,20 @@ void calcDepths(const NGHolder &g, vector<NFAVertexBidiDepth> &depths) {
* reachable from a loop need to be removed
*/
vector<bool> deadNodes(numVertices);
findLoopReachable(g.g, g.start, deadNodes);
findLoopReachable(g, g.start, deadNodes);
DEBUG_PRINTF("doing start\n");
calcAndStoreDepth<NFAGraph, NFAVertexBidiDepth>(
g, g.g, g.start, deadNodes, dMin, dMax, depths,
calcAndStoreDepth<NGHolder, NFAVertexBidiDepth>(
g, g, g.start, deadNodes, dMin, dMax, depths,
&NFAVertexBidiDepth::fromStart);
DEBUG_PRINTF("doing startds\n");
calcAndStoreDepth<NFAGraph, NFAVertexBidiDepth>(
g, g.g, g.startDs, deadNodes, dMin, dMax, depths,
calcAndStoreDepth<NGHolder, NFAVertexBidiDepth>(
g, g, g.startDs, deadNodes, dMin, dMax, depths,
&NFAVertexBidiDepth::fromStartDotStar);
/* Now go backwards */
typedef reverse_graph<NFAGraph, const NFAGraph&> RevNFAGraph;
const RevNFAGraph rg(g.g);
typedef reverse_graph<NGHolder, const NGHolder &> RevNFAGraph;
const RevNFAGraph rg(g);
deadNodes.assign(numVertices, false);
findLoopReachable(rg, g.acceptEod, deadNodes);
@@ -374,10 +372,10 @@ void calcDepthsFrom(const NGHolder &g, const NFAVertex src,
const size_t numVertices = num_vertices(g);
vector<bool> deadNodes(numVertices);
findLoopReachable(g.g, g.start, deadNodes);
findLoopReachable(g, g.start, deadNodes);
vector<int> dMin, dMax;
calcDepthFromSource(g, g.g, src, deadNodes, dMin, dMax);
calcDepthFromSource(g, g, src, deadNodes, dMin, dMax);
depths.clear();
depths.resize(numVertices);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-16, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -48,37 +48,45 @@ using boost::make_iterator_property_map;
namespace ue2 {
template <class Graph>
ue2::unordered_map<NFAVertex, NFAVertex> calcDominators(const Graph &g,
NFAVertex source) {
unordered_map<NFAVertex, NFAVertex> calcDominators(const Graph &g,
typename Graph::vertex_descriptor source) {
using Vertex = typename Graph::vertex_descriptor;
const size_t num_verts = num_vertices(g);
auto index_map = get(&NFAGraphVertexProps::index, g);
vector<size_t> dfnum(num_verts, 0);
vector<NFAVertex> parents(num_verts, Graph::null_vertex());
vector<Vertex> parents(num_verts, Graph::null_vertex());
auto dfnum_map = make_iterator_property_map(dfnum.begin(), index_map);
auto parent_map = make_iterator_property_map(parents.begin(), index_map);
vector<NFAVertex> vertices_by_dfnum(num_verts, Graph::null_vertex());
vector<Vertex> vertices_by_dfnum(num_verts, Graph::null_vertex());
// Output map.
unordered_map<NFAVertex, NFAVertex> doms;
unordered_map<Vertex, Vertex> doms;
auto dom_map = make_assoc_property_map(doms);
boost_ue2::lengauer_tarjan_dominator_tree(g, source, index_map, dfnum_map,
parent_map, vertices_by_dfnum,
dom_map);
return doms;
/* Translate back to an NFAVertex map */
unordered_map<NFAVertex, NFAVertex> doms2;
for (const auto &e : doms) {
NFAVertex f(e.first);
NFAVertex s(e.second);
doms2[f] = s;
}
return doms2;
}
ue2::unordered_map<NFAVertex, NFAVertex> findDominators(const NGHolder &g) {
unordered_map<NFAVertex, NFAVertex> findDominators(const NGHolder &g) {
assert(hasCorrectlyNumberedVertices(g));
return calcDominators(g.g, g.start);
return calcDominators(g, g.start);
}
ue2::unordered_map<NFAVertex, NFAVertex> findPostDominators(const NGHolder &g) {
unordered_map<NFAVertex, NFAVertex> findPostDominators(const NGHolder &g) {
assert(hasCorrectlyNumberedVertices(g));
return calcDominators(boost::reverse_graph<NFAGraph, const NFAGraph &>(g.g),
return calcDominators(boost::reverse_graph<NGHolder, const NGHolder &>(g),
g.acceptEod);
}

View File

@@ -285,7 +285,7 @@ void dumpGraphImpl(const char *name, const GraphT &g,
}
// manual instantiation of templated dumpGraph above.
template void dumpGraphImpl(const char *, const NFAGraph &);
template void dumpGraphImpl(const char *, const NGHolder &);
void dumpDotWrapperImpl(const NGWrapper &nw, const char *name,
const Grey &grey) {
@@ -293,7 +293,7 @@ void dumpDotWrapperImpl(const NGWrapper &nw, const char *name,
stringstream ss;
ss << grey.dumpPath << "Expr_" << nw.expressionIndex << "_" << name << ".dot";
DEBUG_PRINTF("dumping dot graph to '%s'\n", ss.str().c_str());
dumpGraphImpl(ss.str().c_str(), nw.g);
dumpGraphImpl(ss.str().c_str(), nw);
}
}
@@ -304,7 +304,7 @@ void dumpComponentImpl(const NGHolder &g, const char *name, u32 expr,
ss << grey.dumpPath << "Comp_" << expr << "-" << comp << "_"
<< name << ".dot";
DEBUG_PRINTF("dumping dot graph to '%s'\n", ss.str().c_str());
dumpGraphImpl(ss.str().c_str(), g.g);
dumpGraphImpl(ss.str().c_str(), g);
}
}
@@ -315,7 +315,7 @@ void dumpSomSubComponentImpl(const NGHolder &g, const char *name, u32 expr,
ss << grey.dumpPath << "Comp_" << expr << "-" << comp << "_"
<< name << "_" << plan << ".dot";
DEBUG_PRINTF("dumping dot graph to '%s'\n", ss.str().c_str());
dumpGraphImpl(ss.str().c_str(), g.g);
dumpGraphImpl(ss.str().c_str(), g);
}
}
@@ -325,7 +325,7 @@ void dumpHolderImpl(const NGHolder &h, unsigned int stageNumber,
stringstream ss;
ss << grey.dumpPath << "Holder_X_" << stageNumber
<< "-" << stageName << ".dot";
dumpGraphImpl(ss.str().c_str(), h.g);
dumpGraphImpl(ss.str().c_str(), h);
}
}
@@ -337,7 +337,7 @@ void dumpHolderImpl(const NGHolder &h,
stringstream ss;
ss << grey.dumpPath << "Holder_X_" << stageNumber
<< "-" << stageName << ".dot";
dumpGraphImpl(ss.str().c_str(), h.g, region_map);
dumpGraphImpl(ss.str().c_str(), h, region_map);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -297,9 +297,8 @@ bool checkFwdCandidate(const NGHolder &g, NFAVertex fixed_src,
return false;
}
DEBUG_PRINTF("edge (%u, %u) killed by edge (%u, %u)\n",
g[w].index, g[v].index,
g[fixed_src].index, g[v].index);
DEBUG_PRINTF("edge (%zu, %zu) killed by edge (%zu, %zu)\n",
g[w].index, g[v].index, g[fixed_src].index, g[v].index);
return true;
}
@@ -415,7 +414,7 @@ bool removeEdgeRedundancyFwd(NGHolder &g, bool ignore_starts) {
pred(g, u, &parents_u);
done.clear();
if (hasGreaterOutDegree(1, u, g)) {
if (out_degree(u, g) > 1) {
checkLargeOutU(g, u, parents_u, possible_w, done, &dead);
} else {
checkSmallOutU(g, u, parents_u, done, &dead);
@@ -460,7 +459,7 @@ bool removeSiblingsOfStartDotStar(NGHolder &g) {
vector<NFAEdge> dead;
for (auto v : adjacent_vertices_range(g.startDs, g)) {
DEBUG_PRINTF("checking %u\n", g[v].index);
DEBUG_PRINTF("checking %zu\n", g[v].index);
if (is_special(v, g)) {
continue;
}
@@ -470,8 +469,7 @@ bool removeSiblingsOfStartDotStar(NGHolder &g) {
if (is_special(u, g)) {
continue;
}
DEBUG_PRINTF("removing %u->%u\n", g[u].index,
g[v].index);
DEBUG_PRINTF("removing %zu->%zu\n", g[u].index, g[v].index);
dead.push_back(e);
}
}

View File

@@ -77,7 +77,7 @@ public:
flat_set<VertexInfo *, VertexInfoPtrCmp> pred; //!< predecessors of this vertex
flat_set<VertexInfo *, VertexInfoPtrCmp> succ; //!< successors of this vertex
NFAVertex v;
u32 vert_index;
size_t vert_index;
CharReach cr;
CharReach pred_cr;
CharReach succ_cr;
@@ -122,7 +122,7 @@ public:
vertex_flags(vi.vertex_flags), edge_tops(vi.edge_tops), cr(vi.cr),
adjacent_cr(eq == LEFT_EQUIVALENCE ? vi.pred_cr : vi.succ_cr),
/* treat non-special vertices the same */
node_type(min(g[vi.v].index, u32{N_SPECIALS})), depth(d_in) {}
node_type(min(g[vi.v].index, size_t{N_SPECIALS})), depth(d_in) {}
bool operator==(const ClassInfo &b) const {
return node_type == b.node_type && depth.d1 == b.depth.d1 &&
@@ -678,7 +678,7 @@ bool reduceGraphEquivalences(NGHolder &g, const CompileContext &cc) {
DEBUG_PRINTF("equivalence processing disabled in grey box\n");
return false;
}
g.renumberVertices();
renumber_vertices(g);
// Cheap check: if all the non-special vertices have in-degree one and
// out-degree one, there's no redundancy in this here graph and we can

View File

@@ -183,8 +183,6 @@ flat_set<NFAVertex> execute_graph(const NGHolder &g,
return getVertices(work_states, info);
}
typedef boost::reverse_graph<const NFAGraph, const NFAGraph &> RevNFAGraph;
namespace {
class eg_visitor : public boost::default_dfs_visitor {
public:
@@ -195,13 +193,14 @@ public:
info(info_in), input_g(input_g_in), states(states_in),
succs(vertex_count) {}
void finish_vertex(NFAVertex input_v, const RevNFAGraph &) {
void finish_vertex(NFAVertex input_v,
const boost::reverse_graph<NGHolder, const NGHolder &> &) {
if (input_v == input_g.accept) {
return;
}
assert(input_v != input_g.acceptEod);
DEBUG_PRINTF("finished p%u\n", input_g[input_v].index);
DEBUG_PRINTF("finished p%zu\n", input_g[input_v].index);
/* finish vertex is called on vertex --> implies that all its parents
* (in the forward graph) are also finished. Our parents will have
@@ -236,7 +235,7 @@ public:
/* we need to push into all our (forward) children their successors
* from us. */
for (auto v : adjacent_vertices_range(input_v, input_g)) {
DEBUG_PRINTF("pushing our states to pstate %u\n",
DEBUG_PRINTF("pushing our states to pstate %zu\n",
input_g[v].index);
if (v == input_g.startDs) {
/* no need for intra start edges */
@@ -289,7 +288,7 @@ flat_set<NFAVertex> execute_graph(const NGHolder &running_g,
map<NFAVertex, boost::default_color_type> colours;
/* could just a topo order, but really it is time to pull a slightly bigger
* gun: DFS */
RevNFAGraph revg(input_dag.g);
boost::reverse_graph<NGHolder, const NGHolder &> revg(input_dag);
map<NFAVertex, dynamic_bitset<> > dfs_states;
auto info = makeInfoTable(running_g);
@@ -308,7 +307,7 @@ flat_set<NFAVertex> execute_graph(const NGHolder &running_g,
#ifdef DEBUG
DEBUG_PRINTF(" output rstates:");
for (const auto &v : states) {
printf(" %u", running_g[v].index);
printf(" %zu", running_g[v].index);
}
printf("\n");
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -118,7 +118,7 @@ void checkVertex(const ReportManager &rm, const NGWrapper &w, NFAVertex v,
rd.max = min(rd.max, max_offset);
}
DEBUG_PRINTF("vertex %u report %u: %s\n", w[v].index, report_id,
DEBUG_PRINTF("vertex %zu report %u: %s\n", w[v].index, report_id,
rd.str().c_str());
info = unionDepthMinMax(info, rd);

View File

@@ -172,8 +172,7 @@ void updateReportBounds(ReportManager &rm, NGWrapper &g, NFAVertex accept,
new_reports.insert(rm.getInternalId(ir));
}
DEBUG_PRINTF("swapping reports on vertex %u\n",
g[v].index);
DEBUG_PRINTF("swapping reports on vertex %zu\n", g[v].index);
reports.swap(new_reports);
}
}
@@ -286,8 +285,8 @@ bool anchorPatternWithBoundedRepeat(NGWrapper &g, const depth &minWidth,
add_edge(u, v, g);
}
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
return true;
}
@@ -309,7 +308,7 @@ NFAVertex findSingleCyclic(const NGHolder &g) {
}
if (v != NGHolder::null_vertex()) {
DEBUG_PRINTF("cyclic is %u\n", g[v].index);
DEBUG_PRINTF("cyclic is %zu\n", g[v].index);
assert(!is_special(v, g));
}
return v;
@@ -380,7 +379,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
// Walk from the start vertex to the cyclic state and ensure we have a
// chain of vertices.
while (v != cyclic) {
DEBUG_PRINTF("vertex %u\n", g[v].index);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
width++;
auto succ = succs(v, g);
if (contains(succ, cyclic)) {
@@ -418,7 +417,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
// Walk from the cyclic state to an accept and ensure we have a chain of
// vertices.
while (!is_any_accept(v, g)) {
DEBUG_PRINTF("vertex %u\n", g[v].index);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
width++;
auto succ = succs(v, g);
if (succ.size() != 1) {
@@ -435,7 +434,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
DEBUG_PRINTF("adjusting width by %d\n", offsetAdjust);
width += offsetAdjust;
DEBUG_PRINTF("width=%u, vertex %u is cyclic\n", width,
DEBUG_PRINTF("width=%u, vertex %zu is cyclic\n", width,
g[cyclic].index);
if (width >= g.min_length) {
@@ -448,7 +447,7 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
vector<NFAVertex> preds;
vector<NFAEdge> dead;
for (auto u : inv_adjacent_vertices_range(cyclic, g)) {
DEBUG_PRINTF("pred %u\n", g[u].index);
DEBUG_PRINTF("pred %zu\n", g[u].index);
if (u == cyclic) {
continue;
}
@@ -484,8 +483,8 @@ bool transformMinLengthToRepeat(const ReportManager &rm, NGWrapper &g) {
add_edge(u, cyclic, g);
}
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
clearReports(g);
g.min_length = 0;
@@ -542,8 +541,7 @@ bool isEdgePrunable(const NGWrapper &g,
const NFAVertex u = source(e, g);
const NFAVertex v = target(e, g);
DEBUG_PRINTF("edge (%u,%u)\n", g[u].index,
g[v].index);
DEBUG_PRINTF("edge (%zu,%zu)\n", g[u].index, g[v].index);
// Leave our special-to-special edges alone.
if (is_special(u, g) && is_special(v, g)) {
@@ -716,8 +714,7 @@ static
bool isUnanchored(const NGHolder &g) {
for (auto v : adjacent_vertices_range(g.start, g)) {
if (!edge(g.startDs, v, g).second) {
DEBUG_PRINTF("fail, %u is anchored vertex\n",
g[v].index);
DEBUG_PRINTF("fail, %zu is anchored vertex\n", g[v].index);
return false;
}
}
@@ -862,7 +859,7 @@ void handleExtendedParams(ReportManager &rm, NGWrapper &g,
}
}
}
//dumpGraph("final.dot", g.g);
//dumpGraph("final.dot", g);
if (!hasExtParams(g)) {
return;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -77,7 +77,7 @@ bool findMask(const NGHolder &g, vector<CharReach> *mask, bool *anchored,
NFAVertex v = *succs.begin();
while (true) {
DEBUG_PRINTF("validating vertex %u\n", g[v].index);
DEBUG_PRINTF("validating vertex %zu\n", g[v].index);
assert(v != g.acceptEod);

View File

@@ -1,114 +0,0 @@
/*
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/** \file
* \brief Definition of the NFAGraph type used for all NFA graph
* representations.
*
* Note that most of the time we don't work on a bare NFAGraph: instead
* we use an NGHolder, which wraps the graph and defines our special vertices,
* etc.
*/
#ifndef NG_GRAPH_H
#define NG_GRAPH_H
#include "util/charreach.h"
#include "util/ue2_containers.h"
#include "ue2common.h"
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
namespace ue2 {
/** \brief Properties associated with each vertex in an NFAGraph. */
struct NFAGraphVertexProps {
/** \brief Set of characters on which this vertex is reachable. */
CharReach char_reach;
/** \brief Set of reports raised by this vertex. */
ue2::flat_set<ReportID> reports;
/** \brief Unique index for this vertex, used for BGL algorithms. */
u32 index = 0;
/** \brief Flags associated with assertions. */
u32 assert_flags = 0;
};
/** \brief Properties associated with each edge in an NFAGraph. */
struct NFAGraphEdgeProps {
/** \brief Unique index for this edge, used for BGL algorithms. */
u32 index = 0;
/** \brief For graphs that will be implemented as multi-top engines, this
* specifies the top events. Only used on edges from the start vertex. */
ue2::flat_set<u32> tops;
/** \brief Flags associated with assertions. */
u32 assert_flags = 0;
};
// For flexibility: boost::listS, boost::listS for out-edge and vertex lists.
// boost::bidirectionalS for directed graph so that we can get at in-edges.
typedef boost::adjacency_list<boost::listS,
boost::listS,
boost::bidirectionalS,
NFAGraphVertexProps,
NFAGraphEdgeProps> NFAGraph;
typedef NFAGraph::vertex_descriptor NFAVertex;
typedef NFAGraph::edge_descriptor NFAEdge;
/** \brief vertex_index values for special nodes in the NFAGraph. */
enum SpecialNodes {
/** \brief Anchored start vertex. WARNING: this may be triggered at various
* locations (not just zero) for triggered graphs. */
NODE_START,
/** \brief Unanchored start-dotstar vertex. WARNING: this may not have a
* proper self-loop. */
NODE_START_DOTSTAR,
/** \brief Accept vertex. All vertices that can match at arbitrary offsets
* must have an edge to this vertex. */
NODE_ACCEPT,
/** \brief Accept-EOD vertex. Vertices that must raise a match at EOD only
* must have an edge to this vertex. */
NODE_ACCEPT_EOD,
/** \brief Sentinel, number of special vertices. */
N_SPECIALS
};
} // namespace ue2
#endif

View File

@@ -37,10 +37,10 @@
#include "ng_mcclellan_internal.h"
#include "ng_som_util.h"
#include "ng_squash.h"
#include "ng_util.h"
#include "util/bitfield.h"
#include "util/container.h"
#include "util/determinise.h"
#include "util/graph.h"
#include "util/graph_range.h"
#include "util/make_unique.h"
#include "util/ue2_containers.h"
@@ -449,7 +449,7 @@ void haig_do_preds(const NGHolder &g, const stateset &nfa_states,
NFAVertex v = state_mapping[i];
s32 slot_id = g[v].index;
DEBUG_PRINTF("d vertex %u\n", g[v].index);
DEBUG_PRINTF("d vertex %zu\n", g[v].index);
vector<u32> &out_map = preds[slot_id];
for (auto u : inv_adjacent_vertices_range(v, g)) {
out_map.push_back(g[u].index);
@@ -490,7 +490,7 @@ void haig_note_starts(const NGHolder &g, map<u32, u32> *out) {
for (auto v : vertices_range(g)) {
if (is_any_start_inc_virtual(v, g)) {
DEBUG_PRINTF("%u creates new som value\n", g[v].index);
DEBUG_PRINTF("%zu creates new som value\n", g[v].index);
out->emplace(g[v].index, 0U);
continue;
}
@@ -501,7 +501,7 @@ void haig_note_starts(const NGHolder &g, map<u32, u32> *out) {
const DepthMinMax &d = depths[g[v].index];
if (d.min == d.max && d.min.is_finite()) {
DEBUG_PRINTF("%u is fixed at %u\n", g[v].index, (u32)d.min);
DEBUG_PRINTF("%zu is fixed at %u\n", g[v].index, (u32)d.min);
out->emplace(g[v].index, d.min);
}
}

View File

@@ -36,123 +36,33 @@ using namespace std;
namespace ue2 {
// internal use only
static NFAVertex addSpecialVertex(NFAGraph &g, SpecialNodes id) {
NFAVertex v = add_vertex(g);
static NFAVertex addSpecialVertex(NGHolder &g, SpecialNodes id) {
NFAVertex v(add_vertex(g));
g[v].index = id;
return v;
}
NGHolder::NGHolder(void)
: g(),
// add initial special nodes
start(addSpecialVertex(g, NODE_START)),
startDs(addSpecialVertex(g, NODE_START_DOTSTAR)),
accept(addSpecialVertex(g, NODE_ACCEPT)),
acceptEod(addSpecialVertex(g, NODE_ACCEPT_EOD)),
// misc data
numVertices(N_SPECIALS),
numEdges(0),
isValidNumEdges(true),
isValidNumVertices(true) {
// wire up some fake edges for the stylized bits of the NFA
add_edge(start, startDs, *this);
add_edge(startDs, startDs, *this);
add_edge(accept, acceptEod, *this);
g[start].char_reach.setall();
g[startDs].char_reach.setall();
}
NGHolder::NGHolder(nfa_kind k)
: kind (k), g(),
: kind (k),
// add initial special nodes
start(addSpecialVertex(g, NODE_START)),
startDs(addSpecialVertex(g, NODE_START_DOTSTAR)),
accept(addSpecialVertex(g, NODE_ACCEPT)),
acceptEod(addSpecialVertex(g, NODE_ACCEPT_EOD)),
// misc data
numVertices(N_SPECIALS),
numEdges(0),
isValidNumEdges(true),
isValidNumVertices(true) {
start(addSpecialVertex(*this, NODE_START)),
startDs(addSpecialVertex(*this, NODE_START_DOTSTAR)),
accept(addSpecialVertex(*this, NODE_ACCEPT)),
acceptEod(addSpecialVertex(*this, NODE_ACCEPT_EOD)) {
// wire up some fake edges for the stylized bits of the NFA
add_edge(start, startDs, *this);
add_edge(startDs, startDs, *this);
add_edge(accept, acceptEod, *this);
g[start].char_reach.setall();
g[startDs].char_reach.setall();
(*this)[start].char_reach.setall();
(*this)[startDs].char_reach.setall();
}
NGHolder::~NGHolder(void) {
DEBUG_PRINTF("destroying holder @ %p\n", this);
}
size_t num_edges(NGHolder &h) {
if (!h.isValidNumEdges) {
h.numEdges = num_edges(h.g);
h.isValidNumEdges = true;
}
return h.numEdges;
}
size_t num_edges(const NGHolder &h) {
if (!h.isValidNumEdges) {
return num_edges(h.g);
}
return h.numEdges;
}
size_t num_vertices(NGHolder &h) {
if (!h.isValidNumVertices) {
h.numVertices = num_vertices(h.g);
h.isValidNumVertices = true;
}
return h.numVertices;
}
size_t num_vertices(const NGHolder &h) {
if (!h.isValidNumVertices) {
return num_vertices(h.g);
}
return h.numVertices;
}
void remove_edge(const NFAEdge &e, NGHolder &h) {
remove_edge(e, h.g);
assert(!h.isValidNumEdges || h.numEdges > 0);
h.numEdges--;
}
void remove_edge(NFAVertex u, NFAVertex v, NGHolder &h) {
remove_edge(u, v, h.g);
assert(!h.isValidNumEdges || h.numEdges > 0);
h.numEdges--;
}
void remove_vertex(NFAVertex v, NGHolder &h) {
remove_vertex(v, h.g);
assert(!h.isValidNumVertices || h.numVertices > 0);
h.numVertices--;
}
void clear_vertex(NFAVertex v, NGHolder &h) {
h.isValidNumEdges = false;
clear_vertex_faster(v, h.g);
}
void clear_in_edges(NFAVertex v, NGHolder &h) {
h.isValidNumEdges = false;
clear_in_edges(v, h.g);
}
void clear_out_edges(NFAVertex v, NGHolder &h) {
h.isValidNumEdges = false;
clear_out_edges(v, h.g);
}
void clear_graph(NGHolder &h) {
NGHolder::vertex_iterator vi, ve;
for (tie(vi, ve) = vertices(h); vi != ve;) {
@@ -166,6 +76,8 @@ void clear_graph(NGHolder &h) {
}
assert(num_vertices(h) == N_SPECIALS);
renumber_vertices(h); /* ensure that we reset our next allocated index */
renumber_edges(h);
// Recreate special stylised edges.
add_edge(h.start, h.startDs, h);
@@ -173,56 +85,13 @@ void clear_graph(NGHolder &h) {
add_edge(h.accept, h.acceptEod, h);
}
std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v, NGHolder &h) {
assert(edge(u, v, h.g).second == false);
pair<NFAEdge, bool> e = add_edge(u, v, h.g);
h.g[e.first].index = h.numEdges++;
assert(!h.isValidNumEdges || h.numEdges > 0); // no wrapping
return e;
}
std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v,
const NFAGraph::edge_property_type &ep,
NGHolder &h) {
assert(edge(u, v, h.g).second == false);
pair<NFAEdge, bool> e = add_edge(u, v, ep, h.g);
h.g[e.first].index = h.numEdges++;
assert(!h.isValidNumEdges || h.numEdges > 0); // no wrapping
return e;
}
NFAVertex add_vertex(NGHolder &h) {
NFAVertex v = add_vertex(h.g);
h[v].index = h.numVertices++;
assert(h.numVertices > 0); // no wrapping
return v;
}
NFAVertex add_vertex(const NFAGraph::vertex_property_type &vp, NGHolder &h) {
NFAVertex v = add_vertex(h);
u32 i = h.g[v].index; /* preserve index */
h.g[v] = vp;
h.g[v].index = i;
return v;
}
void NGHolder::renumberEdges() {
numEdges = renumberGraphEdges(g);
isValidNumEdges = true;
}
void NGHolder::renumberVertices() {
numVertices = renumberGraphVertices(g);
isValidNumVertices = true;
}
NFAVertex NGHolder::getSpecialVertex(u32 id) const {
switch (id) {
case NODE_START: return start;
case NODE_START_DOTSTAR: return startDs;
case NODE_ACCEPT: return accept;
case NODE_ACCEPT_EOD: return acceptEod;
default: return nullptr;
case NODE_START: return start;
case NODE_START_DOTSTAR: return startDs;
case NODE_ACCEPT: return accept;
case NODE_ACCEPT_EOD: return acceptEod;
default: return null_vertex();
}
}

View File

@@ -26,19 +26,75 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/** \file
* \brief Definition of the NGHolder type used for to represent general nfa
* graphs as well as all associated types (vertex and edge properties, etc).
*
* The NGHolder also contains the special vertices used to represents starts and
* accepts.
*/
#ifndef NG_HOLDER_H
#define NG_HOLDER_H
#include "ng_graph.h"
#include "ue2common.h"
#include "nfa/nfa_kind.h"
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include "util/charreach.h"
#include "util/ue2_containers.h"
#include "util/ue2_graph.h"
namespace ue2 {
/** \brief Properties associated with each vertex in an NFAGraph. */
struct NFAGraphVertexProps {
/** \brief Set of characters on which this vertex is reachable. */
CharReach char_reach;
/** \brief Set of reports raised by this vertex. */
flat_set<ReportID> reports;
/** \brief Unique index for this vertex, used for BGL algorithms. */
size_t index = 0;
/** \brief Flags associated with assertions. */
u32 assert_flags = 0;
};
/** \brief Properties associated with each edge in an NFAGraph. */
struct NFAGraphEdgeProps {
/** \brief Unique index for this edge, used for BGL algorithms. */
size_t index = 0;
/** \brief For graphs that will be implemented as multi-top engines, this
* specifies the top events. Only used on edges from the start vertex. */
ue2::flat_set<u32> tops;
/** \brief Flags associated with assertions. */
u32 assert_flags = 0;
};
/** \brief vertex_index values for special nodes in the NFAGraph. */
enum SpecialNodes {
/** \brief Anchored start vertex. WARNING: this may be triggered at various
* locations (not just zero) for triggered graphs. */
NODE_START,
/** \brief Unanchored start-dotstar vertex. WARNING: this may not have a
* proper self-loop. */
NODE_START_DOTSTAR,
/** \brief Accept vertex. All vertices that can match at arbitrary offsets
* must have an edge to this vertex. */
NODE_ACCEPT,
/** \brief Accept-EOD vertex. Vertices that must raise a match at EOD only
* must have an edge to this vertex. */
NODE_ACCEPT_EOD,
/** \brief Sentinel, number of special vertices. */
N_SPECIALS
};
/** \brief Encapsulates an NFAGraph, stores special vertices and other
* metadata.
*
@@ -49,188 +105,34 @@ namespace ue2 {
* - (startDs, startDs) (self-loop)
* - (accept, acceptEod)
*/
class NGHolder : boost::noncopyable {
class NGHolder : public ue2_graph<NGHolder, NFAGraphVertexProps,
NFAGraphEdgeProps> {
public:
NGHolder(void);
explicit NGHolder(nfa_kind kind);
NGHolder(void) : NGHolder(NFA_OUTFIX) {};
virtual ~NGHolder(void);
// Pack edge and vertex indices.
// Note: maintaining edge index order can be expensive due to the frequency
// of edge removal/addition, so only renumberEdges() when required by
// operations on edge lists.
void renumberEdges();
void renumberVertices();
nfa_kind kind; /* Role that this plays in Rose */
NFAVertex getSpecialVertex(u32 id) const;
static const size_t N_SPECIAL_VERTICES = N_SPECIALS;
public:
const vertex_descriptor start; //!< Anchored start vertex.
const vertex_descriptor startDs; //!< Unanchored start-dotstar vertex.
const vertex_descriptor accept; //!< Accept vertex.
const vertex_descriptor acceptEod; //!< Accept at EOD vertex.
nfa_kind kind = NFA_OUTFIX; /* Role that this plays in Rose */
/** \brief Underlying graph object */
NFAGraph g;
const NFAVertex start; //!< Anchored start vertex.
const NFAVertex startDs; //!< Unanchored start-dotstar vertex.
const NFAVertex accept; //!< Accept vertex.
const NFAVertex acceptEod; //!< Accept at EOD vertex.
using directed_category = NFAGraph::directed_category;
using edge_parallel_category = NFAGraph::edge_parallel_category;
using traversal_category = NFAGraph::traversal_category;
using vertex_descriptor = NFAGraph::vertex_descriptor;
using edge_descriptor = NFAGraph::edge_descriptor;
using adjacency_iterator = NFAGraph::adjacency_iterator;
using edge_iterator = NFAGraph::edge_iterator;
using in_edge_iterator = NFAGraph::in_edge_iterator;
using inv_adjacency_iterator = NFAGraph::inv_adjacency_iterator;
using out_edge_iterator = NFAGraph::out_edge_iterator;
using vertex_iterator = NFAGraph::vertex_iterator;
using edge_property_type = NFAGraph::edge_property_type;
using vertex_property_type = NFAGraph::vertex_property_type;
// These free functions, which follow the BGL model, are the interface to
// the graph held by this class.
friend size_t num_vertices(NGHolder &h);
friend size_t num_vertices(const NGHolder &h);
friend size_t num_edges(NGHolder &h);
friend size_t num_edges(const NGHolder &h);
friend void remove_vertex(NFAVertex v, NGHolder &h);
friend void clear_vertex(NFAVertex v, NGHolder &h);
friend void clear_in_edges(NFAVertex v, NGHolder &h);
friend void clear_out_edges(NFAVertex v, NGHolder &h);
friend void remove_edge(const NFAEdge &e, NGHolder &h);
friend void remove_edge(NFAVertex u, NFAVertex v, NGHolder &h);
template<class Predicate>
friend void remove_out_edge_if(NFAVertex v, Predicate pred, NGHolder &h) {
boost::remove_out_edge_if(v, pred, h.g);
h.isValidNumEdges = false;
}
template<class Predicate>
friend void remove_in_edge_if(NFAVertex v, Predicate pred, NGHolder &h) {
boost::remove_in_edge_if(v, pred, h.g);
h.isValidNumEdges = false;
}
template<class Predicate>
friend void remove_edge_if(Predicate pred, NGHolder &h) {
boost::remove_edge_if(pred, h.g);
h.isValidNumEdges = false;
}
friend std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v,
NGHolder &h);
friend std::pair<NFAEdge, bool> add_edge(NFAVertex u, NFAVertex v,
const edge_property_type &ep,
NGHolder &h);
friend NFAVertex add_vertex(NGHolder &h);
friend NFAVertex add_vertex(const vertex_property_type &vp, NGHolder &h);
static NFAVertex null_vertex(void) { return NFAGraph::null_vertex(); }
// Subscript operators for BGL bundled properties.
using graph_bundled = NFAGraph::graph_bundled;
using vertex_bundled = NFAGraph::vertex_bundled;
using edge_bundled = NFAGraph::edge_bundled;
vertex_bundled &operator[](NFAVertex v) {
return get(boost::vertex_bundle, g)[v];
}
const vertex_bundled &operator[](NFAVertex v) const {
return get(boost::vertex_bundle, g)[v];
}
edge_bundled &operator[](const NFAEdge &e) {
return get(boost::edge_bundle, g)[e];
}
const edge_bundled &operator[](const NFAEdge &e) const {
return get(boost::edge_bundle, g)[e];
}
protected:
/* Since the NFAGraph vertex/edge list selectors are std::lists, computing
* num_vertices and num_edges is O(N). We use these members to store a
* cached copy of the size.
*
* In the future, with C++11's constant-time std::list::size, these may
* become obsolete. */
u32 numVertices;
u32 numEdges;
bool isValidNumEdges;
bool isValidNumVertices;
vertex_descriptor getSpecialVertex(u32 id) const;
};
typedef NGHolder::vertex_descriptor NFAVertex;
typedef NGHolder::edge_descriptor NFAEdge;
/** \brief True if the vertex \p v is one of our special vertices. */
template <typename GraphT>
static really_inline
bool is_special(const NFAVertex v, const GraphT &g) {
bool is_special(const typename GraphT::vertex_descriptor v, const GraphT &g) {
return g[v].index < N_SPECIALS;
}
static really_inline
std::pair<NGHolder::adjacency_iterator, NGHolder::adjacency_iterator>
adjacent_vertices(NFAVertex v, const NGHolder &h) {
return adjacent_vertices(v, h.g);
}
static really_inline
std::pair<NFAEdge, bool> edge(NFAVertex u, NFAVertex v, const NGHolder &h) {
return boost::edge(u, v, h.g);
}
static really_inline
std::pair<NGHolder::edge_iterator, NGHolder::edge_iterator>
edges(const NGHolder &h) {
return edges(h.g);
}
static really_inline
size_t in_degree(NFAVertex v, const NGHolder &h) {
return in_degree(v, h.g);
}
static really_inline
std::pair<NGHolder::in_edge_iterator, NGHolder::in_edge_iterator>
in_edges(NFAVertex v, const NGHolder &h) {
return in_edges(v, h.g);
}
static really_inline
std::pair<NGHolder::inv_adjacency_iterator, NGHolder::inv_adjacency_iterator>
inv_adjacent_vertices(NFAVertex v, const NGHolder &h) {
return inv_adjacent_vertices(v, h.g);
}
static really_inline
size_t out_degree(NFAVertex v, const NGHolder &h) {
return out_degree(v, h.g);
}
static really_inline
std::pair<NGHolder::out_edge_iterator, NGHolder::out_edge_iterator>
out_edges(NFAVertex v, const NGHolder &h) {
return out_edges(v, h.g);
}
static really_inline
NFAVertex source(const NFAEdge &e, const NGHolder &h) {
return source(e, h.g);
}
static really_inline
NFAVertex target(const NFAEdge &e, const NGHolder &h) {
return target(e, h.g);
}
static really_inline
std::pair<NGHolder::vertex_iterator, NGHolder::vertex_iterator>
vertices(const NGHolder &h) {
return vertices(h.g);
}
/**
* \brief Clears all non-special vertices and edges from the graph.
*
@@ -239,16 +141,6 @@ vertices(const NGHolder &h) {
*/
void clear_graph(NGHolder &h);
inline
void renumber_edges(NGHolder &h) {
h.renumberEdges();
}
inline
void renumber_vertices(NGHolder &h) {
h.renumberVertices();
}
/*
* \brief Clear and remove all of the vertices pointed to by the given iterator
* range.
@@ -275,8 +167,8 @@ void remove_vertices(Iter begin, Iter end, NGHolder &h, bool renumber = true) {
}
if (renumber) {
h.renumberEdges();
h.renumberVertices();
renumber_edges(h);
renumber_vertices(h);
}
}
@@ -311,7 +203,7 @@ void remove_edges(Iter begin, Iter end, NGHolder &h, bool renumber = true) {
}
if (renumber) {
h.renumberEdges();
renumber_edges(h);
}
}

View File

@@ -77,6 +77,26 @@ private:
ReportID a_rep;
ReportID b_rep;
};
/** Comparison functor used to sort by vertex_index. */
template<typename Graph>
struct VertexIndexOrdering {
explicit VertexIndexOrdering(const Graph &g_in) : g(g_in) {}
bool operator()(typename Graph::vertex_descriptor a,
typename Graph::vertex_descriptor b) const {
assert(a == b || g[a].index != g[b].index);
return g[a].index < g[b].index;
}
private:
const Graph &g;
};
template<typename Graph>
static
VertexIndexOrdering<Graph> make_index_ordering(const Graph &g) {
return VertexIndexOrdering<Graph>(g);
}
}
static
@@ -109,7 +129,7 @@ bool is_equal_i(const NGHolder &a, const NGHolder &b,
for (size_t i = 0; i < vert_a.size(); i++) {
NFAVertex va = vert_a[i];
NFAVertex vb = vert_b[i];
DEBUG_PRINTF("vertex %u\n", a[va].index);
DEBUG_PRINTF("vertex %zu\n", a[va].index);
// Vertex index must be the same.
if (a[va].index != b[vb].index) {

View File

@@ -78,8 +78,7 @@ bool sanityCheckGraph(const NGHolder &g,
// Non-specials should have non-empty reachability.
if (!is_special(v, g)) {
if (g[v].char_reach.none()) {
DEBUG_PRINTF("vertex %u has empty reach\n",
g[v].index);
DEBUG_PRINTF("vertex %zu has empty reach\n", g[v].index);
return false;
}
}
@@ -88,25 +87,23 @@ bool sanityCheckGraph(const NGHolder &g,
// other vertices must not have them.
if (is_match_vertex(v, g) && v != g.accept) {
if (g[v].reports.empty()) {
DEBUG_PRINTF("vertex %u has no reports\n", g[v].index);
DEBUG_PRINTF("vertex %zu has no reports\n", g[v].index);
return false;
}
} else if (!g[v].reports.empty()) {
DEBUG_PRINTF("vertex %u has reports but no accept edge\n",
DEBUG_PRINTF("vertex %zu has reports but no accept edge\n",
g[v].index);
return false;
}
// Participant vertices should have distinct state indices.
if (!contains(state_ids, v)) {
DEBUG_PRINTF("vertex %u has no state index!\n",
g[v].index);
DEBUG_PRINTF("vertex %zu has no state index!\n", g[v].index);
return false;
}
u32 s = state_ids.at(v);
if (s != NO_STATE && !seen_states.insert(s).second) {
DEBUG_PRINTF("vertex %u has dupe state %u\n",
g[v].index, s);
DEBUG_PRINTF("vertex %zu has dupe state %u\n", g[v].index, s);
return false;
}
}
@@ -178,11 +175,7 @@ NFAVertex makeTopStartVertex(NGHolder &g, const flat_set<u32> &tops,
CharReach top_cr = calcTopVertexReach(tops, top_reach);
g[u].char_reach = top_cr;
// Add edges in vertex index order, for determinism.
vector<NFAVertex> ordered_succs(begin(succs), end(succs));
sort(begin(ordered_succs), end(ordered_succs), make_index_ordering(g));
for (auto v : ordered_succs) {
for (auto v : succs) {
if (v == g.accept || v == g.acceptEod) {
reporter = true;
}
@@ -374,7 +367,7 @@ void attemptToUseAsStart(const NGHolder &g, NFAVertex u,
return;
}
DEBUG_PRINTF("reusing %u is a start vertex\n", g[u].index);
DEBUG_PRINTF("reusing %zu is a start vertex\n", g[u].index);
markTopSuccAsHandled(u, top_inter, succs, tops_out, unhandled_top_succs,
unhandled_succ_tops);
}
@@ -388,8 +381,7 @@ void reusePredsAsStarts(const NGHolder &g, const map<u32, CharReach> &top_reach,
map<u32, flat_set<NFAVertex>> &unhandled_top_succs,
map<NFAVertex, flat_set<u32>> &unhandled_succ_tops,
map<u32, set<NFAVertex>> &tops_out) {
/* create list of candidates first, to avoid issues of iter invalidation
* and determinism */
/* create list of candidates first, to avoid issues of iter invalidation */
DEBUG_PRINTF("attempting to reuse vertices for top starts\n");
vector<NFAVertex> cand_starts;
for (NFAVertex u : unhandled_succ_tops | map_keys) {
@@ -397,7 +389,6 @@ void reusePredsAsStarts(const NGHolder &g, const map<u32, CharReach> &top_reach,
cand_starts.push_back(u);
}
}
sort(cand_starts.begin(), cand_starts.end(), make_index_ordering(g));
for (NFAVertex u : cand_starts) {
if (!contains(unhandled_succ_tops, u)) {
@@ -625,7 +616,7 @@ void remapReportsToPrograms(NGHolder &h, const ReportManager &rm) {
u32 program = rm.getProgramOffset(id);
reports.insert(program);
}
DEBUG_PRINTF("vertex %u: remapped reports {%s} to programs {%s}\n",
DEBUG_PRINTF("vertex %zu: remapped reports {%s} to programs {%s}\n",
h[v].index, as_string_list(old_reports).c_str(),
as_string_list(reports).c_str());
}

View File

@@ -69,7 +69,7 @@ void findAccelFriendGeneration(const NGHolder &g, const CharReach &cr,
}
const CharReach &acr = g[v].char_reach;
DEBUG_PRINTF("checking %u\n", g[v].index);
DEBUG_PRINTF("checking %zu\n", g[v].index);
if (acr.count() < WIDE_FRIEND_MIN || !acr.isSubsetOf(cr)) {
DEBUG_PRINTF("bad reach %zu\n", acr.count());
@@ -86,7 +86,7 @@ void findAccelFriendGeneration(const NGHolder &g, const CharReach &cr,
next_preds->insert(v);
insert(next_cands, adjacent_vertices(v, g));
DEBUG_PRINTF("%u is a friend indeed\n", g[v].index);
DEBUG_PRINTF("%zu is a friend indeed\n", g[v].index);
friends->insert(v);
next_cand:;
}
@@ -675,7 +675,7 @@ NFAVertex get_sds_or_proxy(const NGHolder &g) {
while (true) {
if (hasSelfLoop(v, g)) {
DEBUG_PRINTF("woot %u\n", g[v].index);
DEBUG_PRINTF("woot %zu\n", g[v].index);
return v;
}
if (out_degree(v, g) != 1) {
@@ -837,7 +837,7 @@ bool nfaCheckAccel(const NGHolder &g, NFAVertex v,
CharReach terminating = g[v].char_reach;
terminating.flip();
DEBUG_PRINTF("vertex %u is cyclic and has %zu stop chars%s\n",
DEBUG_PRINTF("vertex %zu is cyclic and has %zu stop chars%s\n",
g[v].index, terminating.count(),
allow_wide ? " (w)" : "");

View File

@@ -46,6 +46,7 @@
#include <fstream>
#include <queue>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/boykov_kolmogorov_max_flow.hpp>
using namespace std;
@@ -335,7 +336,7 @@ void processWorkQueue(const NGHolder &g, const NFAEdge &e,
// Our literal set should contain no literal that is a suffix of another.
assert(!hasSuffixLiterals(s));
DEBUG_PRINTF("edge %u (%u->%u) produced %zu literals\n", g[e].index,
DEBUG_PRINTF("edge %zu (%zu->%zu) produced %zu literals\n", g[e].index,
g[source(e, g)].index, g[target(e, g)].index, s.size());
}
@@ -791,7 +792,7 @@ bool splitOffLeadingLiteral_i(const NGHolder &g, bool anch,
}
while (true) {
DEBUG_PRINTF("validating vertex %u\n", g[v].index);
DEBUG_PRINTF("validating vertex %zu\n", g[v].index);
assert(v != g.acceptEod && v != g.accept);

View File

@@ -95,7 +95,7 @@ void addToString(string &s, const NGHolder &g, NFAVertex v) {
static
bool splitOffLiteral(NG &ng, NGWrapper &g, NFAVertex v, const bool anchored,
set<NFAVertex> &dead) {
DEBUG_PRINTF("examine vertex %u\n", g[v].index);
DEBUG_PRINTF("examine vertex %zu\n", g[v].index);
bool nocase = false, casefixed = false;
assert(!is_special(v, g));
@@ -109,7 +109,7 @@ bool splitOffLiteral(NG &ng, NGWrapper &g, NFAVertex v, const bool anchored,
assert(edge(g.start, v, g).second);
assert(edge(g.startDs, v, g).second);
}
if (hasGreaterInDegree(reqInDegree, v, g)) {
if (in_degree(v, g) > reqInDegree) {
DEBUG_PRINTF("extra in-edges\n");
return false;
}
@@ -134,7 +134,7 @@ bool splitOffLiteral(NG &ng, NGWrapper &g, NFAVertex v, const bool anchored,
u = v; // previous vertex
v = *(adjacent_vertices(v, g).first);
DEBUG_PRINTF("loop, v=%u\n", g[v].index);
DEBUG_PRINTF("loop, v=%zu\n", g[v].index);
if (is_special(v, g)) {
if (v == g.accept || v == g.acceptEod) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -77,7 +77,7 @@ bool findPaths(const NGHolder &g, vector<Path> &paths) {
read_count[g[v].index] = out_degree(v, g);
DEBUG_PRINTF("setting read_count to %zu for %u\n",
DEBUG_PRINTF("setting read_count to %zu for %zu\n",
read_count[g[v].index], g[v].index);
if (v == g.start || v == g.startDs) {
@@ -117,7 +117,7 @@ bool findPaths(const NGHolder &g, vector<Path> &paths) {
read_count[g[u].index]--;
if (!read_count[g[u].index]) {
DEBUG_PRINTF("clearing %u as finished reading\n", g[u].index);
DEBUG_PRINTF("clearing %zu as finished reading\n", g[u].index);
built[g[u].index].clear();
built[g[u].index].shrink_to_fit();
}
@@ -138,9 +138,9 @@ bool hasLargeDegreeVertex(const NGHolder &g) {
if (is_special(v, g)) { // specials can have large degree
continue;
}
if (has_greater_degree(MAX_VERTEX_DEGREE, v, g)) {
DEBUG_PRINTF("vertex %u has degree %zu\n", g[v].index,
boost::degree(v, g.g));
if (degree(v, g) > MAX_VERTEX_DEGREE) {
DEBUG_PRINTF("vertex %zu has degree %zu\n", g[v].index,
degree(v, g));
return true;
}
}
@@ -188,7 +188,8 @@ struct PathMask {
}
// Reports are attached to the second-to-last vertex.
reports = g[*next(path.rbegin())].reports;
NFAVertex u = *std::next(path.rbegin());
reports = g[u].reports;
assert(!reports.empty());
}

View File

@@ -328,7 +328,7 @@ void markToppableStarts(const NGHolder &g, const flat_set<NFAVertex> &unused,
}
for (const auto &trigger : triggers) {
if (triggerAllowed(g, v, triggers, trigger)) {
DEBUG_PRINTF("idx %u is valid location for top\n", g[v].index);
DEBUG_PRINTF("idx %zu is valid location for top\n", g[v].index);
out->set(g[v].index);
break;
}

View File

@@ -80,6 +80,7 @@
#include <vector>
using namespace std;
using boost::make_filtered_graph;
namespace ue2 {
@@ -108,7 +109,7 @@ void findCandidates(NGHolder &g, const vector<NFAVertex> &ordering,
goto next_cand;
}
}
DEBUG_PRINTF("vertex %u is a candidate\n", g[v].index);
DEBUG_PRINTF("vertex %zu is a candidate\n", g[v].index);
cand->push_back(v);
next_cand:;
}
@@ -139,7 +140,7 @@ void findCandidates_rev(NGHolder &g, const vector<NFAVertex> &ordering,
goto next_cand;
}
}
DEBUG_PRINTF("vertex %u is a candidate\n", g[v].index);
DEBUG_PRINTF("vertex %zu is a candidate\n", g[v].index);
cand->push_back(v);
next_cand:;
}
@@ -242,7 +243,7 @@ set<NFAVertex> findSustainSet_rev(const NGHolder &g, NFAVertex p,
static
bool enlargeCyclicVertex(NGHolder &g, som_type som, NFAVertex v) {
DEBUG_PRINTF("considering vertex %u\n", g[v].index);
DEBUG_PRINTF("considering vertex %zu\n", g[v].index);
const CharReach &v_cr = g[v].char_reach;
CharReach add;
@@ -261,7 +262,7 @@ bool enlargeCyclicVertex(NGHolder &g, som_type som, NFAVertex v) {
if (p == v) {
continue;
}
DEBUG_PRINTF("looking at pred %u\n", g[p].index);
DEBUG_PRINTF("looking at pred %zu\n", g[p].index);
bool ignore_sds = som; /* if we are tracking som, entries into a state
from sds are significant. */
@@ -291,13 +292,13 @@ bool enlargeCyclicVertex(NGHolder &g, som_type som, NFAVertex v) {
/* the cr can be increased */
g[v].char_reach = add;
DEBUG_PRINTF("vertex %u was widened\n", g[v].index);
DEBUG_PRINTF("vertex %zu was widened\n", g[v].index);
return true;
}
static
bool enlargeCyclicVertex_rev(NGHolder &g, NFAVertex v) {
DEBUG_PRINTF("considering vertex %u\n", g[v].index);
DEBUG_PRINTF("considering vertex %zu\n", g[v].index);
const CharReach &v_cr = g[v].char_reach;
CharReach add;
@@ -316,7 +317,7 @@ bool enlargeCyclicVertex_rev(NGHolder &g, NFAVertex v) {
if (p == v) {
continue;
}
DEBUG_PRINTF("looking at succ %u\n", g[p].index);
DEBUG_PRINTF("looking at succ %zu\n", g[p].index);
set<NFAVertex> sustain = findSustainSet_rev(g, p, add);
DEBUG_PRINTF("sustain set is %zu\n", sustain.size());
@@ -341,7 +342,7 @@ bool enlargeCyclicVertex_rev(NGHolder &g, NFAVertex v) {
/* the cr can be increased */
g[v].char_reach = add;
DEBUG_PRINTF("vertex %u was widened\n", g[v].index);
DEBUG_PRINTF("vertex %zu was widened\n", g[v].index);
return true;
}
@@ -390,7 +391,7 @@ bool improveGraph(NGHolder &g, som_type som) {
* enlargeCyclicCR. */
CharReach reduced_cr(NFAVertex v, const NGHolder &g,
const map<NFAVertex, BoundedRepeatSummary> &br_cyclic) {
DEBUG_PRINTF("find minimal cr for %u\n", g[v].index);
DEBUG_PRINTF("find minimal cr for %zu\n", g[v].index);
CharReach v_cr = g[v].char_reach;
if (proper_in_degree(v, g) != 1) {
return v_cr;
@@ -579,12 +580,11 @@ flat_set<NFAVertex> findDependentVertices(const NGHolder &g, NFAVertex v) {
}
}
auto filtered_g = make_filtered_graph(g.g,
make_bad_edge_filter(&no_explore));
auto filtered_g = make_filtered_graph(g, make_bad_edge_filter(&no_explore));
vector<boost::default_color_type> color_raw(num_vertices(g));
auto color = make_iterator_property_map(color_raw.begin(),
get(&NFAGraphVertexProps::index, g.g));
get(vertex_index, g));
flat_set<NFAVertex> bad;
for (NFAVertex b : vertices_range(g)) {
if (b != g.start && g[b].char_reach.isSubsetOf(g[v].char_reach)) {
@@ -597,7 +597,7 @@ flat_set<NFAVertex> findDependentVertices(const NGHolder &g, NFAVertex v) {
flat_set<NFAVertex> rv;
for (NFAVertex u : vertices_range(g)) {
if (!contains(bad, u)) {
DEBUG_PRINTF("%u is good\n", g[u].index);
DEBUG_PRINTF("%zu is good\n", g[u].index);
rv.insert(u);
}
}
@@ -623,7 +623,7 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
}
bool changed = false;
DEBUG_PRINTF("using cyclic %u as base\n", g[u].index);
DEBUG_PRINTF("using cyclic %zu as base\n", g[u].index);
auto children = findDependentVertices(g, u);
vector<NFAVertex> u_succs;
for (NFAVertex v : adjacent_vertices_range(u, g)) {
@@ -639,23 +639,23 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
return g[a].char_reach.count() > g[b].char_reach.count();
});
for (NFAVertex v : u_succs) {
DEBUG_PRINTF(" using %u as killer\n", g[v].index);
DEBUG_PRINTF(" using %zu as killer\n", g[v].index);
/* Need to distinguish between vertices that are switched on after the
* cyclic vs vertices that are switched on concurrently with the cyclic
* if (subject to a suitable reach) */
bool v_peer_of_cyclic = willBeEnabledConcurrently(u, v, g);
set<NFAEdge> dead;
for (NFAVertex s : adjacent_vertices_range(v, g)) {
DEBUG_PRINTF(" looking at preds of %u\n", g[s].index);
DEBUG_PRINTF(" looking at preds of %zu\n", g[s].index);
for (NFAEdge e : in_edges_range(s, g)) {
NFAVertex p = source(e, g);
if (!contains(children, p) || p == v || p == u
|| p == g.accept) {
DEBUG_PRINTF("%u not a cand\n", g[p].index);
DEBUG_PRINTF("%zu not a cand\n", g[p].index);
continue;
}
if (is_any_accept(s, g) && g[p].reports != g[v].reports) {
DEBUG_PRINTF("%u bad reports\n", g[p].index);
DEBUG_PRINTF("%zu bad reports\n", g[p].index);
continue;
}
/* the out-edges of a vertex that may be enabled on the same
@@ -664,7 +664,7 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
* may not be switched on until another byte is processed). */
if (!v_peer_of_cyclic
&& sometimesEnabledConcurrently(u, p, g)) {
DEBUG_PRINTF("%u can only be squashed by a proper peer\n",
DEBUG_PRINTF("%zu can only be squashed by a proper peer\n",
g[p].index);
continue;
}
@@ -672,14 +672,14 @@ bool pruneUsingSuccessors(NGHolder &g, NFAVertex u, som_type som) {
if (g[p].char_reach.isSubsetOf(g[v].char_reach)) {
dead.insert(e);
changed = true;
DEBUG_PRINTF("removing edge %u->%u\n", g[p].index,
DEBUG_PRINTF("removing edge %zu->%zu\n", g[p].index,
g[s].index);
} else if (is_subset_of(succs(p, g), succs(u, g))) {
if (is_match_vertex(p, g)
&& !is_subset_of(g[p].reports, g[v].reports)) {
continue;
}
DEBUG_PRINTF("updating reach on %u\n", g[p].index);
DEBUG_PRINTF("updating reach on %zu\n", g[p].index);
changed |= (g[p].char_reach & g[v].char_reach).any();
g[p].char_reach &= ~g[v].char_reach;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -111,6 +111,7 @@ static
void removeEdgesFromIndex(NGHolder &g, vector<u64a> &capacityMap, u32 idx) {
remove_edge_if([&](const NFAEdge &e) { return g[e].index >= idx; }, g);
capacityMap.resize(idx);
renumber_edges(g);
}
/** A wrapper around boykov_kolmogorov_max_flow, returns the max flow and
@@ -142,11 +143,10 @@ u64a getMaxFlow(NGHolder &h, const vector<u64a> &capacityMap_in,
vector<s32> distances(numVertices);
assert(colorMap.size() == numVertices);
const NFAGraph &g = h.g;
auto v_index_map = get(&NFAGraphVertexProps::index, g);
auto e_index_map = get(&NFAGraphEdgeProps::index, g);
auto v_index_map = get(vertex_index, h);
auto e_index_map = get(edge_index, h);
u64a flow = boykov_kolmogorov_max_flow(g,
u64a flow = boykov_kolmogorov_max_flow(h,
make_iterator_property_map(capacityMap.begin(), e_index_map),
make_iterator_property_map(edgeResiduals.begin(), e_index_map),
make_iterator_property_map(reverseEdges.begin(), e_index_map),
@@ -158,7 +158,7 @@ u64a getMaxFlow(NGHolder &h, const vector<u64a> &capacityMap_in,
// Remove reverse edges from graph.
removeEdgesFromIndex(h, capacityMap, numRealEdges);
assert(num_edges(h.g) == numRealEdges);
assert(num_edges(h) == numRealEdges);
DEBUG_PRINTF("flow = %llu\n", flow);
return flow;
@@ -190,14 +190,14 @@ vector<NFAEdge> findMinCut(NGHolder &h, const vector<u64a> &scores) {
if (fromColor != boost::white_color && toColor == boost::white_color) {
assert(ec <= INVALID_EDGE_CAP);
DEBUG_PRINTF("found white cut edge %u->%u cap %llu\n",
DEBUG_PRINTF("found white cut edge %zu->%zu cap %llu\n",
h[from].index, h[to].index, ec);
observed_white_flow += ec;
picked_white.push_back(e);
}
if (fromColor == boost::black_color && toColor != boost::black_color) {
assert(ec <= INVALID_EDGE_CAP);
DEBUG_PRINTF("found black cut edge %u->%u cap %llu\n",
DEBUG_PRINTF("found black cut edge %zu->%zu cap %llu\n",
h[from].index, h[to].index, ec);
observed_black_flow += ec;
picked_black.push_back(e);

View File

@@ -220,13 +220,7 @@ void copyInEdges(NGHolder &g, NFAVertex from, NFAVertex to,
continue;
}
// Check with edge_by_target to cope with predecessors with large
// fan-out.
if (edge_by_target(u, to, g).second) {
continue;
}
add_edge(u, to, g[e], g);
add_edge_if_not_present(u, to, g[e], g);
}
}
@@ -361,7 +355,7 @@ void reduceRegions(NGHolder &h) {
// We may have vertices that have edges to both accept and acceptEod: in
// this case, we can optimize for performance by removing the acceptEod
// edges.
remove_in_edge_if(h.acceptEod, SourceHasEdgeToAccept(h), h.g);
remove_in_edge_if(h.acceptEod, SourceHasEdgeToAccept(h), h);
}
void prefilterReductions(NGHolder &h, const CompileContext &cc) {
@@ -378,13 +372,13 @@ void prefilterReductions(NGHolder &h, const CompileContext &cc) {
DEBUG_PRINTF("before: graph with %zu vertices, %zu edges\n",
num_vertices(h), num_edges(h));
h.renumberVertices();
h.renumberEdges();
renumber_vertices(h);
renumber_edges(h);
reduceRegions(h);
h.renumberVertices();
h.renumberEdges();
renumber_vertices(h);
renumber_edges(h);
DEBUG_PRINTF("after: graph with %zu vertices, %zu edges\n",
num_vertices(h), num_edges(h));

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -57,9 +57,8 @@ namespace ue2 {
void pruneUnreachable(NGHolder &g) {
deque<NFAVertex> dead;
if (!hasGreaterInDegree(1, g.acceptEod, g) &&
!hasGreaterInDegree(0, g.accept, g) &&
edge(g.accept, g.acceptEod, g).second) {
if (in_degree(g.acceptEod, g) == 1 && !in_degree(g.accept, g)
&& edge(g.accept, g.acceptEod, g).second) {
// Trivial case: there are no in-edges to our accepts (other than
// accept->acceptEod), so all non-specials are unreachable.
for (auto v : vertices_range(g)) {
@@ -70,10 +69,10 @@ void pruneUnreachable(NGHolder &g) {
} else {
// Walk a reverse graph from acceptEod with Boost's depth_first_visit
// call.
typedef reverse_graph<NFAGraph, NFAGraph&> RevNFAGraph;
RevNFAGraph revg(g.g);
typedef reverse_graph<NGHolder, NGHolder &> RevNFAGraph;
RevNFAGraph revg(g);
map<NFAVertex, default_color_type> colours;
map<RevNFAGraph::vertex_descriptor, default_color_type> colours;
depth_first_visit(revg, g.acceptEod,
make_dfs_visitor(boost::null_visitor()),
@@ -104,7 +103,8 @@ void pruneUnreachable(NGHolder &g) {
template<class nfag_t>
static
bool pruneForwardUseless(NGHolder &h, const nfag_t &g, NFAVertex s,
bool pruneForwardUseless(NGHolder &h, const nfag_t &g,
typename nfag_t::vertex_descriptor s,
vector<default_color_type> &vertexColor) {
// Begin with all vertices set to white, as DFV only marks visited
// vertices.
@@ -122,9 +122,9 @@ bool pruneForwardUseless(NGHolder &h, const nfag_t &g, NFAVertex s,
for (auto v : vertices_range(g)) {
u32 idx = g[v].index;
if (!is_special(v, g) && vertexColor[idx] == boost::white_color) {
DEBUG_PRINTF("vertex %u is unreachable from %u\n",
DEBUG_PRINTF("vertex %zu is unreachable from %zu\n",
g[v].index, g[s].index);
dead.push_back(v);
dead.push_back(NFAVertex(v));
}
}
@@ -145,17 +145,17 @@ void pruneUseless(NGHolder &g, bool renumber) {
assert(hasCorrectlyNumberedVertices(g));
vector<default_color_type> vertexColor(num_vertices(g));
bool work_done = pruneForwardUseless(g, g.g, g.start, vertexColor);
work_done |= pruneForwardUseless(
g, reverse_graph<NFAGraph, NFAGraph &>(g.g), g.acceptEod, vertexColor);
bool work_done = pruneForwardUseless(g, g, g.start, vertexColor);
work_done |= pruneForwardUseless(g, reverse_graph<NGHolder, NGHolder &>(g),
g.acceptEod, vertexColor);
if (!work_done) {
return;
}
if (renumber) {
g.renumberEdges();
g.renumberVertices();
renumber_edges(g);
renumber_vertices(g);
}
}
@@ -172,7 +172,7 @@ void pruneEmptyVertices(NGHolder &g) {
const CharReach &cr = g[v].char_reach;
if (cr.none()) {
DEBUG_PRINTF("empty: %u\n", g[v].index);
DEBUG_PRINTF("empty: %zu\n", g[v].index);
dead.push_back(v);
}
}
@@ -234,7 +234,7 @@ bool isDominatedByReporter(const NGHolder &g,
// Note: reporters with edges only to acceptEod are not considered to
// dominate.
if (edge(u, g.accept, g).second && contains(g[u].reports, report_id)) {
DEBUG_PRINTF("%u is dominated by %u, and both report %u\n",
DEBUG_PRINTF("%zu is dominated by %zu, and both report %u\n",
g[v].index, g[u].index, report_id);
return true;
}
@@ -296,7 +296,7 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
}
sort(begin(reporters), end(reporters), make_index_ordering(g));
sort(begin(reporters), end(reporters));
reporters.erase(unique(begin(reporters), end(reporters)), end(reporters));
DEBUG_PRINTF("%zu vertices have simple exhaustible reports\n",
@@ -315,14 +315,14 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
continue;
}
if (isDominatedByReporter(g, dom, v, report_id)) {
DEBUG_PRINTF("removed dominated report %u from vertex %u\n",
DEBUG_PRINTF("removed dominated report %u from vertex %zu\n",
report_id, g[v].index);
g[v].reports.erase(report_id);
}
}
if (g[v].reports.empty()) {
DEBUG_PRINTF("removed edges to accepts from %u, no reports left\n",
DEBUG_PRINTF("removed edges to accepts from %zu, no reports left\n",
g[v].index);
remove_edge(v, g.accept, g);
remove_edge(v, g.acceptEod, g);
@@ -337,7 +337,7 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
if (hasOnlySelfLoopAndExhaustibleAccepts(g, rm, v)) {
remove_edge(v, v, g);
modified = true;
DEBUG_PRINTF("removed self-loop on %u\n", g[v].index);
DEBUG_PRINTF("removed self-loop on %zu\n", g[v].index);
}
}
@@ -349,7 +349,7 @@ void pruneHighlanderDominated(NGHolder &g, const ReportManager &rm) {
// We may have only removed self-loops, in which case pruneUseless wouldn't
// renumber, so we do edge renumbering explicitly here.
g.renumberEdges();
renumber_edges(g);
}
/** Removes the given Report ID from vertices connected to accept, and then
@@ -388,8 +388,8 @@ void pruneReport(NGHolder &g, ReportID report) {
remove_edges(dead, g);
pruneUnreachable(g);
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
}
/** Removes all Report IDs bar the given one from vertices connected to accept,
@@ -431,8 +431,8 @@ void pruneAllOtherReports(NGHolder &g, ReportID report) {
remove_edges(dead, g);
pruneUnreachable(g);
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
}
} // namespace ue2

View File

@@ -59,7 +59,7 @@ static
size_t countChain(const NGHolder &g, NFAVertex v) {
size_t count = 0;
while (v) {
DEBUG_PRINTF("counting vertex %u\n", g[v].index);
DEBUG_PRINTF("counting vertex %zu\n", g[v].index);
if (is_special(v, g)) {
break;
}
@@ -79,7 +79,7 @@ void wireNewAccepts(NGHolder &g, NFAVertex head,
continue;
}
DEBUG_PRINTF("adding edge: %u -> accept\n", g[u].index);
DEBUG_PRINTF("adding edge: %zu -> accept\n", g[u].index);
assert(!edge(u, g.accept, g).second);
assert(!edge(u, g.acceptEod, g).second);
add_edge(u, g.accept, g);
@@ -136,13 +136,13 @@ bool singleStart(const NGHolder &g) {
for (auto v : adjacent_vertices_range(g.start, g)) {
if (!is_special(v, g)) {
DEBUG_PRINTF("saw %u\n", g[v].index);
DEBUG_PRINTF("saw %zu\n", g[v].index);
seen.insert(v);
}
}
for (auto v : adjacent_vertices_range(g.startDs, g)) {
if (!is_special(v, g)) {
DEBUG_PRINTF("saw %u\n", g[v].index);
DEBUG_PRINTF("saw %zu\n", g[v].index);
seen.insert(v);
}
}
@@ -158,7 +158,7 @@ bool triggerResetsPuff(const NGHolder &g, NFAVertex head) {
for (auto u : inv_adjacent_vertices_range(head, g)) {
if (!g[u].char_reach.isSubsetOf(puff_escapes)) {
DEBUG_PRINTF("no reset on trigger %u %u\n", g[u].index,
DEBUG_PRINTF("no reset on trigger %zu %zu\n", g[u].index,
g[head].index);
return false;
}
@@ -172,7 +172,7 @@ bool triggerResetsPuff(const NGHolder &g, NFAVertex head) {
* */
static
bool triggerFloodsPuff(const NGHolder &g, NFAVertex head) {
DEBUG_PRINTF("head = %u\n", g[head].index);
DEBUG_PRINTF("head = %zu\n", g[head].index);
const CharReach &puff_cr = g[head].char_reach;
@@ -186,14 +186,14 @@ bool triggerFloodsPuff(const NGHolder &g, NFAVertex head) {
if (proper_in_degree(head, g) == 1
&& puff_cr == g[getSoleSourceVertex(g, head)].char_reach) {
head = getSoleSourceVertex(g, head);
DEBUG_PRINTF("temp new head = %u\n", g[head].index);
DEBUG_PRINTF("temp new head = %zu\n", g[head].index);
}
for (auto s : inv_adjacent_vertices_range(head, g)) {
DEBUG_PRINTF("s = %u\n", g[s].index);
DEBUG_PRINTF("s = %zu\n", g[s].index);
if (!puff_cr.isSubsetOf(g[s].char_reach)) {
DEBUG_PRINTF("no flood on trigger %u %u\n",
g[s].index, g[head].index);
DEBUG_PRINTF("no flood on trigger %zu %zu\n", g[s].index,
g[head].index);
return false;
}
@@ -268,7 +268,7 @@ void constructPuff(NGHolder &g, const NFAVertex a, const NFAVertex puffv,
RoseBuild &rose, ReportManager &rm,
flat_set<ReportID> &chain_reports, bool prefilter) {
DEBUG_PRINTF("constructing Puff for report %u\n", report);
DEBUG_PRINTF("a = %u\n", g[a].index);
DEBUG_PRINTF("a = %zu\n", g[a].index);
const Report &puff_report = rm.getReport(report);
const bool simple_exhaust = isSimpleExhaustible(puff_report);
@@ -349,7 +349,7 @@ bool doComponent(RoseBuild &rose, ReportManager &rm, NGHolder &g, NFAVertex a,
}
nodes.push_back(a);
DEBUG_PRINTF("vertex %u has in_degree %zu\n", g[a].index,
DEBUG_PRINTF("vertex %zu has in_degree %zu\n", g[a].index,
in_degree(a, g));
a = getSoleSourceVertex(g, a);
@@ -387,10 +387,10 @@ bool doComponent(RoseBuild &rose, ReportManager &rm, NGHolder &g, NFAVertex a,
bool auto_restart = false;
DEBUG_PRINTF("a = %u\n", g[a].index);
DEBUG_PRINTF("a = %zu\n", g[a].index);
if (nodes.size() < MIN_PUFF_LENGTH || a == g.startDs) {
DEBUG_PRINTF("bad %zu %u\n", nodes.size(), g[a].index);
DEBUG_PRINTF("bad %zu %zu\n", nodes.size(), g[a].index);
if (nodes.size() < MIN_PUFF_LENGTH) {
return false;
} else {

View File

@@ -309,14 +309,10 @@ static
bool hasInEdgeTops(const NGHolder &g, NFAVertex v) {
bool exists;
NFAEdge e;
tie(e, exists) = edge_by_target(g.start, v, g);
if (exists && !g[e].tops.empty()) {
return true;
}
return false;
tie(e, exists) = edge(g.start, v, g);
return exists && !g[e].tops.empty();
}
/** Transform (1), removal of redundant vertices. */
static
bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
@@ -348,8 +344,7 @@ bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
}
if (info.pred.empty() || info.succ.empty()) {
DEBUG_PRINTF("vertex %u has empty pred/succ list\n",
g[v].index);
DEBUG_PRINTF("vertex %zu has empty pred/succ list\n", g[v].index);
assert(0); // non-special states should always have succ/pred lists
continue;
}
@@ -448,7 +443,7 @@ bool doUselessMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
CharReach &otherReach = g[t].char_reach;
if (currReach.isSubsetOf(otherReach)) {
DEBUG_PRINTF("removing redundant vertex %u (keeping %u)\n",
DEBUG_PRINTF("removing redundant vertex %zu (keeping %zu)\n",
g[v].index, g[t].index);
markForRemoval(v, infoMap, removable);
changed = true;
@@ -539,9 +534,6 @@ bool doDiamondMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
continue;
}
/* ensure that we look for candidates in the same order */
sort(intersection.begin(), intersection.end(), make_index_ordering(g));
const CharReach &currReach = g[v].char_reach;
const auto &currReports = g[v].reports;
for (auto t : intersection) {
@@ -578,8 +570,8 @@ bool doDiamondMergePass(NGHolder &g, som_type som, VertexInfoMap &infoMap,
CharReach &otherReach = g[t].char_reach;
otherReach |= currReach;
// v can be removed
DEBUG_PRINTF("removing redundant vertex %u and merging "
"reachability with vertex %u\n",
DEBUG_PRINTF("removing redundant vertex %zu and merging "
"reachability with vertex %zu\n",
g[v].index, g[t].index);
markForRemoval(v, infoMap, removable);
changed = true;
@@ -645,14 +637,14 @@ bool reversePathReachSubset(const NFAEdge &e, const NFAVertex &dom,
}
NFAVertex start = source(e, g);
using RevGraph = boost::reverse_graph<NFAGraph, const NFAGraph &>;
using RevGraph = boost::reverse_graph<NGHolder, const NGHolder &>;
map<RevGraph::vertex_descriptor, boost::default_color_type> vertexColor;
// Walk the graph backwards from v, examining each node. We fail (return
// false) if we encounter a node with reach NOT a subset of domReach, and
// we stop searching at dom.
try {
depth_first_visit(RevGraph(g.g), start,
depth_first_visit(RevGraph(g), start,
ReachSubsetVisitor(domReach),
make_assoc_property_map(vertexColor),
VertexIs<RevGraph, RevGraph::vertex_descriptor>(dom));
@@ -674,16 +666,15 @@ bool forwardPathReachSubset(const NFAEdge &e, const NFAVertex &dom,
}
NFAVertex start = target(e, g);
map<NFAGraph::vertex_descriptor, boost::default_color_type> vertexColor;
map<NFAVertex, boost::default_color_type> vertexColor;
// Walk the graph forward from v, examining each node. We fail (return
// false) if we encounter a node with reach NOT a subset of domReach, and
// we stop searching at dom.
try {
depth_first_visit(g.g, start,
ReachSubsetVisitor(domReach),
depth_first_visit(g, start, ReachSubsetVisitor(domReach),
make_assoc_property_map(vertexColor),
VertexIs<NFAGraph, NFAVertex>(dom));
VertexIs<NGHolder, NFAVertex>(dom));
} catch(ReachMismatch&) {
return false;
}
@@ -775,9 +766,8 @@ void findCyclicDom(NGHolder &g, vector<bool> &cyclic,
continue;
}
DEBUG_PRINTF("vertex %u is dominated by directly-connected cyclic "
"vertex %u\n", g[v].index,
g[dom].index);
DEBUG_PRINTF("vertex %zu is dominated by directly-connected cyclic "
"vertex %zu\n", g[v].index, g[dom].index);
// iff all paths through in-edge e of v involve vertices whose
// reachability is a subset of reach(dom), we can delete edge e.
@@ -787,8 +777,8 @@ void findCyclicDom(NGHolder &g, vector<bool> &cyclic,
}
if (reversePathReachSubset(e, dom, g)) {
DEBUG_PRINTF("edge (%u, %u) can be removed: leading paths "
"share dom reach\n",
DEBUG_PRINTF("edge (%zu, %zu) can be removed: leading "
"paths share dom reach\n",
g[source(e, g)].index, g[target(e, g)].index);
dead.insert(e);
if (source(e, g) == v) {
@@ -814,11 +804,9 @@ void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
// Path out through a post-dominator (e.g. a?.+foobar')
NFAVertex postdom = postdominators[v];
if (postdom && cyclic[g[postdom].index]
&& edge(v, postdom, g).second) {
DEBUG_PRINTF("vertex %u is postdominated by directly-connected "
"cyclic vertex %u\n", g[v].index,
g[postdom].index);
if (postdom && cyclic[g[postdom].index] && edge(v, postdom, g).second) {
DEBUG_PRINTF("vertex %zu is postdominated by directly-connected "
"cyclic vertex %zu\n", g[v].index, g[postdom].index);
// iff all paths through in-edge e of v involve vertices whose
// reachability is a subset of reach(dom), we can delete edge e.
@@ -828,8 +816,8 @@ void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
}
if (forwardPathReachSubset(e, postdom, g)) {
DEBUG_PRINTF("edge (%u, %u) can be removed: trailing paths "
"share postdom reach\n",
DEBUG_PRINTF("edge (%zu, %zu) can be removed: trailing "
"paths share postdom reach\n",
g[source(e, g)].index, g[target(e, g)].index);
if (target(e, g) == v) {
cyclic[g[v].index] = false;
@@ -844,7 +832,7 @@ void findCyclicPostDom(NGHolder &g, vector<bool> &cyclic,
bool removeRedundancy(NGHolder &g, som_type som) {
DEBUG_PRINTF("rr som = %d\n", (int)som);
g.renumberVertices();
renumber_vertices(g);
// Cheap check: if all the non-special vertices have in-degree one and
// out-degree one, there's no redundancy in this here graph and we can

View File

@@ -71,7 +71,7 @@ using namespace std;
namespace ue2 {
typedef ue2::unordered_set<NFAEdge> BackEdgeSet;
typedef boost::filtered_graph<NFAGraph, bad_edge_filter<BackEdgeSet>>
typedef boost::filtered_graph<NGHolder, bad_edge_filter<BackEdgeSet>>
AcyclicGraph;
namespace {
@@ -92,17 +92,17 @@ void checkAndAddExitCandidate(const AcyclicGraph &g,
/* find the set of vertices reachable from v which are not in r */
for (auto w : adjacent_vertices_range(v, g)) {
if (!contains(r, w)) {
if (!contains(r, NFAVertex(w))) {
if (!open) {
exits->push_back(exit_info(v));
exits->push_back(exit_info(NFAVertex(v)));
open = &exits->back().open;
}
open->insert(w);
open->insert(NFAVertex(w));
}
}
if (open) {
DEBUG_PRINTF("exit %u\n", g[v].index);
DEBUG_PRINTF("exit %zu\n", g[v].index);
}
}
@@ -141,7 +141,7 @@ bool exitValid(UNUSED const AcyclicGraph &g, const vector<exit_info> &exits,
return true;
}
if (exits.size() == 1 && open_jumps.size() == 1) {
DEBUG_PRINTF("oj %u, e %u\n", g[*open_jumps.begin()].index,
DEBUG_PRINTF("oj %zu, e %zu\n", g[*open_jumps.begin()].index,
g[exits[0].exit].index);
if (*open_jumps.begin() == exits[0].exit) {
return true;
@@ -190,7 +190,7 @@ void buildInitialCandidate(const AcyclicGraph &g,
if (exits->empty()) {
DEBUG_PRINTF("odd\n");
candidate->clear();
DEBUG_PRINTF("adding %u to initial\n", g[*it].index);
DEBUG_PRINTF("adding %zu to initial\n", g[*it].index);
candidate->insert(*it);
open_jumps->erase(*it);
checkAndAddExitCandidate(g, *candidate, *it, exits);
@@ -202,7 +202,7 @@ void buildInitialCandidate(const AcyclicGraph &g,
candidate->clear();
for (; it != ite; ++it) {
DEBUG_PRINTF("adding %u to initial\n", g[*it].index);
DEBUG_PRINTF("adding %zu to initial\n", g[*it].index);
candidate->insert(*it);
if (contains(enters, *it)) {
break;
@@ -231,10 +231,10 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
vector<exit_info> exits;
ue2::unordered_set<NFAVertex> candidate;
ue2::unordered_set<NFAVertex> open_jumps;
DEBUG_PRINTF("adding %u to current\n", g[*t_it].index);
DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index);
assert(t_it != topo.rend());
candidate.insert(*t_it++);
DEBUG_PRINTF("adding %u to current\n", g[*t_it].index);
DEBUG_PRINTF("adding %zu to current\n", g[*t_it].index);
assert(t_it != topo.rend());
candidate.insert(*t_it++);
findExits(g, candidate, &exits);
@@ -257,7 +257,7 @@ void findDagLeaders(const NGHolder &h, const AcyclicGraph &g,
&open_jumps);
} else {
NFAVertex curr = *t_it;
DEBUG_PRINTF("adding %u to current\n", g[curr].index);
DEBUG_PRINTF("adding %zu to current\n", g[curr].index);
candidate.insert(curr);
open_jumps.erase(curr);
refineExits(g, candidate, *t_it, &exits);
@@ -284,7 +284,7 @@ void mergeUnderBackEdges(const NGHolder &g, const vector<NFAVertex> &topo,
continue;
}
DEBUG_PRINTF("merging v = %u(%u), u = %u(%u)\n", g[v].index, rv,
DEBUG_PRINTF("merging v = %zu(%u), u = %zu(%u)\n", g[v].index, rv,
g[u].index, ru);
assert(rv < ru);
@@ -350,8 +350,8 @@ void liftSinks(const AcyclicGraph &acyclic_g, vector<NFAVertex> &topoOrder) {
}
if (isLeafNode(v, acyclic_g)) {
DEBUG_PRINTF("sink found %u\n", acyclic_g[v].index);
sinks.insert(v);
DEBUG_PRINTF("sink found %zu\n", acyclic_g[v].index);
sinks.insert(NFAVertex(v));
}
}
@@ -365,18 +365,18 @@ void liftSinks(const AcyclicGraph &acyclic_g, vector<NFAVertex> &topoOrder) {
DEBUG_PRINTF("look\n");
changed = false;
for (auto v : vertices_range(acyclic_g)) {
if (is_special(v, acyclic_g) || contains(sinks, v)) {
if (is_special(v, acyclic_g) || contains(sinks, NFAVertex(v))) {
continue;
}
for (auto w : adjacent_vertices_range(v, acyclic_g)) {
if (!contains(sinks, w)) {
if (!contains(sinks, NFAVertex(w))) {
goto next;
}
}
DEBUG_PRINTF("sink found %u\n", acyclic_g[v].index);
sinks.insert(v);
DEBUG_PRINTF("sink found %zu\n", acyclic_g[v].index);
sinks.insert(NFAVertex(v));
changed = true;
next:;
}
@@ -387,10 +387,10 @@ void liftSinks(const AcyclicGraph &acyclic_g, vector<NFAVertex> &topoOrder) {
continue;
}
NFAVertex s = *ri;
DEBUG_PRINTF("handling sink %u\n", acyclic_g[s].index);
DEBUG_PRINTF("handling sink %zu\n", acyclic_g[s].index);
ue2::unordered_set<NFAVertex> parents;
for (const auto &e : in_edges_range(s, acyclic_g)) {
parents.insert(source(e, acyclic_g));
parents.insert(NFAVertex(source(e, acyclic_g)));
}
/* vertex has no children not reachable on a back edge, bubble the
@@ -417,10 +417,9 @@ vector<NFAVertex> buildTopoOrder(const NGHolder &w,
vector<boost::default_color_type> &colours) {
vector<NFAVertex> topoOrder;
topological_sort(
acyclic_g, back_inserter(topoOrder),
color_map(make_iterator_property_map(
colours.begin(), get(&NFAGraphVertexProps::index, acyclic_g))));
topological_sort(acyclic_g, back_inserter(topoOrder),
color_map(make_iterator_property_map(colours.begin(),
get(vertex_index, acyclic_g))));
reorderSpecials(w, acyclic_g, topoOrder);
@@ -432,7 +431,7 @@ vector<NFAVertex> buildTopoOrder(const NGHolder &w,
DEBUG_PRINTF("TOPO ORDER\n");
for (auto ri = topoOrder.rbegin(); ri != topoOrder.rend(); ++ri) {
DEBUG_PRINTF("[%u]\n", acyclic_g[*ri].index);
DEBUG_PRINTF("[%zu]\n", acyclic_g[*ri].index);
}
DEBUG_PRINTF("----------\n");
@@ -448,14 +447,14 @@ ue2::unordered_map<NFAVertex, u32> assignRegions(const NGHolder &g) {
// Build an acyclic graph for this NGHolder.
BackEdgeSet deadEdges;
depth_first_search(
g.g, visitor(BackEdges<BackEdgeSet>(deadEdges))
.root_vertex(g.start)
.color_map(make_iterator_property_map(
colours.begin(), get(&NFAGraphVertexProps::index, g.g))));
depth_first_search(g,
visitor(BackEdges<BackEdgeSet>(deadEdges))
.root_vertex(g.start)
.color_map(make_iterator_property_map(colours.begin(),
get(vertex_index, g))));
auto af = make_bad_edge_filter(&deadEdges);
AcyclicGraph acyclic_g(g.g, af);
AcyclicGraph acyclic_g(g, af);
// Build a (reverse) topological ordering.
vector<NFAVertex> topoOrder = buildTopoOrder(g, acyclic_g, colours);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -181,7 +181,7 @@ bool isOptionalRegion(const Graph &g, NFAVertex v,
const ue2::unordered_map<NFAVertex, u32> &region_map) {
assert(isRegionEntry(g, v, region_map));
DEBUG_PRINTF("check if r%u is optional (inspecting v%u)\n",
DEBUG_PRINTF("check if r%u is optional (inspecting v%zu)\n",
region_map.at(v), g[v].index);
// Region zero is never optional.
@@ -198,12 +198,12 @@ bool isOptionalRegion(const Graph &g, NFAVertex v,
if (inSameRegion(g, v, u, region_map)) {
continue;
}
DEBUG_PRINTF(" searching from u=%u\n", g[u].index);
DEBUG_PRINTF(" searching from u=%zu\n", g[u].index);
assert(inEarlierRegion(g, v, u, region_map));
for (auto w : adjacent_vertices_range(u, g)) {
DEBUG_PRINTF(" searching to w=%u\n", g[w].index);
DEBUG_PRINTF(" searching to w=%zu\n", g[w].index);
if (inLaterRegion(g, v, w, region_map)) {
return true;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -90,7 +90,7 @@ void processCyclicStateForward(NGHolder &h, NFAVertex cyc,
CharReach cr = h[cyc].char_reach;
auto reports = h[cyc].reports;
DEBUG_PRINTF("going forward from %u/%u\n", h[cyc].index,
DEBUG_PRINTF("going forward from %zu/%u\n", h[cyc].index,
region);
map<u32, RegionInfo>::const_iterator it;
@@ -98,7 +98,7 @@ void processCyclicStateForward(NGHolder &h, NFAVertex cyc,
NFAVertex v = it->second.entry;
const CharReach &region_cr = it->second.cr;
assert(isRegionEntry(h, v, region_map) && !is_special(v, h));
DEBUG_PRINTF("checking %u\n", h[v].index);
DEBUG_PRINTF("checking %zu\n", h[v].index);
if (!region_cr.isSubsetOf(cr)) {
DEBUG_PRINTF("doesn't cover the reach of region %u\n", region);
@@ -107,8 +107,8 @@ void processCyclicStateForward(NGHolder &h, NFAVertex cyc,
if (isOptionalRegion(h, v, region_map)
&& !regionHasUnexpectedAccept(h, region, reports, region_map)) {
DEBUG_PRINTF("cyclic state %u leads to optional region leader %u\n",
h[cyc].index, h[v].index);
DEBUG_PRINTF("cyclic state %zu leads to optional region leader"
" %zu\n", h[cyc].index, h[v].index);
deadRegions.insert(region);
} else if (isSingletonRegion(h, v, region_map)) {
/* we can use this region as straw and suck in optional regions on
@@ -136,14 +136,14 @@ void processCyclicStateReverse(NGHolder &h, NFAVertex cyc,
CharReach cr = h[cyc].char_reach;
auto reports = h[cyc].reports;
DEBUG_PRINTF("going back from %u/%u\n", h[cyc].index, region);
DEBUG_PRINTF("going back from %zu/%u\n", h[cyc].index, region);
map<u32, RegionInfo>::const_iterator it;
while ((it = info.find(--region)) != info.end()) {
NFAVertex v = it->second.entry;
const CharReach &region_cr = it->second.cr;
assert(isRegionEntry(h, v, region_map) && !is_special(v, h));
DEBUG_PRINTF("checking %u\n", h[v].index);
DEBUG_PRINTF("checking %zu\n", h[v].index);
if (!region_cr.isSubsetOf(cr)) {
DEBUG_PRINTF("doesn't cover the reach of region %u\n", region);
@@ -152,7 +152,7 @@ void processCyclicStateReverse(NGHolder &h, NFAVertex cyc,
if (isOptionalRegion(h, v, region_map)
&& !regionHasUnexpectedAccept(h, region, reports, region_map)) {
DEBUG_PRINTF("cyclic state %u trails optional region leader %u\n",
DEBUG_PRINTF("cyclic state %zu trails optional region leader %zu\n",
h[cyc].index, h[v].index);
deadRegions.insert(region);
} else if (isSingletonRegion(h, v, region_map)) {

View File

@@ -61,6 +61,8 @@
#include <boost/icl/interval_set.hpp>
using namespace std;
using boost::depth_first_search;
using boost::depth_first_visit;
namespace ue2 {
@@ -99,7 +101,7 @@ struct ReachFilter {
const Graph *g = nullptr;
};
typedef boost::filtered_graph<NFAGraph, ReachFilter<NFAGraph> > RepeatGraph;
typedef boost::filtered_graph<NGHolder, ReachFilter<NGHolder>> RepeatGraph;
struct ReachSubgraph {
vector<NFAVertex> vertices;
@@ -126,9 +128,11 @@ void findInitDepths(const NGHolder &g,
}
}
template<class Graph>
static
void buildTopoOrder(const Graph &g, vector<NFAVertex> &topoOrder) {
vector<NFAVertex> buildTopoOrder(const RepeatGraph &g) {
/* Note: RepeatGraph is a filtered version of NGHolder and still has
* NFAVertex as its vertex descriptor */
typedef ue2::unordered_set<NFAEdge> EdgeSet;
EdgeSet deadEdges;
@@ -140,10 +144,13 @@ void buildTopoOrder(const Graph &g, vector<NFAVertex> &topoOrder) {
color_map(make_assoc_property_map(colours)));
auto acyclic_g = make_filtered_graph(g, make_bad_edge_filter(&deadEdges));
vector<NFAVertex> topoOrder;
topological_sort(acyclic_g, back_inserter(topoOrder),
color_map(make_assoc_property_map(colours)));
reverse(topoOrder.begin(), topoOrder.end());
return topoOrder;
}
static
@@ -171,7 +178,7 @@ bool roguePredecessor(const NGHolder &g, NFAVertex v,
continue;
}
if (!contains(pred, u)) {
DEBUG_PRINTF("%u is a rogue pred\n", g[u].index);
DEBUG_PRINTF("%zu is a rogue pred\n", g[u].index);
return true;
}
@@ -197,7 +204,7 @@ bool rogueSuccessor(const NGHolder &g, NFAVertex v,
}
if (!contains(succ, w)) {
DEBUG_PRINTF("%u is a rogue succ\n", g[w].index);
DEBUG_PRINTF("%zu is a rogue succ\n", g[w].index);
return true;
}
@@ -223,8 +230,8 @@ bool hasDifferentTops(const NGHolder &g, const vector<NFAVertex> &verts) {
if (u != g.start && u != g.startDs) {
continue; // Only edges from starts have valid top properties.
}
DEBUG_PRINTF("edge (%u,%u) with %zu tops\n", g[u].index, g[v].index,
g[e].tops.size());
DEBUG_PRINTF("edge (%zu,%zu) with %zu tops\n", g[u].index,
g[v].index, g[e].tops.size());
if (!tops) {
tops = &g[e].tops;
} else if (g[e].tops != *tops) {
@@ -243,14 +250,14 @@ bool vertexIsBad(const NGHolder &g, NFAVertex v,
const ue2::unordered_set<NFAVertex> &pred,
const ue2::unordered_set<NFAVertex> &succ,
const flat_set<ReportID> &reports) {
DEBUG_PRINTF("check vertex %u\n", g[v].index);
DEBUG_PRINTF("check vertex %zu\n", g[v].index);
// We must drop any vertex that is the target of a back-edge within
// our subgraph. The tail set contains all vertices that are after v in a
// topo ordering.
for (auto u : inv_adjacent_vertices_range(v, g)) {
if (contains(tail, u)) {
DEBUG_PRINTF("back-edge (%u,%u) in subgraph found\n",
DEBUG_PRINTF("back-edge (%zu,%zu) in subgraph found\n",
g[u].index, g[v].index);
return true;
}
@@ -260,18 +267,18 @@ bool vertexIsBad(const NGHolder &g, NFAVertex v,
// edges from *all* the vertices in pred and no other external entries.
// Similarly for exits.
if (roguePredecessor(g, v, involved, pred)) {
DEBUG_PRINTF("preds for %u not well-formed\n", g[v].index);
DEBUG_PRINTF("preds for %zu not well-formed\n", g[v].index);
return true;
}
if (rogueSuccessor(g, v, involved, succ)) {
DEBUG_PRINTF("succs for %u not well-formed\n", g[v].index);
DEBUG_PRINTF("succs for %zu not well-formed\n", g[v].index);
return true;
}
// All reporting vertices should have the same reports.
if (is_match_vertex(v, g) && reports != g[v].reports) {
DEBUG_PRINTF("report mismatch to %u\n", g[v].index);
DEBUG_PRINTF("report mismatch to %zu\n", g[v].index);
return true;
}
@@ -291,8 +298,7 @@ void splitSubgraph(const NGHolder &g, const deque<NFAVertex> &verts,
NFAUndirectedGraph ug;
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> old2new;
ue2::unordered_map<u32, NFAVertex> newIdx2old;
createUnGraph(verts_g.g, true, true, ug, old2new, newIdx2old);
createUnGraph(verts_g, true, true, ug, old2new);
ue2::unordered_map<NFAUndirectedVertex, u32> repeatMap;
@@ -517,7 +523,7 @@ bool processSubgraph(const NGHolder &g, ReachSubgraph &rsi,
if (u == first) {
continue; // no self-loops
}
DEBUG_PRINTF("pred vertex %u\n", g[u].index);
DEBUG_PRINTF("pred vertex %zu\n", g[u].index);
dist[u].insert(0);
}
@@ -619,7 +625,7 @@ void buildTugTrigger(NGHolder &g, NFAVertex cyclic, NFAVertex v,
vector<NFAVertex> &tugs) {
if (allPredsInSubgraph(v, g, involved)) {
// We can transform this vertex into a tug trigger in-place.
DEBUG_PRINTF("all preds in subgraph, vertex %u becomes tug\n",
DEBUG_PRINTF("all preds in subgraph, vertex %zu becomes tug\n",
g[v].index);
add_edge(cyclic, v, g);
tugs.push_back(v);
@@ -631,7 +637,7 @@ void buildTugTrigger(NGHolder &g, NFAVertex cyclic, NFAVertex v,
NFAVertex t = clone_vertex(g, v);
depths[t] = depths[v];
DEBUG_PRINTF("there are other paths, cloned tug %u from vertex %u\n",
DEBUG_PRINTF("there are other paths, cloned tug %zu from vertex %zu\n",
g[t].index, g[v].index);
tugs.push_back(t);
@@ -648,7 +654,7 @@ NFAVertex createCyclic(NGHolder &g, ReachSubgraph &rsi) {
NFAVertex cyclic = clone_vertex(g, last);
add_edge(cyclic, cyclic, g);
DEBUG_PRINTF("created cyclic vertex %u\n", g[cyclic].index);
DEBUG_PRINTF("created cyclic vertex %zu\n", g[cyclic].index);
return cyclic;
}
@@ -659,7 +665,7 @@ NFAVertex createPos(NGHolder &g, ReachSubgraph &rsi) {
g[pos].char_reach = g[first].char_reach;
DEBUG_PRINTF("created pos vertex %u\n", g[pos].index);
DEBUG_PRINTF("created pos vertex %zu\n", g[pos].index);
return pos;
}
@@ -705,7 +711,7 @@ void unpeelNearEnd(NGHolder &g, ReachSubgraph &rsi,
NFAVertex d = clone_vertex(g, last);
depths[d] = depths[last];
DEBUG_PRINTF("created vertex %u\n", g[d].index);
DEBUG_PRINTF("created vertex %zu\n", g[d].index);
for (auto v : *succs) {
add_edge(d, v, g);
@@ -946,7 +952,7 @@ bool peelSubgraph(const NGHolder &g, const Grey &grey, ReachSubgraph &rsi,
zap = it;
break;
} else {
DEBUG_PRINTF("%u is involved in another repeat\n", g[*it].index);
DEBUG_PRINTF("%zu is involved in another repeat\n", g[*it].index);
}
}
DEBUG_PRINTF("peeling %zu vertices from front\n",
@@ -963,7 +969,7 @@ bool peelSubgraph(const NGHolder &g, const Grey &grey, ReachSubgraph &rsi,
zap = it.base(); // Note: erases everything after it.
break;
} else {
DEBUG_PRINTF("%u is involved in another repeat\n", g[*it].index);
DEBUG_PRINTF("%zu is involved in another repeat\n", g[*it].index);
}
}
DEBUG_PRINTF("peeling %zu vertices from back\n",
@@ -974,7 +980,7 @@ bool peelSubgraph(const NGHolder &g, const Grey &grey, ReachSubgraph &rsi,
// no-no.
for (auto v : rsi.vertices) {
if (contains(created, v)) {
DEBUG_PRINTF("vertex %u is in another repeat\n", g[v].index);
DEBUG_PRINTF("vertex %zu is in another repeat\n", g[v].index);
return false;
}
}
@@ -997,7 +1003,7 @@ void peelStartDotStar(const NGHolder &g,
NFAVertex first = rsi.vertices.front();
if (depths.at(first).fromStartDotStar.min == depth(1)) {
DEBUG_PRINTF("peeling start front vertex %u\n", g[first].index);
DEBUG_PRINTF("peeling start front vertex %zu\n", g[first].index);
rsi.vertices.erase(rsi.vertices.begin());
reprocessSubgraph(g, grey, rsi);
}
@@ -1006,8 +1012,8 @@ void peelStartDotStar(const NGHolder &g,
static
void buildReachSubgraphs(const NGHolder &g, vector<ReachSubgraph> &rs,
const u32 minNumVertices) {
const ReachFilter<NFAGraph> fil(&g.g);
const RepeatGraph rg(g.g, fil);
const ReachFilter<NGHolder> fil(&g);
const RepeatGraph rg(g, fil);
if (!isCompBigEnough(rg, minNumVertices)) {
DEBUG_PRINTF("component not big enough, bailing\n");
@@ -1015,19 +1021,17 @@ void buildReachSubgraphs(const NGHolder &g, vector<ReachSubgraph> &rs,
}
NFAUndirectedGraph ug;
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> old2new;
ue2::unordered_map<u32, NFAVertex> newIdx2old;
createUnGraph(rg, true, true, ug, old2new, newIdx2old);
unordered_map<RepeatGraph::vertex_descriptor, NFAUndirectedVertex> old2new;
createUnGraph(rg, true, true, ug, old2new);
ue2::unordered_map<NFAUndirectedVertex, u32> repeatMap;
unordered_map<NFAUndirectedVertex, u32> repeatMap;
unsigned int num;
num = connected_components(ug, make_assoc_property_map(repeatMap));
DEBUG_PRINTF("found %u connected repeat components\n", num);
// Now, we build a set of topo-ordered ReachSubgraphs.
vector<NFAVertex> topoOrder;
buildTopoOrder(rg, topoOrder);
vector<NFAVertex> topoOrder = buildTopoOrder(rg);
rs.resize(num);
@@ -1078,7 +1082,7 @@ bool entered_at_fixed_offset(NFAVertex v, const NGHolder &g,
if (is_triggered(g) && !contains(reached_by_fixed_tops, v)) {
/* can't do this for infix/suffixes unless we know trigger literals
* can only occur at one offset */
DEBUG_PRINTF("bad top(s) for %u\n", g[v].index);
DEBUG_PRINTF("bad top(s) for %zu\n", g[v].index);
return false;
}
@@ -1098,8 +1102,8 @@ bool entered_at_fixed_offset(NFAVertex v, const NGHolder &g,
for (auto u : inv_adjacent_vertices_range(v, g)) {
const depth &u_max_depth = depths.at(u).fromStart.max;
DEBUG_PRINTF("pred %u max depth %s from start\n",
g[u].index, u_max_depth.str().c_str());
DEBUG_PRINTF("pred %zu max depth %s from start\n", g[u].index,
u_max_depth.str().c_str());
if (u_max_depth != first - depth(1)) {
return false;
}
@@ -1122,7 +1126,7 @@ NFAVertex buildTriggerStates(NGHolder &g, const vector<CharReach> &trigger,
u = v;
}
DEBUG_PRINTF("trigger len=%zu has sink %u\n", trigger.size(), g[u].index);
DEBUG_PRINTF("trigger len=%zu has sink %zu\n", trigger.size(), g[u].index);
return u;
}
@@ -1252,7 +1256,7 @@ void buildRepeatGraph(NGHolder &rg,
if (is_triggered(rg)) {
// Add vertices for all our triggers
addTriggers(rg, triggers);
rg.renumberVertices();
renumber_vertices(rg);
// We don't know anything about how often this graph is triggered, so we
// make the start vertex cyclic for the purposes of this analysis ONLY.
@@ -1274,30 +1278,26 @@ void buildInputGraph(NGHolder &lhs,
ue2::unordered_map<NFAVertex, NFAVertex> &lhs_map,
const NGHolder &g, const NFAVertex first,
const map<u32, vector<vector<CharReach>>> &triggers) {
DEBUG_PRINTF("building lhs with first=%u\n", g[first].index);
DEBUG_PRINTF("building lhs with first=%zu\n", g[first].index);
cloneHolder(lhs, g, &lhs_map);
assert(g.kind == lhs.kind);
addTriggers(lhs, triggers);
lhs.renumberVertices();
renumber_vertices(lhs);
// Replace each back-edge (u,v) with an edge (startDs,v), which will
// generate entries at at least the rate of the loop created by that
// back-edge.
set<NFAEdge> dead;
BackEdges<set<NFAEdge> > backEdgeVisitor(dead);
depth_first_search(
lhs.g, visitor(backEdgeVisitor)
.root_vertex(lhs.start)
.vertex_index_map(get(&NFAGraphVertexProps::index, lhs.g)));
depth_first_search(lhs, visitor(backEdgeVisitor).root_vertex(lhs.start));
for (const auto &e : dead) {
const NFAVertex u = source(e, lhs), v = target(e, lhs);
if (u == v) {
continue; // Self-loops are OK.
}
DEBUG_PRINTF("replacing back-edge (%u,%u) with edge (startDs,%u)\n",
lhs[u].index, lhs[v].index,
lhs[v].index);
DEBUG_PRINTF("replacing back-edge (%zu,%zu) with edge (startDs,%zu)\n",
lhs[u].index, lhs[v].index, lhs[v].index);
add_edge_if_not_present(lhs.startDs, v, lhs);
remove_edge(e, lhs);
@@ -1384,13 +1384,13 @@ bool hasSoleEntry(const NGHolder &g, const ReachSubgraph &rsi,
for (const auto &v : rsi.vertices) {
assert(!is_special(v, g)); // no specials in repeats
assert(contains(rg_map, v));
DEBUG_PRINTF("rg vertex %u in repeat\n", rg[rg_map.at(v)].index);
DEBUG_PRINTF("rg vertex %zu in repeat\n", rg[rg_map.at(v)].index);
region_map.emplace(rg_map.at(v), repeat_region);
}
for (const auto &v : vertices_range(rg)) {
if (!contains(region_map, v)) {
DEBUG_PRINTF("rg vertex %u in lhs (trigger)\n", rg[v].index);
DEBUG_PRINTF("rg vertex %zu in lhs (trigger)\n", rg[v].index);
region_map.emplace(v, lhs_region);
}
}
@@ -1432,7 +1432,7 @@ struct StrawWalker {
if (next == v) { // Ignore self loop.
++ai;
if (ai == ae) {
return NFAGraph::null_vertex();
return NGHolder::null_vertex();
}
next = *ai;
}
@@ -1447,7 +1447,7 @@ struct StrawWalker {
succs.erase(v);
for (tie(ai, ae) = adjacent_vertices(v, g); ai != ae; ++ai) {
next = *ai;
DEBUG_PRINTF("checking %u\n", g[next].index);
DEBUG_PRINTF("checking %zu\n", g[next].index);
if (next == v) {
continue;
}
@@ -1468,32 +1468,31 @@ struct StrawWalker {
return next;
}
DEBUG_PRINTF("bailing\n");
return NFAGraph::null_vertex();
return NGHolder::null_vertex();
}
return next;
}
NFAVertex walk(NFAVertex v, vector<NFAVertex> &straw) const {
DEBUG_PRINTF("walk from %u\n", g[v].index);
DEBUG_PRINTF("walk from %zu\n", g[v].index);
ue2::unordered_set<NFAVertex> visited;
straw.clear();
while (!is_special(v, g)) {
DEBUG_PRINTF("checking %u\n", g[v].index);
DEBUG_PRINTF("checking %zu\n", g[v].index);
NFAVertex next = step(v);
if (next == NFAGraph::null_vertex()) {
if (next == NGHolder::null_vertex()) {
break;
}
if (!visited.insert(next).second) {
DEBUG_PRINTF("already visited %u, bailing\n",
g[next].index);
DEBUG_PRINTF("already visited %zu, bailing\n", g[next].index);
break; /* don't want to get stuck in any complicated loops */
}
const CharReach &reach_v = g[v].char_reach;
const CharReach &reach_next = g[next].char_reach;
if (!reach_v.isSubsetOf(reach_next)) {
DEBUG_PRINTF("%u's reach is not a superset of %u's\n",
DEBUG_PRINTF("%zu's reach is not a superset of %zu's\n",
g[next].index, g[v].index);
break;
}
@@ -1501,7 +1500,7 @@ struct StrawWalker {
// If this is cyclic with the right reach, we're done. Note that
// startDs fulfils this requirement.
if (hasSelfLoop(next, g) && !isBoundedRepeatCyclic(next)) {
DEBUG_PRINTF("found cyclic %u\n", g[next].index);
DEBUG_PRINTF("found cyclic %zu\n", g[next].index);
return next;
}
@@ -1510,7 +1509,7 @@ struct StrawWalker {
}
straw.clear();
return NFAGraph::null_vertex();
return NGHolder::null_vertex();
}
private:
@@ -1525,8 +1524,8 @@ static
NFAVertex walkStrawToCyclicRev(const NGHolder &g, NFAVertex v,
const vector<BoundedRepeatData> &all_repeats,
vector<NFAVertex> &straw) {
typedef boost::reverse_graph<NFAGraph, const NFAGraph&> RevGraph;
const RevGraph revg(g.g);
typedef boost::reverse_graph<NGHolder, const NGHolder &> RevGraph;
const RevGraph revg(g);
auto cyclic = StrawWalker<RevGraph>(g, revg, all_repeats).walk(v, straw);
reverse(begin(straw), end(straw)); // path comes from cyclic
@@ -1537,7 +1536,7 @@ static
NFAVertex walkStrawToCyclicFwd(const NGHolder &g, NFAVertex v,
const vector<BoundedRepeatData> &all_repeats,
vector<NFAVertex> &straw) {
return StrawWalker<NFAGraph>(g, g.g, all_repeats).walk(v, straw);
return StrawWalker<NGHolder>(g, g, all_repeats).walk(v, straw);
}
/** True if entries to this subgraph must pass through a cyclic state with
@@ -1553,7 +1552,7 @@ bool hasCyclicSupersetEntryPath(const NGHolder &g, const ReachSubgraph &rsi,
// until we encounter our cyclic, all of which must have superset reach.
vector<NFAVertex> straw;
return walkStrawToCyclicRev(g, rsi.vertices.front(), all_repeats, straw) !=
NFAGraph::null_vertex();
NGHolder::null_vertex();
}
static
@@ -1561,7 +1560,7 @@ bool hasCyclicSupersetExitPath(const NGHolder &g, const ReachSubgraph &rsi,
const vector<BoundedRepeatData> &all_repeats) {
vector<NFAVertex> straw;
return walkStrawToCyclicFwd(g, rsi.vertices.back(), all_repeats, straw) !=
NFAGraph::null_vertex();
NGHolder::null_vertex();
}
static
@@ -1844,7 +1843,7 @@ void buildFeeder(NGHolder &g, const BoundedRepeatData &rd,
add_edge(u, feeder, g);
}
DEBUG_PRINTF("added feeder %u\n", g[feeder].index);
DEBUG_PRINTF("added feeder %zu\n", g[feeder].index);
} else {
// No neg trigger means feeder is empty, and unnecessary.
assert(g[rd.pos_trigger].char_reach.all());
@@ -1892,13 +1891,13 @@ bool improveLeadingRepeat(NGHolder &g, BoundedRepeatData &rd,
// This transformation is only safe if the straw path from startDs that
// we've discovered can *only* lead to this repeat, since we're going to
// remove the self-loop on startDs.
if (hasGreaterOutDegree(2, g.startDs, g)) {
if (proper_out_degree(g.startDs, g) > 1) {
DEBUG_PRINTF("startDs has other successors\n");
return false;
}
for (const auto &v : straw) {
if (proper_out_degree(v, g) != 1) {
DEBUG_PRINTF("branch between startDs and repeat, from vertex %u\n",
DEBUG_PRINTF("branch between startDs and repeat, from vertex %zu\n",
g[v].index);
return false;
}
@@ -2068,8 +2067,8 @@ public:
const depth &our_depth_in)
: top_depths(top_depths_in), our_depth(our_depth_in) {}
void discover_vertex(NFAVertex v, UNUSED const NFAGraph &g) {
DEBUG_PRINTF("discovered %u (depth %s)\n", g[v].index,
void discover_vertex(NFAVertex v, UNUSED const NGHolder &g) {
DEBUG_PRINTF("discovered %zu (depth %s)\n", g[v].index,
our_depth.str().c_str());
auto it = top_depths.find(v);
@@ -2120,22 +2119,21 @@ void populateFixedTopInfo(const map<u32, u32> &fixed_depth_tops,
}
}
DEBUG_PRINTF("scanning from %u depth=%s\n", g[v].index,
DEBUG_PRINTF("scanning from %zu depth=%s\n", g[v].index,
td.str().c_str());
/* for each vertex reachable from v update its map to reflect that it is
* reachable from a top of depth td. */
depth_first_visit(
g.g, v, pfti_visitor(top_depths, td),
make_iterator_property_map(colours.begin(),
get(&NFAGraphVertexProps::index, g.g)));
depth_first_visit(g, v, pfti_visitor(top_depths, td),
make_iterator_property_map(colours.begin(),
get(vertex_index, g)));
}
for (const auto &v_depth : top_depths) {
const NFAVertex v = v_depth.first;
const depth &d = v_depth.second;
if (d.is_finite()) {
DEBUG_PRINTF("%u reached by fixed tops at depth %s\n",
DEBUG_PRINTF("%zu reached by fixed tops at depth %s\n",
g[v].index, d.str().c_str());
reached_by_fixed_tops->insert(v);
}
@@ -2152,19 +2150,16 @@ bool hasOverlappingRepeats(UNUSED const NGHolder &g,
for (const auto &br : repeats) {
if (contains(involved, br.cyclic)) {
DEBUG_PRINTF("already seen cyclic %u\n",
g[br.cyclic].index);
DEBUG_PRINTF("already seen cyclic %zu\n", g[br.cyclic].index);
return true;
}
if (contains(involved, br.pos_trigger)) {
DEBUG_PRINTF("already seen pos %u\n",
g[br.pos_trigger].index);
DEBUG_PRINTF("already seen pos %zu\n", g[br.pos_trigger].index);
return true;
}
for (auto v : br.tug_triggers) {
if (contains(involved, v)) {
DEBUG_PRINTF("already seen tug %u\n",
g[v].index);
DEBUG_PRINTF("already seen tug %zu\n", g[v].index);
return true;
}
}
@@ -2310,7 +2305,7 @@ void analyseRepeats(NGHolder &g, const ReportManager *rm,
// Go to town on the remaining acceptable subgraphs.
ue2::unordered_set<NFAVertex> created;
for (auto &rsi : rs) {
DEBUG_PRINTF("subgraph (beginning vertex %u) is a {%s,%s} repeat\n",
DEBUG_PRINTF("subgraph (beginning vertex %zu) is a {%s,%s} repeat\n",
g[rsi.vertices.front()].index,
rsi.repeatMin.str().c_str(), rsi.repeatMax.str().c_str());
@@ -2343,7 +2338,7 @@ void analyseRepeats(NGHolder &g, const ReportManager *rm,
// Some of our analyses require correctly numbered vertices, so we
// renumber after changes.
g.renumberVertices();
renumber_vertices(g);
}
bool modified_start_ds = false;
@@ -2384,8 +2379,8 @@ void analyseRepeats(NGHolder &g, const ReportManager *rm,
// We have modified the graph, so we need to ensure that our edges
// and vertices are correctly numbered.
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
// Remove stray report IDs.
clearReports(g);
}
@@ -2424,14 +2419,14 @@ bool isPureRepeat(const NGHolder &g, PureRepeat &repeat) {
// Must be start anchored.
assert(edge(g.startDs, g.startDs, g).second);
if (hasGreaterOutDegree(1, g.startDs, g)) {
if (out_degree(g.startDs, g) > 1) {
DEBUG_PRINTF("Unanchored\n");
return false;
}
// Must not be EOD-anchored.
assert(edge(g.accept, g.acceptEod, g).second);
if (hasGreaterInDegree(1, g.acceptEod, g)) {
if (in_degree(g.acceptEod, g) > 1) {
DEBUG_PRINTF("EOD anchored\n");
return false;
}

View File

@@ -52,11 +52,7 @@ namespace ue2 {
static
void wireStartToTops(NGHolder &g, const flat_set<NFAVertex> &tops,
vector<NFAEdge> &tempEdges) {
// Construct edges in vertex index order, for determinism.
vector<NFAVertex> ordered_tops(begin(tops), end(tops));
sort(begin(ordered_tops), end(ordered_tops), make_index_ordering(g));
for (NFAVertex v : ordered_tops) {
for (NFAVertex v : tops) {
assert(!isLeafNode(v, g));
const NFAEdge &e = add_edge(g.start, v, g).first;
@@ -102,7 +98,7 @@ void getStateOrdering(NGHolder &g, const flat_set<NFAVertex> &tops,
vector<NFAEdge> tempEdges;
wireStartToTops(g, tops, tempEdges);
renumberGraphVertices(g);
renumber_vertices(g);
vector<NFAVertex> temp = getTopoOrdering(g);
@@ -144,7 +140,7 @@ getStateIndices(const NGHolder &h, const vector<NFAVertex> &ordering) {
u32 stateNum = 0;
for (auto v : ordering) {
DEBUG_PRINTF("assigning state num %u to vertex %u\n", stateNum,
DEBUG_PRINTF("assigning state num %u to vertex %zu\n", stateNum,
h[v].index);
states[v] = stateNum++;
}
@@ -187,7 +183,7 @@ void optimiseTightLoops(const NGHolder &g, vector<NFAVertex> &ordering) {
continue;
}
DEBUG_PRINTF("moving vertex %u next to %u\n", g[v].index, g[u].index);
DEBUG_PRINTF("moving vertex %zu next to %zu\n", g[v].index, g[u].index);
ordering.erase(v_it);
ordering.insert(++u_it, v);

View File

@@ -538,7 +538,7 @@ void getRegionRoseLiterals(const NGHolder &g,
DEBUG_PRINTF("inspecting region %u\n", region);
set<ue2_literal> s;
for (auto v : vv) {
DEBUG_PRINTF(" exit vertex: %u\n", g[v].index);
DEBUG_PRINTF(" exit vertex: %zu\n", g[v].index);
/* Note: RHS can not be depended on to take all subsequent revisits
* to this vertex */
set<ue2_literal> ss = getLiteralSet(g, v, false);
@@ -573,8 +573,7 @@ void gatherBackEdges(const NGHolder &g,
ue2::unordered_map<NFAVertex, vector<NFAVertex>> *out) {
set<NFAEdge> backEdges;
BackEdges<set<NFAEdge>> be(backEdges);
depth_first_search(g.g, visitor(be).root_vertex(g.start).vertex_index_map(
get(&NFAGraphVertexProps::index, g.g)));
depth_first_search(g, visitor(be).root_vertex(g.start));
for (const auto &e : backEdges) {
(*out)[source(e, g)].push_back(target(e, g));
@@ -757,7 +756,7 @@ unique_ptr<VertLitInfo> LitCollection::pickNext() {
unique_ptr<VertLitInfo> rv = move(lits.back());
lits.pop_back();
poisonCandidates(*rv);
DEBUG_PRINTF("best is '%s' %u a%d t%d\n",
DEBUG_PRINTF("best is '%s' %zu a%d t%d\n",
dumpString(*(rv->lit.begin())).c_str(),
g[rv->vv.front()].index,
(int)createsAnchoredLHS(g, rv->vv, depths, grey),
@@ -863,8 +862,6 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
assert(delay <= lit.length());
DEBUG_PRINTF("managed delay %u (of max %u)\n", delay, max_delay);
// For determinism, we make sure that we create these edges from vertices
// in index-sorted order.
set<NFAVertex> pred;
for (auto v : curr) {
insert(&pred, inv_adjacent_vertices_range(v, g));
@@ -873,10 +870,7 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
clear_in_edges(g.accept, g);
clearReports(g);
vector<NFAVertex> verts(pred.begin(), pred.end());
sort(verts.begin(), verts.end(), VertexIndexOrdering<NGHolder>(g));
for (auto v : verts) {
for (auto v : pred) {
NFAEdge e = add_edge(v, g.accept, g).first;
g[v].reports.insert(0);
if (is_triggered(g) && v == g.start) {
@@ -921,8 +915,8 @@ void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
g[u].reports.insert(0);
}
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
assert(allMatchStatesHaveReports(g));
assert(isCorrectlyTopped(g));
}
@@ -1152,7 +1146,7 @@ void deanchorIfNeeded(NGHolder &g, bool *orig_anch) {
succ_g.erase(g.startDs);
for (auto v : adjacent_vertices_range(g.start, g)) {
DEBUG_PRINTF("inspecting cand %u || =%zu\n", g[v].index,
DEBUG_PRINTF("inspecting cand %zu || =%zu\n", g[v].index,
g[v].char_reach.size());
if (v == g.startDs || !g[v].char_reach.all()) {
@@ -1170,7 +1164,7 @@ void deanchorIfNeeded(NGHolder &g, bool *orig_anch) {
}
clear_vertex(v, g);
remove_vertex(v, g);
g.renumberVertices();
renumber_vertices(g);
return;
}
@@ -1701,7 +1695,7 @@ void splitEdgesByCut(RoseInGraph &ig, const vector<RoseInEdge> &to_cut,
/* TODO need to update v_mapping (if we were doing more cuts) */
}
DEBUG_PRINTF("splitting on pivot %u\n", h[pivot].index);
DEBUG_PRINTF("splitting on pivot %zu\n", h[pivot].index);
ue2::unordered_map<NFAVertex, NFAVertex> temp_map;
shared_ptr<NGHolder> new_lhs = make_shared<NGHolder>();
splitLHS(h, pivot, new_lhs.get(), &temp_map);
@@ -1774,8 +1768,8 @@ bool doNetflowCut(RoseInGraph &ig, const vector<RoseInEdge> &to_cut,
return false;
}
h.renumberVertices();
h.renumberEdges();
renumber_vertices(h);
renumber_edges(h);
/* Step 1: Get scores for all edges */
vector<u64a> scores = scoreEdges(h); /* scores by edge_index */
/* Step 2: poison scores for edges covered by successor literal */
@@ -2573,7 +2567,7 @@ bool followedByStar(const vector<NFAVertex> &vv, const NGHolder &g) {
static
bool isEodPrefixCandidate(const NGHolder &g) {
if (hasGreaterInDegree(0, g.accept, g)) {
if (in_degree(g.accept, g)) {
DEBUG_PRINTF("graph isn't eod anchored\n");
return false;
}
@@ -2644,7 +2638,7 @@ void processEodPrefixes(RoseInGraph &g) {
}
// TODO: handle cases with multiple out-edges.
if (hasGreaterOutDegree(1, source(e, g), g)) {
if (out_degree(source(e, g), g) > 1) {
continue;
}
@@ -2671,7 +2665,7 @@ void processEodPrefixes(RoseInGraph &g) {
}
for (auto v : accepts) {
if (!hasGreaterInDegree(0, v, g)) {
if (!in_degree(v, g)) {
remove_vertex(v, g);
}
}
@@ -2813,6 +2807,7 @@ unique_ptr<RoseInGraph> buildRose(const NGHolder &h, bool desperation,
dumpPreRoseGraph(ig, cc.grey);
renumber_vertices(ig);
calcVertexOffsets(ig);
return igp;
}
@@ -2829,6 +2824,7 @@ void desperationImprove(RoseInGraph &ig, const CompileContext &cc) {
handleLongMixedSensitivityLiterals(ig);
dedupe(ig);
pruneUseless(ig);
renumber_vertices(ig);
calcVertexOffsets(ig);
}
@@ -2839,8 +2835,7 @@ bool splitOffRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
}
// We should have at least one edge into accept or acceptEod!
assert(hasGreaterInDegree(0, h.accept, h) ||
hasGreaterInDegree(1, h.acceptEod, h));
assert(in_degree(h.accept, h) || in_degree(h.acceptEod, h) > 1);
unique_ptr<RoseInGraph> igp = buildRose(h, false, cc);
if (igp && rose.addRose(*igp, prefilter)) {
@@ -2932,6 +2927,7 @@ bool finalChanceRose(RoseBuild &rose, const NGHolder &h, bool prefilter,
add_edge(v, a, RoseInEdgeProps(rhs, 0U), ig);
}
renumber_vertices(ig);
calcVertexOffsets(ig);
return rose.addRose(ig, prefilter, true /* final chance */);
@@ -2944,8 +2940,7 @@ bool checkRose(const ReportManager &rm, const NGHolder &h, bool prefilter,
}
// We should have at least one edge into accept or acceptEod!
assert(hasGreaterInDegree(0, h.accept, h) ||
hasGreaterInDegree(1, h.acceptEod, h));
assert(in_degree(h.accept, h) || in_degree(h.acceptEod, h) > 1);
unique_ptr<RoseInGraph> igp;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -125,7 +125,7 @@ bool findLiterals(const NGHolder &g,
set<sls_literal> &out = built[g[v].index];
read_count[g[v].index] = out_degree(v, g);
DEBUG_PRINTF("setting read_count to %zu for %u\n",
DEBUG_PRINTF("setting read_count to %zu for %zu\n",
read_count[g[v].index], g[v].index);
assert(out.empty());
@@ -154,7 +154,7 @@ bool findLiterals(const NGHolder &g,
}
set<sls_literal> &in = built[g[u].index];
DEBUG_PRINTF("getting from %u (%zu reads to go)\n",
DEBUG_PRINTF("getting from %zu (%zu reads to go)\n",
g[u].index, read_count[g[u].index]);
assert(!in.empty());
assert(read_count[g[u].index]);
@@ -188,7 +188,7 @@ bool findLiterals(const NGHolder &g,
read_count[g[u].index]--;
if (!read_count[g[u].index]) {
DEBUG_PRINTF("clearing %u as finished reading\n", g[u].index);
DEBUG_PRINTF("clearing %zu as finished reading\n", g[u].index);
in.clear();
}
}

View File

@@ -110,7 +110,7 @@ bool regionCanEstablishSom(const NGHolder &g,
DEBUG_PRINTF("region %u\n", region);
for (UNUSED auto v : r_exits) {
DEBUG_PRINTF(" exit %u\n", g[v].index);
DEBUG_PRINTF(" exit %zu\n", g[v].index);
}
/* simple if each region exit is at fixed distance from SOM. Note SOM does
@@ -119,12 +119,12 @@ bool regionCanEstablishSom(const NGHolder &g,
assert(regions.at(v) == region);
const DepthMinMax &d = depths.at(g[v].index);
if (d.min != d.max) {
DEBUG_PRINTF("failing %u as %s != %s\n", g[v].index,
DEBUG_PRINTF("failing %zu as %s != %s\n", g[v].index,
d.min.str().c_str(), d.max.str().c_str());
return false;
}
}
DEBUG_PRINTF("region %u/%u is good\n", regions.at(r_exits[0]),
DEBUG_PRINTF("region %u/%zu is good\n", regions.at(r_exits[0]),
g[r_exits[0]].index);
return true;
@@ -178,10 +178,7 @@ void buildRegionMapping(const NGHolder &g,
set<NFAEdge> be;
BackEdges<set<NFAEdge> > backEdgeVisitor(be);
depth_first_search(
g.g, visitor(backEdgeVisitor)
.root_vertex(g.start)
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
boost::depth_first_search(g, visitor(backEdgeVisitor).root_vertex(g.start));
for (const auto &e : be) {
NFAVertex u = source(e, g);
@@ -208,17 +205,17 @@ void buildRegionMapping(const NGHolder &g,
r_i.optional ? " (optional)" : "");
DEBUG_PRINTF(" enters:");
for (u32 i = 0; i < r_i.enters.size(); i++) {
printf(" %u", g[r_i.enters[i]].index);
printf(" %zu", g[r_i.enters[i]].index);
}
printf("\n");
DEBUG_PRINTF(" exits:");
for (u32 i = 0; i < r_i.exits.size(); i++) {
printf(" %u", g[r_i.exits[i]].index);
printf(" %zu", g[r_i.exits[i]].index);
}
printf("\n");
DEBUG_PRINTF(" all:");
for (u32 i = 0; i < r_i.full.size(); i++) {
printf(" %u", g[r_i.full[i]].index);
printf(" %zu", g[r_i.full[i]].index);
}
printf("\n");
}
@@ -235,8 +232,7 @@ bool validateXSL(const NGHolder &g,
u32 v_region = regions.at(v);
if (!is_special(v, g) && v_region > region &&
(escapes & g[v].char_reach).any()) {
DEBUG_PRINTF("problem with escapes for %u\n",
g[v].index);
DEBUG_PRINTF("problem with escapes for %zu\n", g[v].index);
first_bad_region = MIN(first_bad_region, v_region);
}
}
@@ -402,7 +398,7 @@ makePrefix(const NGHolder &g, const ue2::unordered_map<NFAVertex, u32> &regions,
vector<NFAVertex> to_clear;
assert(contains(lhs_map, curr_exits.front()));
NFAVertex p_u = lhs_map[curr_exits.front()];
DEBUG_PRINTF("p_u: %u\n", prefix[p_u].index);
DEBUG_PRINTF("p_u: %zu\n", prefix[p_u].index);
for (auto p_v : adjacent_vertices_range(p_u, prefix)) {
auto v = rev_map.at(p_v);
if (p_v == prefix.accept || regions.at(v) < dead_region) {
@@ -412,7 +408,7 @@ makePrefix(const NGHolder &g, const ue2::unordered_map<NFAVertex, u32> &regions,
}
for (auto v : to_clear) {
DEBUG_PRINTF("clearing in_edges on %u\n", prefix[v].index);
DEBUG_PRINTF("clearing in_edges on %zu\n", prefix[v].index);
clear_in_edges(v, prefix);
}
@@ -575,7 +571,7 @@ void replaceExternalReportsWithSomRep(ReportManager &rm, NGHolder &g,
ir.somDistance = param;
ReportID rep = rm.getInternalId(ir);
DEBUG_PRINTF("vertex %u, replacing report %u with %u (type %u)\n",
DEBUG_PRINTF("vertex %zu, replacing report %u with %u (type %u)\n",
g[v].index, report_id, rep, ir_type);
r_new.insert(rep);
}
@@ -713,7 +709,7 @@ void fillHolderForLockCheck(NGHolder *out, const NGHolder &g,
/* add all vertices in region, create mapping */
for (auto v : jt->second.full) {
DEBUG_PRINTF("adding v %u to midfix\n", g[v].index);
DEBUG_PRINTF("adding v %zu to midfix\n", g[v].index);
if (contains(v_map, v)) {
continue;
}
@@ -758,7 +754,7 @@ void fillHolderForLockCheck(NGHolder *out, const NGHolder &g,
}
assert(in_degree(midfix.accept, midfix));
midfix.renumberVertices();
renumber_vertices(midfix);
}
static
@@ -785,7 +781,7 @@ void fillRoughMidfix(NGHolder *out, const NGHolder &g,
/* add all vertices in region, create mapping */
for (auto v : jt->second.full) {
DEBUG_PRINTF("adding v %u to midfix\n", g[v].index);
DEBUG_PRINTF("adding v %zu to midfix\n", g[v].index);
NFAVertex vnew = add_vertex(g[v], midfix);
v_map[v] = vnew;
}
@@ -825,7 +821,7 @@ void fillRoughMidfix(NGHolder *out, const NGHolder &g,
do {
for (auto v : jt->second.exits) {
DEBUG_PRINTF("adding v %u to midfix\n", g[v].index);
DEBUG_PRINTF("adding v %zu to midfix\n", g[v].index);
NFAVertex vnew = add_vertex(g[v], midfix);
v_map[v] = vnew;
@@ -1012,8 +1008,7 @@ bool addPlan(vector<som_plan> &plan, u32 parent) {
// Fetches all preds of {accept, acceptEod} for this graph.
static
void addReporterVertices(const NGHolder &g, vector<NFAVertex> &reporters) {
// Order reporter vertices by index for determinism.
set<NFAVertex, VertexIndexOrdering<NGHolder> > tmp(g);
set<NFAVertex> tmp;
insert(&tmp, inv_adjacent_vertices(g.accept, g));
insert(&tmp, inv_adjacent_vertices(g.acceptEod, g));
tmp.erase(g.accept);
@@ -1021,7 +1016,7 @@ void addReporterVertices(const NGHolder &g, vector<NFAVertex> &reporters) {
#ifdef DEBUG
DEBUG_PRINTF("add reporters:");
for (UNUSED auto v : tmp) {
printf(" %u", g[v].index);
printf(" %zu", g[v].index);
}
printf("\n");
#endif
@@ -1035,7 +1030,7 @@ void addReporterVertices(const region_info &r, const NGHolder &g,
vector<NFAVertex> &reporters) {
for (auto v : r.exits) {
if (edge(v, g.accept, g).second || edge(v, g.acceptEod, g).second) {
DEBUG_PRINTF("add reporter %u\n", g[v].index);
DEBUG_PRINTF("add reporter %zu\n", g[v].index);
reporters.push_back(v);
}
}
@@ -1048,7 +1043,7 @@ void addMappedReporterVertices(const region_info &r, const NGHolder &g,
vector<NFAVertex> &reporters) {
for (auto v : r.exits) {
if (edge(v, g.accept, g).second || edge(v, g.acceptEod, g).second) {
DEBUG_PRINTF("adding v=%u\n", g[v].index);
DEBUG_PRINTF("adding v=%zu\n", g[v].index);
ue2::unordered_map<NFAVertex, NFAVertex>::const_iterator it =
mapping.find(v);
assert(it != mapping.end());
@@ -1105,7 +1100,7 @@ void expandGraph(NGHolder &g, ue2::unordered_map<NFAVertex, u32> &regions,
}
for (auto enter : enters) {
DEBUG_PRINTF("processing enter %u\n", g[enter].index);
DEBUG_PRINTF("processing enter %zu\n", g[enter].index);
map<NFAVertex, NFAVertex> orig_to_copy;
// Make a copy of all of the tail vertices, storing region info along
@@ -1155,7 +1150,7 @@ void expandGraph(NGHolder &g, ue2::unordered_map<NFAVertex, u32> &regions,
[&](const NFAEdge &e) {
NFAVertex u = source(e, g);
return regions.at(u) < split_region;
}, g.g);
}, g);
}
new_enters.push_back(orig_to_copy[enter]);
@@ -1327,7 +1322,7 @@ bool doTreePlanning(NGHolder &g,
dumpHolder(g, g_regions, 14, "som_expandedtree", grey);
for (auto v : enters) {
DEBUG_PRINTF("enter %u\n", g[v].index);
DEBUG_PRINTF("enter %zu\n", g[v].index);
// For this entry vertex, construct a version of the graph without the
// other entries in this region (g_path), and calculate its depths and
@@ -1562,12 +1557,12 @@ void dumpSomPlan(UNUSED const NGHolder &g, UNUSED const som_plan &p,
p.is_reset, p.parent);
printf(" reporters:");
for (auto v : p.reporters) {
printf(" %u", g[v].index);
printf(" %zu", g[v].index);
}
printf("\n");
printf(" reporters_in:");
for (auto v : p.reporters_in) {
printf(" %u", g[v].index);
printf(" %zu", g[v].index);
}
printf("\n");
#endif
@@ -1633,7 +1628,7 @@ void implementSomPlan(NG &ng, const NGWrapper &w, u32 comp_id, NGHolder &g,
/* create prefix to set the som_loc */
if (!plan.front().no_implement) {
plan.front().prefix->renumberVertices();
renumber_vertices(*plan.front().prefix);
assert(plan.front().prefix->kind == NFA_OUTFIX);
if (!ng.addHolder(*plan.front().prefix)) {
throw CompileError(w.expressionIndex, "Pattern is too large.");
@@ -1745,7 +1740,7 @@ aligned_unique_ptr<NFA> makeBareSomRevNfa(const NGHolder &g,
setZeroReports(g_rev);
// Prep for actual construction.
g_rev.renumberVertices();
renumber_vertices(g_rev);
g_rev.kind = NFA_REV_PREFIX;
reduceGraphEquivalences(g_rev, cc);
removeRedundancy(g_rev, SOM_NONE);
@@ -1785,7 +1780,7 @@ bool makeSomRevNfa(vector<SomRevNfa> &som_nfas, const NGHolder &g,
return true;
}
g2.renumberVertices(); // for findMinWidth, findMaxWidth.
renumber_vertices(g2); // for findMinWidth, findMaxWidth.
aligned_unique_ptr<NFA> nfa = makeBareSomRevNfa(g2, cc);
if (!nfa) {
@@ -2220,7 +2215,7 @@ bool leadingLiterals(const NGHolder &g, set<ue2_literal> *lits,
for (const auto &m : curr) {
const NFAVertex u = m.first;
const vector<ue2_literal> &base = m.second;
DEBUG_PRINTF("expanding from %u\n", g[u].index);
DEBUG_PRINTF("expanding from %zu\n", g[u].index);
for (auto v : adjacent_vertices_range(u, g)) {
if (v == g.startDs) {
continue;
@@ -2233,8 +2228,7 @@ bool leadingLiterals(const NGHolder &g, set<ue2_literal> *lits,
DEBUG_PRINTF("match\n");
goto skip_to_next_terminal;
}
if (g[v].char_reach.count()
> 2 * MAX_LEADING_LITERALS) {
if (g[v].char_reach.count() > 2 * MAX_LEADING_LITERALS) {
DEBUG_PRINTF("wide\n");
goto skip_to_next_terminal;
}
@@ -2250,8 +2244,8 @@ bool leadingLiterals(const NGHolder &g, set<ue2_literal> *lits,
CharReach cr = g[v].char_reach;
vector<ue2_literal> &out = next[v];
DEBUG_PRINTF("expanding to %u (|| = %zu)\n",
g[v].index, cr.count());
DEBUG_PRINTF("expanding to %zu (|| = %zu)\n", g[v].index,
cr.count());
for (size_t c = cr.find_first(); c != CharReach::npos;
c = cr.find_next(c)) {
bool nocase = ourisalpha(c) && cr.test(mytoupper(c))
@@ -2327,7 +2321,7 @@ bool splitOffLeadingLiterals(const NGHolder &g, set<ue2_literal> *lit_out,
set<NFAVertex> adj_term1;
insert(&adj_term1, adjacent_vertices(*terms.begin(), g));
for (auto v : terms) {
DEBUG_PRINTF("term %u\n", g[v].index);
DEBUG_PRINTF("term %zu\n", g[v].index);
set<NFAVertex> temp;
insert(&temp, adjacent_vertices(v, g));
if (temp != adj_term1) {
@@ -2354,7 +2348,7 @@ void findBestLiteral(const NGHolder &g,
buildRegionMapping(g, regions, info, false);
ue2_literal best;
NFAVertex best_v = nullptr;
NFAVertex best_v = NGHolder::null_vertex();
map<u32, region_info>::const_iterator lit = info.begin();
while (1) {
@@ -2390,7 +2384,7 @@ bool splitOffBestLiteral(const NGHolder &g,
const ue2::unordered_map<NFAVertex, u32> &regions,
ue2_literal *lit_out, NGHolder *lhs, NGHolder *rhs,
const CompileContext &cc) {
NFAVertex v = nullptr;
NFAVertex v = NGHolder::null_vertex();
findBestLiteral(g, regions, lit_out, &v, cc);
if (lit_out->empty()) {
@@ -2404,7 +2398,7 @@ bool splitOffBestLiteral(const NGHolder &g,
splitGraph(g, v, lhs, &lhs_map, rhs, &rhs_map);
DEBUG_PRINTF("v = %u\n", g[v].index);
DEBUG_PRINTF("v = %zu\n", g[v].index);
return true;
}
@@ -2624,7 +2618,7 @@ bool doHaigLitHaigSom(NG &ng, NGHolder &g,
}
} else {
DEBUG_PRINTF("has start->accept edge\n");
if (hasGreaterInDegree(1, g.acceptEod, g)) {
if (in_degree(g.acceptEod, g) > 1) {
DEBUG_PRINTF("also has a path to EOD\n");
return false;
}
@@ -2825,7 +2819,7 @@ map<u32, region_info>::const_iterator tryForLaterRevNfaCut(const NGHolder &g,
reverseHolder(*prefix, g_rev);
anchorStarts(g_rev);
g_rev.renumberVertices();
renumber_vertices(g_rev);
g_rev.kind = NFA_REV_PREFIX;
reduceGraphEquivalences(g_rev, cc);
removeRedundancy(g_rev, SOM_NONE);
@@ -2869,7 +2863,7 @@ unique_ptr<NGHolder> makePrefixForChain(NGHolder &g,
}
depths->clear(); /* renumbering invalidates depths */
prefix->renumberVertices();
renumber_vertices(*prefix);
DEBUG_PRINTF("done\n");
return prefix;
@@ -2885,8 +2879,7 @@ sombe_rv doSom(NG &ng, NGHolder &g, const NGWrapper &w, u32 comp_id,
// Special case: if g is completely anchored or begins with a dot-star, we
// know that we have an absolute SOM of zero all the time.
assert(edge(g.startDs, g.startDs, g).second);
if (!hasGreaterOutDegree(1, g.startDs, g) || beginsWithDotStar(g)) {
if (!proper_out_degree(g.startDs, g) || beginsWithDotStar(g)) {
makeSomAbsReports(rm, g, g.accept);
makeSomAbsReports(rm, g, g.acceptEod);
return SOMBE_HANDLED_INTERNAL;
@@ -3003,7 +2996,7 @@ sombe_rv doSom(NG &ng, NGHolder &g, const NGWrapper &w, u32 comp_id,
u32 rev_comp_id = doSomRevNfaPrefix(ng, w, *prefix, cc);
updatePrefixReportsRevNFA(rm, *prefix, rev_comp_id);
}
prefix->renumberVertices();
renumber_vertices(*prefix);
if (!ng.addHolder(*prefix)) {
DEBUG_PRINTF("failed to add holder\n");
clear_graph(g);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -155,13 +155,13 @@ bool addSomRedundancy(NGHolder &g, vector<DepthMinMax> &depths) {
if (is_special(v, g)) {
continue;
}
if (!hasGreaterInDegree(0, v, g)) {
if (!in_degree(v, g)) {
continue; // unreachable, probably killed
}
const DepthMinMax &d = getDepth(v, g, depths);
DEBUG_PRINTF("vertex %u has depths %s\n", g[v].index,
DEBUG_PRINTF("vertex %zu has depths %s\n", g[v].index,
d.str().c_str());
if (d.min == d.max) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -76,7 +76,7 @@ vector<DepthMinMax> getDistancesFromSOM(const NGHolder &g_orig) {
clear_in_edges(v, g);
}
//dumpGraph("som_depth.dot", g.g);
//dumpGraph("som_depth.dot", g);
vector<DepthMinMax> temp_depths; // numbered by vertex index in g
calcDepthsFrom(g, g.start, temp_depths);
@@ -143,7 +143,7 @@ bool firstMatchIsFirst(const NGHolder &p) {
for (auto v : vertices_range(p)) {
assert(!is_virtual_start(v, p));
if (!is_special(v, p)) {
DEBUG_PRINTF("turning on %u\n", p[v].index);
DEBUG_PRINTF("turning on %zu\n", p[v].index);
states.insert(v);
}
}
@@ -154,9 +154,9 @@ bool firstMatchIsFirst(const NGHolder &p) {
for (auto v : states) {
/* need to check if this vertex may represent an infix match - ie
* it does not have an edge to accept. */
DEBUG_PRINTF("check %u\n", p[v].index);
DEBUG_PRINTF("check %zu\n", p[v].index);
if (!edge(v, p.accept, p).second) {
DEBUG_PRINTF("fail %u\n", p[v].index);
DEBUG_PRINTF("fail %zu\n", p[v].index);
return false;
}
}
@@ -186,14 +186,11 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &g,
return cache.smgb[u];
}
DEBUG_PRINTF("checking if som can go backwards on %u\n", g[u].index);
DEBUG_PRINTF("checking if som can go backwards on %zu\n", g[u].index);
set<NFAEdge> be;
BackEdges<set<NFAEdge>> backEdgeVisitor(be);
depth_first_search(
g.g, visitor(backEdgeVisitor)
.root_vertex(g.start)
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
boost::depth_first_search(g, visitor(backEdgeVisitor).root_vertex(g.start));
bool rv;
if (0) {
@@ -210,8 +207,7 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &g,
NFAVertex s = source(e, g);
NFAVertex t = target(e, g);
/* only need to worry about big cycles including/before u */
DEBUG_PRINTF("back edge %u %u\n", g[s].index,
g[t].index);
DEBUG_PRINTF("back edge %zu %zu\n", g[s].index, g[t].index);
if (s != t && region_map.at(s) <= u_region) {
DEBUG_PRINTF("eek big cycle\n");
rv = true; /* big cycle -> eek */
@@ -268,13 +264,13 @@ bool somMayGoBackwards(NFAVertex u, const NGHolder &g,
pruneUseless(c_g);
be.clear();
depth_first_search(c_g.g, visitor(backEdgeVisitor).root_vertex(c_g.start).
vertex_index_map(get(&NFAGraphVertexProps::index, c_g.g)));
boost::depth_first_search(c_g, visitor(backEdgeVisitor)
.root_vertex(c_g.start));
for (const auto &e : be) {
NFAVertex s = source(e, c_g);
NFAVertex t = target(e, c_g);
DEBUG_PRINTF("back edge %u %u\n", c_g[s].index, c_g[t].index);
DEBUG_PRINTF("back edge %zu %zu\n", c_g[s].index, c_g[t].index);
if (s != t) {
assert(0);
DEBUG_PRINTF("eek big cycle\n");
@@ -326,7 +322,7 @@ bool sentClearsTail(const NGHolder &g,
}
for (UNUSED auto v : states) {
DEBUG_PRINTF("start state: %u\n", g[v].index);
DEBUG_PRINTF("start state: %zu\n", g[v].index);
}
/* run the prefix the main graph */
@@ -338,7 +334,7 @@ bool sentClearsTail(const NGHolder &g,
continue; /* not in tail */
}
DEBUG_PRINTF("v %u is still on\n", g[v].index);
DEBUG_PRINTF("v %zu is still on\n", g[v].index);
assert(v != g.accept && v != g.acceptEod); /* no cr */
assert(contains(region_map, v));

View File

@@ -87,7 +87,7 @@ void splitLHS(const NGHolder &base, const vector<NFAVertex> &pivots,
clearAccepts(*lhs);
for (auto pivot : pivots) {
DEBUG_PRINTF("pivot is %u lv %zu lm %zu\n", base[pivot].index,
DEBUG_PRINTF("pivot is %zu lv %zu lm %zu\n", base[pivot].index,
num_vertices(*lhs), lhs_map->size());
assert(contains(*lhs_map, pivot));
@@ -191,8 +191,8 @@ void findCommonSuccessors(const NGHolder &g, const vector<NFAVertex> &pivots,
vector<NFAVertex> &succ) {
assert(!pivots.empty());
// Note: for determinism, we must sort our successor sets by vertex_index.
set<NFAVertex, VertexIndexOrdering<NGHolder> > adj(g), adj_temp(g);
set<NFAVertex> adj;
set<NFAVertex> adj_temp;
insert(&adj, adjacent_vertices(pivots.at(0), g));

View File

@@ -134,8 +134,7 @@ void buildPDomTree(const NGHolder &g, PostDomTree &tree) {
}
NFAVertex pdom = postdominators[v];
if (pdom) {
DEBUG_PRINTF("vertex %u -> %u\n", g[pdom].index,
g[v].index);
DEBUG_PRINTF("vertex %zu -> %zu\n", g[pdom].index, g[v].index);
tree[pdom].insert(v);
}
}
@@ -153,8 +152,7 @@ void buildSquashMask(NFAStateSet &mask, const NGHolder &g, NFAVertex v,
som_type som, const vector<DepthMinMax> &som_depths,
const ue2::unordered_map<NFAVertex, u32> &region_map,
smgb_cache &cache) {
DEBUG_PRINTF("build base squash mask for vertex %u)\n",
g[v].index);
DEBUG_PRINTF("build base squash mask for vertex %zu)\n", g[v].index);
vector<NFAVertex> q;
@@ -301,7 +299,7 @@ void findDerivedSquashers(const NGHolder &g, const vector<NFAVertex> &vByIndex,
}
NFAStateSet u_squash(init.size());
u32 u_index = g[u].index;
size_t u_index = g[u].index;
buildSquashMask(u_squash, g, u, g[u].char_reach, init, vByIndex,
pdom_tree, som, som_depths, region_map, cache);
@@ -309,7 +307,7 @@ void findDerivedSquashers(const NGHolder &g, const vector<NFAVertex> &vByIndex,
u_squash.set(u_index); /* never clear ourselves */
if ((~u_squash).any()) { // i.e. some bits unset in mask
DEBUG_PRINTF("%u is an upstream squasher of %u\n", u_index,
DEBUG_PRINTF("%zu is an upstream squasher of %zu\n", u_index,
g[v].index);
(*squash)[u] = u_squash;
remaining.push_back(u);
@@ -521,8 +519,7 @@ void filterSquashers(const NGHolder &g,
if (!contains(squash, v)) {
continue;
}
DEBUG_PRINTF("looking at squash set for vertex %u\n",
g[v].index);
DEBUG_PRINTF("looking at squash set for vertex %zu\n", g[v].index);
if (!hasSelfLoop(v, g)) {
DEBUG_PRINTF("acyclic\n");
@@ -600,7 +597,7 @@ void removeEdgesToAccept(NGHolder &g, NFAVertex v) {
NFAVertex u = source(e, g);
const auto &r = g[u].reports;
if (!r.empty() && is_subset_of(r, reports)) {
DEBUG_PRINTF("vertex %u\n", g[u].index);
DEBUG_PRINTF("vertex %zu\n", g[u].index);
dead.insert(e);
}
}
@@ -609,7 +606,7 @@ void removeEdgesToAccept(NGHolder &g, NFAVertex v) {
NFAVertex u = source(e, g);
const auto &r = g[u].reports;
if (!r.empty() && is_subset_of(r, reports)) {
DEBUG_PRINTF("vertex %u\n", g[u].index);
DEBUG_PRINTF("vertex %zu\n", g[u].index);
dead.insert(e);
}
}
@@ -620,7 +617,7 @@ void removeEdgesToAccept(NGHolder &g, NFAVertex v) {
static
vector<NFAVertex> findUnreachable(const NGHolder &g) {
const boost::reverse_graph<NFAGraph, const NFAGraph &> revg(g.g);
const boost::reverse_graph<NGHolder, const NGHolder &> revg(g);
ue2::unordered_map<NFAVertex, boost::default_color_type> colours;
colours.reserve(num_vertices(g));
@@ -633,7 +630,7 @@ vector<NFAVertex> findUnreachable(const NGHolder &g) {
vector<NFAVertex> unreach;
for (auto v : vertices_range(revg)) {
if (!contains(colours, v)) {
unreach.push_back(v);
unreach.push_back(NFAVertex(v));
}
}
return unreach;
@@ -656,7 +653,7 @@ findHighlanderSquashers(const NGHolder &g, const ReportManager &rm) {
const u32 numStates = num_vertices(g);
for (auto v : verts) {
DEBUG_PRINTF("vertex %u with %zu reports\n", g[v].index,
DEBUG_PRINTF("vertex %zu with %zu reports\n", g[v].index,
g[v].reports.size());
// Find the set of vertices that lead to v or any other reporter with a
@@ -683,7 +680,7 @@ findHighlanderSquashers(const NGHolder &g, const ReportManager &rm) {
NFAStateSet &mask = squash[v];
for (auto uv : unreach) {
DEBUG_PRINTF("squashes index %u\n", h[uv].index);
DEBUG_PRINTF("squashes index %zu\n", h[uv].index);
mask.reset(h[uv].index);
}
}

View File

@@ -259,7 +259,7 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
vmap[vic.startDs] = dest.startDs;
vmap[vic.accept] = dest.accept;
vmap[vic.acceptEod] = dest.acceptEod;
vmap[nullptr] = nullptr;
vmap[NGHolder::null_vertex()] = NGHolder::null_vertex();
// For vertices in the common len, add to vmap and merge in the reports, if
// any.
@@ -312,7 +312,7 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
in_common_region = true;
}
DEBUG_PRINTF("adding idx=%u (state %u) -> idx=%u (state %u)%s\n",
DEBUG_PRINTF("adding idx=%zu (state %u) -> idx=%zu (state %u)%s\n",
dest[u].index, dest_info.get(u),
dest[v].index, dest_info.get(v),
in_common_region ? " [common]" : "");
@@ -338,8 +338,8 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
add_edge(u, v, vic[e], dest);
}
dest.renumberEdges();
dest.renumberVertices();
renumber_edges(dest);
renumber_vertices(dest);
}
namespace {

View File

@@ -36,14 +36,13 @@
#include <map>
#include <vector>
#include "nfagraph/ng_graph.h"
#include "nfagraph/ng_holder.h"
#include "util/ue2_containers.h"
namespace ue2 {
struct CompileContext;
struct Grey;
class NGHolder;
class ReportManager;
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Intel Corporation
* Copyright (c) 2015-2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -39,6 +39,10 @@
#include "util/graph_range.h"
#include "util/ue2_containers.h"
#include <vector>
#include <boost/graph/adjacency_list.hpp>
namespace ue2 {
/**
@@ -51,7 +55,7 @@ namespace ue2 {
typedef boost::adjacency_list<boost::setS, // out edges
boost::listS, // vertices
boost::undirectedS, // graph is undirected
boost::property<boost::vertex_index_t, u32> >
boost::property<boost::vertex_index_t, size_t> >
NFAUndirectedGraph;
typedef NFAUndirectedGraph::vertex_descriptor NFAUndirectedVertex;
@@ -60,16 +64,18 @@ typedef NFAUndirectedGraph::vertex_descriptor NFAUndirectedVertex;
* Make a copy of an NFAGraph with undirected edges, optionally without start
* vertices. Mappings from the original graph to the new one are provided.
*
* Note that new vertex indices are assigned contiguously in \a vertices(g) order.
* Note that new vertex indices are assigned contiguously in \a vertices(g)
* order.
*/
template <typename GraphT>
void createUnGraph(const GraphT &g,
bool excludeStarts,
bool excludeAccepts,
NFAUndirectedGraph &ug,
ue2::unordered_map<NFAVertex, NFAUndirectedVertex> &old2new,
ue2::unordered_map<u32, NFAVertex> &newIdx2old) {
u32 idx = 0;
bool excludeStarts,
bool excludeAccepts,
NFAUndirectedGraph &ug,
ue2::unordered_map<typename GraphT::vertex_descriptor,
NFAUndirectedVertex> &old2new) {
size_t idx = 0;
typedef typename GraphT::vertex_descriptor VertexT;
for (auto v : ue2::vertices_range(g)) {
// skip all accept nodes
@@ -84,13 +90,12 @@ void createUnGraph(const GraphT &g,
NFAUndirectedVertex nuv = boost::add_vertex(ug);
old2new[v] = nuv;
newIdx2old[idx] = v;
boost::put(boost::vertex_index, ug, nuv, idx++);
}
for (const auto &e : ue2::edges_range(g)) {
NFAVertex src = source(e, g);
NFAVertex targ = target(e, g);
VertexT src = source(e, g);
VertexT targ = target(e, g);
if ((excludeAccepts && is_any_accept(src, g))
|| (excludeStarts && is_any_start(src, g))) {

View File

@@ -176,7 +176,7 @@ void findSeeds(const NGHolder &h, const bool som, vector<NFAVertex> *seeds) {
continue;
}
DEBUG_PRINTF("%u is a seed\n", h[v].index);
DEBUG_PRINTF("%zu is a seed\n", h[v].index);
seeds->push_back(v);
already_seeds.insert(v);
}
@@ -184,7 +184,7 @@ void findSeeds(const NGHolder &h, const bool som, vector<NFAVertex> *seeds) {
static
bool expandCyclic(NGHolder &h, NFAVertex v) {
DEBUG_PRINTF("inspecting %u\n", h[v].index);
DEBUG_PRINTF("inspecting %zu\n", h[v].index);
bool changes = false;
auto v_preds = preds(v, h);
@@ -201,7 +201,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
auto a_preds = preds(a, h);
if (a_preds == v_preds && isutf8start(h[a].char_reach)) {
DEBUG_PRINTF("%u is a start v\n", h[a].index);
DEBUG_PRINTF("%zu is a start v\n", h[a].index);
start_siblings.insert(a);
}
}
@@ -212,7 +212,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
auto a_succs = succs(a, h);
if (a_succs == v_succs && h[a].char_reach == UTF_CONT_CR) {
DEBUG_PRINTF("%u is a full tail cont\n", h[a].index);
DEBUG_PRINTF("%zu is a full tail cont\n", h[a].index);
end_siblings.insert(a);
}
}
@@ -226,7 +226,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
if (cr.isSubsetOf(UTF_TWO_START_CR)) {
if (end_siblings.find(*adjacent_vertices(s, h).first)
== end_siblings.end()) {
DEBUG_PRINTF("%u is odd\n", h[s].index);
DEBUG_PRINTF("%zu is odd\n", h[s].index);
continue;
}
} else if (cr.isSubsetOf(UTF_THREE_START_CR)) {
@@ -238,7 +238,7 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
}
if (end_siblings.find(*adjacent_vertices(m, h).first)
== end_siblings.end()) {
DEBUG_PRINTF("%u is odd\n", h[s].index);
DEBUG_PRINTF("%zu is odd\n", h[s].index);
continue;
}
} else if (cr.isSubsetOf(UTF_FOUR_START_CR)) {
@@ -258,11 +258,11 @@ bool expandCyclic(NGHolder &h, NFAVertex v) {
if (end_siblings.find(*adjacent_vertices(m2, h).first)
== end_siblings.end()) {
DEBUG_PRINTF("%u is odd\n", h[s].index);
DEBUG_PRINTF("%zu is odd\n", h[s].index);
continue;
}
} else {
DEBUG_PRINTF("%u is bad\n", h[s].index);
DEBUG_PRINTF("%zu is bad\n", h[s].index);
continue;
}

View File

@@ -52,7 +52,7 @@
using namespace std;
using boost::default_color_type;
using boost::filtered_graph;
using boost::make_filtered_graph;
using boost::make_assoc_property_map;
using boost::adaptors::map_values;
@@ -172,15 +172,14 @@ namespace {
struct CycleFound {};
struct DetectCycles : public boost::default_dfs_visitor {
explicit DetectCycles(const NGHolder &g) : startDs(g.startDs) {}
void back_edge(const NFAEdge &e, const NFAGraph &g) const {
void back_edge(const NFAEdge &e, const NGHolder &g) const {
NFAVertex u = source(e, g), v = target(e, g);
// We ignore the startDs self-loop.
if (u == startDs && v == startDs) {
return;
}
// Any other back-edge indicates a cycle.
DEBUG_PRINTF("back edge %u->%u found\n", g[u].index,
g[v].index);
DEBUG_PRINTF("back edge %zu->%zu found\n", g[u].index, g[v].index);
throw CycleFound();
}
private:
@@ -215,10 +214,8 @@ bool isFloating(const NGHolder &g) {
bool isAcyclic(const NGHolder &g) {
try {
depth_first_search(
g.g, visitor(DetectCycles(g))
.root_vertex(g.start)
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
boost::depth_first_search(g, visitor(DetectCycles(g))
.root_vertex(g.start));
} catch (const CycleFound &) {
return false;
}
@@ -234,11 +231,11 @@ bool hasReachableCycle(const NGHolder &g, NFAVertex src) {
try {
// Use depth_first_visit, rather than depth_first_search, so that we
// only search from src.
auto index_map = get(&NFAGraphVertexProps::index, g.g);
depth_first_visit(
g.g, src, DetectCycles(g),
make_iterator_property_map(colors.begin(), index_map));
} catch (const CycleFound&) {
auto index_map = get(vertex_index, g);
boost::depth_first_visit(g, src, DetectCycles(g),
make_iterator_property_map(colors.begin(),
index_map));
} catch (const CycleFound &) {
return true;
}
@@ -249,10 +246,7 @@ bool hasBigCycles(const NGHolder &g) {
assert(hasCorrectlyNumberedVertices(g));
set<NFAEdge> dead;
BackEdges<set<NFAEdge>> backEdgeVisitor(dead);
depth_first_search(
g.g, visitor(backEdgeVisitor)
.root_vertex(g.start)
.vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
boost::depth_first_search(g, visitor(backEdgeVisitor).root_vertex(g.start));
for (const auto &e : dead) {
if (source(e, g) != target(e, g)) {
@@ -266,8 +260,7 @@ bool hasBigCycles(const NGHolder &g) {
set<NFAVertex> findVerticesInCycles(const NGHolder &g) {
map<NFAVertex, size_t> comp_map;
strong_components(g.g, make_assoc_property_map(comp_map),
vertex_index_map(get(&NFAGraphVertexProps::index, g.g)));
strong_components(g, make_assoc_property_map(comp_map));
map<size_t, set<NFAVertex> > comps;
@@ -298,8 +291,7 @@ set<NFAVertex> findVerticesInCycles(const NGHolder &g) {
bool can_never_match(const NGHolder &g) {
assert(edge(g.accept, g.acceptEod, g).second);
if (!hasGreaterInDegree(0, g.accept, g)
&& !hasGreaterInDegree(1, g.acceptEod, g)) {
if (in_degree(g.accept, g) == 0 && in_degree(g.acceptEod, g) == 1) {
DEBUG_PRINTF("no paths into accept\n");
return true;
}
@@ -308,7 +300,7 @@ bool can_never_match(const NGHolder &g) {
}
bool can_match_at_eod(const NGHolder &h) {
if (hasGreaterInDegree(1, h.acceptEod, h)) {
if (in_degree(h.acceptEod, h) > 1) {
DEBUG_PRINTF("more than one edge to acceptEod\n");
return true;
}
@@ -396,21 +388,17 @@ vector<NFAVertex> getTopoOrdering(const NGHolder &g) {
EdgeSet backEdges;
BackEdges<EdgeSet> be(backEdges);
auto index_map = get(&NFAGraphVertexProps::index, g.g);
depth_first_search(g.g, visitor(be)
.root_vertex(g.start)
.color_map(make_iterator_property_map(
colour.begin(), index_map))
.vertex_index_map(index_map));
auto index_map = get(vertex_index, g);
depth_first_search(g, visitor(be).root_vertex(g.start)
.color_map(make_iterator_property_map(
colour.begin(), index_map)));
auto acyclic_g = make_filtered_graph(g.g, make_bad_edge_filter(&backEdges));
auto acyclic_g = make_filtered_graph(g, make_bad_edge_filter(&backEdges));
vector<NFAVertex> ordering;
ordering.reserve(num_verts);
topological_sort(
acyclic_g, back_inserter(ordering),
color_map(make_iterator_property_map(colour.begin(), index_map))
.vertex_index_map(index_map));
topological_sort(acyclic_g, back_inserter(ordering),
color_map(make_iterator_property_map(colour.begin(), index_map)));
reorderSpecials(g, ordering);
@@ -434,12 +422,12 @@ void mustBeSetBefore_int(NFAVertex u, const NGHolder &g,
}
}
auto prefix = make_filtered_graph(g.g, make_bad_edge_filter(&dead));
auto prefix = make_filtered_graph(g, make_bad_edge_filter(&dead));
depth_first_visit(
prefix, g.start, make_dfs_visitor(boost::null_visitor()),
make_iterator_property_map(vertexColor.begin(),
get(&NFAGraphVertexProps::index, g.g)));
get(vertex_index, g)));
}
bool mustBeSetBefore(NFAVertex u, NFAVertex v, const NGHolder &g,
@@ -456,15 +444,14 @@ bool mustBeSetBefore(NFAVertex u, NFAVertex v, const NGHolder &g,
mustBeSetBefore_int(u, g, vertexColor);
for (auto vi : vertices_range(g)) {
auto key2 = make_pair(g[u].index,
g[vi].index);
DEBUG_PRINTF("adding %u %u\n", key2.first, key2.second);
auto key2 = make_pair(g[u].index, g[vi].index);
DEBUG_PRINTF("adding %zu %zu\n", key2.first, key2.second);
assert(!contains(cache.cache, key2));
bool value = vertexColor[g[vi].index] == boost::white_color;
cache.cache[key2] = value;
assert(contains(cache.cache, key2));
}
DEBUG_PRINTF("cache miss %u %u (%zu)\n", key.first, key.second,
DEBUG_PRINTF("cache miss %zu %zu (%zu)\n", key.first, key.second,
cache.cache.size());
return cache.cache[key];
}
@@ -592,12 +579,13 @@ void fillHolder(NGHolder *outp, const NGHolder &in, const deque<NFAVertex> &vv,
fillHolderOutEdges(out, in, v_map, u);
}
out.renumberEdges();
out.renumberVertices();
renumber_edges(out);
renumber_vertices(out);
}
void cloneHolder(NGHolder &out, const NGHolder &in) {
assert(hasCorrectlyNumberedVertices(in));
assert(hasCorrectlyNumberedVertices(out));
out.kind = in.kind;
// Note: depending on the state of the input graph, some stylized edges
@@ -607,6 +595,7 @@ void cloneHolder(NGHolder &out, const NGHolder &in) {
/* remove the existing special edges */
clear_vertex(out.startDs, out);
clear_vertex(out.accept, out);
renumber_edges(out);
vector<NFAVertex> out_mapping(num_vertices(in));
out_mapping[NODE_START] = out.start;
@@ -642,8 +631,8 @@ void cloneHolder(NGHolder &out, const NGHolder &in) {
}
// Safety checks.
assert(num_vertices(in.g) == num_vertices(out.g));
assert(num_edges(in.g) == num_edges(out.g));
assert(num_vertices(in) == num_vertices(out));
assert(num_edges(in) == num_edges(out));
assert(hasCorrectlyNumberedVertices(out));
}
@@ -672,9 +661,8 @@ unique_ptr<NGHolder> cloneHolder(const NGHolder &in) {
void reverseHolder(const NGHolder &g_in, NGHolder &g) {
// Make the BGL do the grunt work.
ue2::unordered_map<NFAVertex, NFAVertex> vertexMap;
boost::transpose_graph(g_in.g, g.g,
orig_to_copy(boost::make_assoc_property_map(vertexMap)).
vertex_index_map(get(&NFAGraphVertexProps::index, g_in.g)));
boost::transpose_graph(g_in, g,
orig_to_copy(boost::make_assoc_property_map(vertexMap)));
// The transpose_graph operation will have created extra copies of our
// specials. We have to rewire their neighbours to the 'real' specials and
@@ -716,8 +704,8 @@ void reverseHolder(const NGHolder &g_in, NGHolder &g) {
// Renumber so that g's properties (number of vertices, edges) are
// accurate.
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
assert(num_vertices(g) == num_vertices(g_in));
assert(num_edges(g) == num_edges(g_in));
@@ -729,8 +717,7 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
unordered_set<NFAVertex> reporters;
for (auto v : inv_adjacent_vertices_range(g.accept, g)) {
if (g[v].reports.empty()) {
DEBUG_PRINTF("vertex %u has no reports!\n",
g[v].index);
DEBUG_PRINTF("vertex %zu has no reports!\n", g[v].index);
return false;
}
reporters.insert(v);
@@ -741,8 +728,7 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
continue; // stylised edge
}
if (g[v].reports.empty()) {
DEBUG_PRINTF("vertex %u has no reports!\n",
g[v].index);
DEBUG_PRINTF("vertex %zu has no reports!\n", g[v].index);
return false;
}
reporters.insert(v);
@@ -750,7 +736,7 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
for (auto v : vertices_range(g)) {
if (!contains(reporters, v) && !g[v].reports.empty()) {
DEBUG_PRINTF("vertex %u is not a match state, but has reports!\n",
DEBUG_PRINTF("vertex %zu is not a match state, but has reports!\n",
g[v].index);
return false;
}
@@ -759,34 +745,6 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
return true;
}
bool hasCorrectlyNumberedVertices(const NGHolder &g) {
size_t count = num_vertices(g);
vector<bool> ids(count, false);
for (auto v : vertices_range(g)) {
u32 id = g[v].index;
if (id >= count || ids[id]) {
return false; // duplicate
}
ids[id] = true;
}
return find(ids.begin(), ids.end(), false) == ids.end()
&& num_vertices(g) == num_vertices(g.g);
}
bool hasCorrectlyNumberedEdges(const NGHolder &g) {
size_t count = num_edges(g);
vector<bool> ids(count, false);
for (const auto &e : edges_range(g)) {
u32 id = g[e].index;
if (id >= count || ids[id]) {
return false; // duplicate
}
ids[id] = true;
}
return find(ids.begin(), ids.end(), false) == ids.end()
&& num_edges(g) == num_edges(g.g);
}
bool isCorrectlyTopped(const NGHolder &g) {
if (is_triggered(g)) {
for (const auto &e : out_edges_range(g.start, g)) {
@@ -805,7 +763,6 @@ bool isCorrectlyTopped(const NGHolder &g) {
return true;
}
#endif // NDEBUG
} // namespace ue2

View File

@@ -65,9 +65,8 @@ bool is_dot(NFAVertex v, const GraphT &g) {
template<class U>
static really_inline
void succ(const NGHolder &g, NFAVertex v, U *s) {
NGHolder::adjacency_iterator ai, ae;
tie(ai, ae) = adjacent_vertices(v, g);
s->insert(ai, ae);
auto rv = adjacent_vertices(v, g);
s->insert(rv.first, rv.second);
}
template<class ContTemp = flat_set<NFAVertex>>
@@ -81,9 +80,8 @@ ContTemp succs(NFAVertex u, const NGHolder &g) {
template<class U>
static really_inline
void pred(const NGHolder &g, NFAVertex v, U *p) {
NGHolder::inv_adjacency_iterator it, ite;
tie(it, ite) = inv_adjacent_vertices(v, g);
p->insert(it, ite);
auto rv = inv_adjacent_vertices(v, g);
p->insert(rv.first, rv.second);
}
template<class ContTemp = flat_set<NFAVertex>>
@@ -138,42 +136,11 @@ public:
BackEdgeSet &backEdges;
};
/**
* Generic code to renumber all the vertices in a graph. Assumes that we're
* using a vertex_index property of type u32, and that we always have
* N_SPECIALS special vertices already present (which we don't want to
* renumber).
*/
template<typename GraphT>
static really_inline
size_t renumberGraphVertices(GraphT &g) {
size_t num = N_SPECIALS;
for (const auto &v : vertices_range(g)) {
if (!is_special(v, g)) {
g[v].index = num++;
assert(num > 0); // no wrapping
}
}
return num;
}
/** Renumber all the edges in a graph. */
template<typename GraphT>
static really_inline
size_t renumberGraphEdges(GraphT &g) {
size_t num = 0;
for (const auto &e : edges_range(g)) {
g[e].index = num++;
assert(num > 0); // no wrapping
}
return num;
}
/** Returns true if the vertex is either of the real starts (NODE_START,
* NODE_START_DOTSTAR). */
template <typename GraphT>
static really_inline
bool is_any_start(const NFAVertex v, const GraphT &g) {
bool is_any_start(typename GraphT::vertex_descriptor v, const GraphT &g) {
u32 i = g[v].index;
return i == NODE_START || i == NODE_START_DOTSTAR;
}
@@ -181,16 +148,14 @@ bool is_any_start(const NFAVertex v, const GraphT &g) {
bool is_virtual_start(NFAVertex v, const NGHolder &g);
template <typename GraphT>
static really_inline
bool is_any_accept(const NFAVertex v, const GraphT &g) {
bool is_any_accept(typename GraphT::vertex_descriptor v, const GraphT &g) {
u32 i = g[v].index;
return i == NODE_ACCEPT || i == NODE_ACCEPT_EOD;
}
/** returns true iff v has an edge to accept or acceptEod */
template <typename GraphT>
static really_inline
bool is_match_vertex(NFAVertex v, const GraphT &g) {
bool is_match_vertex(typename GraphT::vertex_descriptor v, const GraphT &g) {
return edge(v, g.accept, g).second || edge(v, g.acceptEod, g).second;
}
@@ -202,25 +167,6 @@ bool is_match_vertex(NFAVertex v, const GraphT &g) {
*/
std::vector<NFAVertex> getTopoOrdering(const NGHolder &g);
/** Comparison functor used to sort by vertex_index. */
template<typename Graph>
struct VertexIndexOrdering {
VertexIndexOrdering(const Graph &g_in) : g(&g_in) {}
bool operator()(typename Graph::vertex_descriptor a,
typename Graph::vertex_descriptor b) const {
assert(a == b || (*g)[a].index != (*g)[b].index);
return (*g)[a].index < (*g)[b].index;
}
private:
const Graph *g;
};
template<typename Graph>
static
VertexIndexOrdering<Graph> make_index_ordering(const Graph &g) {
return VertexIndexOrdering<Graph>(g);
}
bool onlyOneTop(const NGHolder &g);
/** Return the set of the tops on the given graph. */
@@ -340,18 +286,6 @@ void reverseHolder(const NGHolder &g, NGHolder &out);
*/
bool allMatchStatesHaveReports(const NGHolder &g);
/**
* Assertion: returns true if the vertices in this graph are contiguously (and
* uniquely) numbered from zero.
*/
bool hasCorrectlyNumberedVertices(const NGHolder &g);
/**
* Assertion: returns true if the edges in this graph are contiguously (and
* uniquely) numbered from zero.
*/
bool hasCorrectlyNumberedEdges(const NGHolder &g);
/**
* Assertion: returns true if the graph is triggered and all edges out of start
* have tops OR if the graph is not-triggered and all edges out of start have no

View File

@@ -464,7 +464,7 @@ void getRegionRoseLiterals(const NGHolder &g, bool seeking_anchored,
DEBUG_PRINTF("inspecting region %u\n", region);
set<ue2_literal> s;
for (auto v : vv) {
DEBUG_PRINTF(" exit vertex: %u\n", g[v].index);
DEBUG_PRINTF(" exit vertex: %zu\n", g[v].index);
/* Note: RHS can not be depended on to take all subsequent revisits
* to this vertex */
set<ue2_literal> ss = getLiteralSet(g, v, false);
@@ -669,7 +669,7 @@ unique_ptr<VertLitInfo> findBestSplit(const NGHolder &g,
lits.pop_back();
}
DEBUG_PRINTF("best is '%s' %u a%d t%d\n",
DEBUG_PRINTF("best is '%s' %zu a%d t%d\n",
dumpString(*best->lit.begin()).c_str(),
g[best->vv.front()].index,
depths ? (int)createsAnchoredLHS(g, best->vv, *depths, cc.grey) : 0,
@@ -777,7 +777,7 @@ set<NFAVertex> poisonVertices(const NGHolder &h, const RoseInGraph &vg,
set<NFAVertex> bad_vertices;
for (const NFAEdge &e : bad_edges) {
bad_vertices.insert(target(e, h));
DEBUG_PRINTF("bad: %u->%u\n", h[source(e, h)].index,
DEBUG_PRINTF("bad: %zu->%zu\n", h[source(e, h)].index,
h[target(e, h)].index);
}
@@ -1144,7 +1144,7 @@ void splitEdgesByCut(NGHolder &h, RoseInGraph &vg,
NFAVertex prev_v = source(e, h);
NFAVertex pivot = target(e, h);
DEBUG_PRINTF("splitting on pivot %u\n", h[pivot].index);
DEBUG_PRINTF("splitting on pivot %zu\n", h[pivot].index);
ue2::unordered_map<NFAVertex, NFAVertex> temp_map;
shared_ptr<NGHolder> new_lhs = make_shared<NGHolder>();
splitLHS(h, pivot, new_lhs.get(), &temp_map);
@@ -1324,7 +1324,7 @@ bool deanchorIfNeeded(NGHolder &g) {
succ_g.erase(g.startDs);
for (auto v : adjacent_vertices_range(g.start, g)) {
DEBUG_PRINTF("inspecting cand %u || = %zu\n", g[v].index,
DEBUG_PRINTF("inspecting cand %zu || = %zu\n", g[v].index,
g[v].char_reach.count());
if (v == g.startDs || !g[v].char_reach.all()) {
@@ -2339,7 +2339,7 @@ bool leadingDotStartLiteral(const NGHolder &h, VertLitInfo *out) {
make_nocase(&lit);
}
DEBUG_PRINTF("%u found %s\n", h[v].index, dumpString(lit).c_str());
DEBUG_PRINTF("%zu found %s\n", h[v].index, dumpString(lit).c_str());
out->vv = {v};
out->lit = {lit};
return true;
@@ -2468,7 +2468,7 @@ bool trailingDotStarLiteral(const NGHolder &h, VertLitInfo *out) {
}
ue2_literal lit = reverse_literal(rv.second);
DEBUG_PRINTF("%u found %s\n", h[v].index, dumpString(lit).c_str());
DEBUG_PRINTF("%zu found %s\n", h[v].index, dumpString(lit).c_str());
if (bad_mixed_sensitivity(lit)) {
make_nocase(&lit);
@@ -2672,6 +2672,7 @@ bool doViolet(RoseBuild &rose, const NGHolder &h, bool prefilter,
pruneUseless(vg);
dumpPreRoseGraph(vg, cc.grey);
renumber_vertices(vg);
calcVertexOffsets(vg);
bool rv = rose.addRose(vg, prefilter);
DEBUG_PRINTF("violet: %s\n", rv ? "success" : "fail");

View File

@@ -58,18 +58,18 @@ namespace {
struct SpecialEdgeFilter {
SpecialEdgeFilter() {}
explicit SpecialEdgeFilter(const NGHolder &h_in) : h(&h_in) {}
explicit SpecialEdgeFilter(const NGHolder &h_in, u32 top_in)
SpecialEdgeFilter(const NGHolder &h_in, u32 top_in)
: h(&h_in), single_top(true), top(top_in) {}
bool operator()(const NFAEdge &e) const {
const NFAGraph &g = h->g;
NFAVertex u = source(e, g), v = target(e, g);
if ((is_any_start(u, g) && is_any_start(v, g)) ||
(is_any_accept(u, g) && is_any_accept(v, g))) {
NFAVertex u = source(e, *h);
NFAVertex v = target(e, *h);
if ((is_any_start(u, *h) && is_any_start(v, *h)) ||
(is_any_accept(u, *h) && is_any_accept(v, *h))) {
return false;
}
if (single_top) {
if (u == h->start && !contains(g[e].tops, top)) {
if (u == h->start && !contains((*h)[e].tops, top)) {
return false;
}
if (u == h->startDs) {
@@ -94,7 +94,7 @@ depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
return depth::unreachable();
}
boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter);
boost::filtered_graph<NGHolder, SpecialEdgeFilter> g(h, filter);
assert(hasCorrectlyNumberedVertices(h));
const size_t num = num_vertices(h);
@@ -106,11 +106,10 @@ depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
// Since we are interested in the single-source shortest paths on a graph
// with the same weight on every edge, using BFS will be faster than
// Dijkstra here.
breadth_first_search(
g, src,
breadth_first_search(g, src,
visitor(make_bfs_visitor(record_distances(
make_iterator_property_map(distance.begin(), index_map),
boost::on_tree_edge()))).vertex_index_map(index_map));
boost::on_tree_edge()))));
DEBUG_PRINTF("d[accept]=%s, d[acceptEod]=%s\n",
distance.at(NODE_ACCEPT).str().c_str(),
@@ -130,7 +129,7 @@ depth findMinWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
static
depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
NFAVertex src) {
if (isLeafNode(src, h.g)) {
if (isLeafNode(src, h)) {
return depth::unreachable();
}
@@ -139,7 +138,7 @@ depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
return depth::infinity();
}
boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter);
boost::filtered_graph<NGHolder, SpecialEdgeFilter> g(h, filter);
assert(hasCorrectlyNumberedVertices(h));
const size_t num = num_vertices(h);
@@ -149,11 +148,9 @@ depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
auto index_map = get(&NFAGraphVertexProps::index, g);
// DAG shortest paths with negative edge weights.
dag_shortest_paths(
g, src,
dag_shortest_paths(g, src,
distance_map(make_iterator_property_map(distance.begin(), index_map))
.weight_map(boost::make_constant_property<NFAEdge>(-1))
.vertex_index_map(index_map)
.color_map(make_iterator_property_map(colors.begin(), index_map)));
depth acceptDepth, acceptEodDepth;