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

@ -711,7 +711,6 @@ SET (hs_SRCS
src/nfagraph/ng_extparam.h
src/nfagraph/ng_fixed_width.cpp
src/nfagraph/ng_fixed_width.h
src/nfagraph/ng_graph.h
src/nfagraph/ng_haig.cpp
src/nfagraph/ng_haig.h
src/nfagraph/ng_holder.cpp
@ -933,6 +932,7 @@ SET (hs_SRCS
src/util/target_info.cpp
src/util/target_info.h
src/util/ue2_containers.h
src/util/ue2_graph.h
src/util/ue2string.cpp
src/util/ue2string.h
src/util/unaligned.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:
@ -117,11 +117,11 @@ typedef map<pair<NFAVertex, NFAVertex>, NFAEdge> edge_cache_t;
static
void replaceAssertVertex(NGWrapper &g, NFAVertex t, edge_cache_t &edge_cache,
u32 &assert_edge_count) {
DEBUG_PRINTF("replacing assert vertex %u\n", g[t].index);
DEBUG_PRINTF("replacing assert vertex %zu\n", g[t].index);
const u32 flags = g[t].assert_flags;
DEBUG_PRINTF("consider assert vertex %u with flags %u\n",
g[t].index, flags);
DEBUG_PRINTF("consider assert vertex %zu with flags %u\n", g[t].index,
flags);
// Wire up all the predecessors to all the successors.
@ -142,7 +142,7 @@ void replaceAssertVertex(NGWrapper &g, NFAVertex t, edge_cache_t &edge_cache,
for (const auto &outEdge : out_edges_range(t, g)) {
NFAVertex v = target(outEdge, g);
DEBUG_PRINTF("consider path [%u,%u,%u]\n", g[u].index,
DEBUG_PRINTF("consider path [%zu,%zu,%zu]\n", g[u].index,
g[t].index, g[v].index);
if (v == t) {
@ -173,8 +173,7 @@ void replaceAssertVertex(NGWrapper &g, NFAVertex t, edge_cache_t &edge_cache,
auto cache_key = make_pair(u, v);
auto ecit = edge_cache.find(cache_key);
if (ecit == edge_cache.end()) {
DEBUG_PRINTF("adding edge %u %u\n", g[u].index,
g[v].index);
DEBUG_PRINTF("adding edge %zu %zu\n", g[u].index, g[v].index);
NFAEdge e = add_edge(u, v, g).first;
edge_cache.emplace(cache_key, e);
g[e].assert_flags = flags;
@ -184,7 +183,7 @@ void replaceAssertVertex(NGWrapper &g, NFAVertex t, edge_cache_t &edge_cache,
}
} else {
NFAEdge e = ecit->second;
DEBUG_PRINTF("updating edge %u %u [a %u]\n", g[u].index,
DEBUG_PRINTF("updating edge %zu %zu [a %zu]\n", g[u].index,
g[v].index, g[t].index);
// Edge already exists.
u32 &e_flags = g[e].assert_flags;
@ -211,8 +210,7 @@ void setReportId(ReportManager &rm, NGWrapper &g, NFAVertex v, s32 adj) {
Report r = rm.getBasicInternalReport(g, adj);
g[v].reports.insert(rm.getInternalId(r));
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
@ -222,8 +220,7 @@ void checkForMultilineStart(ReportManager &rm, NGWrapper &g) {
if (!(g[v].assert_flags & POS_FLAG_MULTILINE_START)) {
continue;
}
DEBUG_PRINTF("mls %u %08x\n", g[v].index,
g[v].assert_flags);
DEBUG_PRINTF("mls %zu %08x\n", g[v].index, g[v].assert_flags);
/* we have found a multi-line start (maybe more than one) */
@ -299,8 +296,8 @@ void removeAssertVertices(ReportManager &rm, NGWrapper &g) {
DEBUG_PRINTF("resolved %zu assert vertices\n", num);
pruneUseless(g);
pruneEmptyVertices(g);
g.renumberVertices();
g.renumberEdges();
renumber_vertices(g);
renumber_edges(g);
}
DEBUG_PRINTF("after: graph has %zu vertices\n", num_vertices(g));

View File

@ -56,15 +56,6 @@ struct path {
};
};
static UNUSED
string describeClasses(const vector<CharReach> &v) {
std::ostringstream oss;
for (const auto &cr : v) {
describeClass(oss, cr);
}
return oss.str();
}
static
void dump_paths(const vector<path> &paths) {
for (UNUSED const auto &p : paths) {

View File

@ -58,6 +58,7 @@
#include <stack>
#include <cassert>
#include <boost/graph/adjacency_list.hpp>
#include <boost/range/adaptor/map.hpp>
using namespace std;
@ -981,7 +982,7 @@ unique_ptr<NGHolder> makeHolder(const CastleProto &proto,
addToHolder(*g, m.first, m.second);
}
//dumpGraph("castle_holder.dot", g->g);
//dumpGraph("castle_holder.dot", *g);
// Sanity checks.
assert(allMatchStatesHaveReports(*g));

View File

@ -494,7 +494,7 @@ void nfaFindAccelSchemes(const NGHolder &g,
// We want to skip any vertices that don't lead to at least one other
// (self-loops don't count) vertex.
if (!has_proper_successor(v, g)) {
DEBUG_PRINTF("skipping vertex %u\n", g[v].index);
DEBUG_PRINTF("skipping vertex %zu\n", g[v].index);
continue;
}
@ -502,7 +502,7 @@ void nfaFindAccelSchemes(const NGHolder &g,
AccelScheme as;
if (nfaCheckAccel(g, v, refined_cr, br_cyclic, &as, allow_wide)) {
DEBUG_PRINTF("graph vertex %u is accelerable with offset %u.\n",
DEBUG_PRINTF("graph vertex %zu is accelerable with offset %u.\n",
g[v].index, as.offset);
(*out)[v] = as;
}
@ -514,7 +514,7 @@ struct fas_visitor : public boost::default_bfs_visitor {
ue2::unordered_map<NFAVertex, AccelScheme> *out_in)
: accel_map(am_in), out(out_in) {}
void discover_vertex(NFAVertex v, const NFAGraph &) {
void discover_vertex(NFAVertex v, const NGHolder &) {
if (accel_map.find(v) != accel_map.end()) {
(*out)[v] = accel_map.find(v)->second;
}
@ -552,11 +552,10 @@ void filterAccelStates(NGHolder &g, const map<u32, set<NFAVertex>> &tops,
try {
vector<boost::default_color_type> colour(num_vertices(g));
breadth_first_search(
g.g, g.start,
boost::breadth_first_search(g, g.start,
visitor(fas_visitor(*accel_map, &out))
.color_map(make_iterator_property_map(
colour.begin(), get(&NFAGraphVertexProps::index, g.g))));
.color_map(make_iterator_property_map(colour.begin(),
get(vertex_index, g))));
} catch (fas_visitor *) {
; /* found max accel_states */
}
@ -628,7 +627,7 @@ void fillAccelInfo(build_info &bi) {
/* for each subset of the accel keys need to find an accel scheme */
assert(astates.size() < 32);
sort(astates.begin(), astates.end(), make_index_ordering(g));
sort(astates.begin(), astates.end());
for (u32 i = 1, i_end = 1U << astates.size(); i < i_end; i++) {
DEBUG_PRINTF("saving info for accel %u\n", i);
@ -2335,8 +2334,7 @@ bool isSane(const NGHolder &h, const map<u32, set<NFAVertex>> &tops,
for (auto v : vertices_range(h)) {
if (!contains(state_ids, v)) {
DEBUG_PRINTF("no entry for vertex %u in state map\n",
h[v].index);
DEBUG_PRINTF("no entry for vertex %zu in state map\n", h[v].index);
return false;
}
const u32 i = state_ids.at(v);
@ -2344,8 +2342,7 @@ bool isSane(const NGHolder &h, const map<u32, set<NFAVertex>> &tops,
continue;
}
DEBUG_PRINTF("checking vertex %u (state %u)\n", h[v].index,
i);
DEBUG_PRINTF("checking vertex %zu (state %u)\n", h[v].index, i);
if (i >= num_states || contains(seen, i)) {
DEBUG_PRINTF("vertex %u/%u has invalid state\n", i, num_states);
@ -2355,7 +2352,7 @@ bool isSane(const NGHolder &h, const map<u32, set<NFAVertex>> &tops,
// All our states should be reachable and have a state assigned.
if (h[v].char_reach.none()) {
DEBUG_PRINTF("vertex %u has empty reachability\n", h[v].index);
DEBUG_PRINTF("vertex %zu has empty reachability\n", h[v].index);
return false;
}
@ -2363,7 +2360,7 @@ bool isSane(const NGHolder &h, const map<u32, set<NFAVertex>> &tops,
// must have at least one predecessor that is not itself.
if (v != h.start && v != h.startDs && !contains(top_starts, v)
&& !proper_in_degree(v, h)) {
DEBUG_PRINTF("vertex %u has no pred\n", h[v].index);
DEBUG_PRINTF("vertex %zu has no pred\n", h[v].index);
return false;
}
}

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;

View File

@ -112,11 +112,10 @@ RoseVertex createVertex(RoseBuildImpl *build, u32 literalId, u32 min_offset,
RoseGraph &g = build->g;
// add to tree
RoseVertex v = add_vertex(g);
g[v].idx = build->vertexIndex++;
g[v].min_offset = min_offset;
g[v].max_offset = max_offset;
DEBUG_PRINTF("insert vertex %zu into literal %u's vertex set\n", g[v].idx,
DEBUG_PRINTF("insert vertex %zu into literal %u's vertex set\n", g[v].index,
literalId);
g[v].literals.insert(literalId);
build->literal_info[literalId].vertices.insert(v);
@ -167,7 +166,7 @@ RoseVertex createAnchoredVertex(RoseBuildImpl *build, u32 literalId,
RoseGraph &g = build->g;
RoseVertex v = createVertex(build, literalId, min_offset, max_offset);
DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].idx,
DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].index,
literalId);
RoseEdge e = add_edge(build->anchored_root, v, g).first;
@ -181,8 +180,7 @@ static
RoseVertex duplicate(RoseBuildImpl *build, RoseVertex v) {
RoseGraph &g = build->g;
RoseVertex w = add_vertex(g[v], g);
g[w].idx = build->vertexIndex++;
DEBUG_PRINTF("added vertex %zu\n", g[w].idx);
DEBUG_PRINTF("added vertex %zu\n", g[w].index);
for (auto lit_id : g[w].literals) {
build->literal_info[lit_id].vertices.insert(w);
@ -191,7 +189,7 @@ RoseVertex duplicate(RoseBuildImpl *build, RoseVertex v) {
for (const auto &e : in_edges_range(v, g)) {
RoseVertex s = source(e, g);
add_edge(s, w, g[e], g);
DEBUG_PRINTF("added edge (%zu,%zu)\n", g[s].idx, g[w].idx);
DEBUG_PRINTF("added edge (%zu,%zu)\n", g[s].index, g[w].index);
}
return w;
@ -227,7 +225,7 @@ RoseRoleHistory selectHistory(const RoseBuildImpl &tbi, const RoseBuildData &bd,
const bool has_bounds = g[e].minBound || (g[e].maxBound != ROSE_BOUND_INF);
DEBUG_PRINTF("edge %zu->%zu, bounds=[%u,%u], fixed_u=%d, prefix=%d\n",
g[u].idx, g[v].idx, g[e].minBound, g[e].maxBound,
g[u].index, g[v].index, g[e].minBound, g[e].maxBound,
(int)g[u].fixedOffset(), (int)g[v].left);
if (g[v].left) {
@ -309,7 +307,7 @@ void createVertices(RoseBuildImpl *tbi,
DEBUG_PRINTF("set som_adjust to %u\n", g[w].som_adjust);
}
DEBUG_PRINTF(" adding new vertex idx=%zu\n", tbi->g[w].idx);
DEBUG_PRINTF(" adding new vertex index=%zu\n", tbi->g[w].index);
vertex_map[iv].push_back(w);
} else {
w = created[key];
@ -383,7 +381,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) {
for (auto it = lit.rbegin(), ite = lit.rend(); it != ite; ++it) {
next.clear();
for (auto curr_v : curr) {
DEBUG_PRINTF("handling %u\n", g[curr_v].index);
DEBUG_PRINTF("handling %zu\n", g[curr_v].index);
vector<NFAVertex> next_cand;
insert(&next_cand, next_cand.end(),
inv_adjacent_vertices(curr_v, g));
@ -401,7 +399,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) {
const CharReach &cr = g[v].char_reach;
if (!overlaps(*it, cr)) {
DEBUG_PRINTF("false edge %u\n", g[v].index);
DEBUG_PRINTF("false edge %zu\n", g[v].index);
continue;
}
@ -409,7 +407,7 @@ void removeFalsePaths(NGHolder &g, const ue2_literal &lit) {
clone_in_edges(g, v, v2);
add_edge(v2, curr_v, g);
g[v2].char_reach &= *it;
DEBUG_PRINTF("next <- %u\n", g[v2].index);
DEBUG_PRINTF("next <- %zu\n", g[v2].index);
next.insert(v2);
}
}
@ -557,7 +555,7 @@ void findRoseLiteralMask(const NGHolder &h, const u32 lag, vector<u8> &msk,
next.clear();
CharReach cr;
for (auto v : curr) {
DEBUG_PRINTF("vertex %u, reach %s\n", h[v].index,
DEBUG_PRINTF("vertex %zu, reach %s\n", h[v].index,
describeClass(h[v].char_reach).c_str());
cr |= h[v].char_reach;
insert(&next, inv_adjacent_vertices(v, h));
@ -705,7 +703,6 @@ void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u,
for (const auto &report_mapping : report_remap) {
RoseVertex v = add_vertex(g);
g[v].idx = build.vertexIndex++;
g[v].literals.insert(eod_event);
build.literal_info[eod_event].vertices.insert(v);
@ -728,7 +725,6 @@ void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u,
g[e1].history = ROSE_ROLE_HISTORY_NONE; // handled by prefix
RoseVertex w = add_vertex(g);
g[w].idx = build.vertexIndex++;
g[w].eod_accept = true;
g[w].reports = report_mapping.first;
g[w].min_offset = g[v].min_offset;
@ -737,7 +733,7 @@ void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u,
g[e].minBound = 0;
g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
DEBUG_PRINTF("accept eod vertex (idx=%zu)\n", g[w].idx);
DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index);
}
}
@ -769,7 +765,7 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi,
|| (ig[iv].type == RIV_ACCEPT_EOD && out_degree(u, g)
&& !edge_props.graph)
|| (!isLeafNode(u, g) && !tbi->isAnyStart(u))) {
DEBUG_PRINTF("duplicating for parent %zu\n", g[u].idx);
DEBUG_PRINTF("duplicating for parent %zu\n", g[u].index);
assert(!tbi->isAnyStart(u));
u = duplicate(tbi, u);
g[u].suffix.reset();
@ -780,20 +776,20 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi,
if (ig[iv].type == RIV_ACCEPT) {
assert(!tbi->isAnyStart(u));
if (contains(bd.early_dfas, edge_props.graph.get())) {
DEBUG_PRINTF("adding early dfa suffix to i%zu\n", g[u].idx);
DEBUG_PRINTF("adding early dfa suffix to i%zu\n", g[u].index);
g[u].suffix.rdfa = bd.early_dfas.at(edge_props.graph.get());
g[u].suffix.dfa_min_width = findMinWidth(*edge_props.graph);
g[u].suffix.dfa_max_width = findMaxWidth(*edge_props.graph);
} else if (edge_props.graph) {
DEBUG_PRINTF("adding suffix to i%zu\n", g[u].idx);
DEBUG_PRINTF("adding suffix to i%zu\n", g[u].index);
g[u].suffix.graph = edge_props.graph;
assert(g[u].suffix.graph->kind == NFA_SUFFIX);
/* TODO: set dfa_(min|max)_width */
} else if (edge_props.haig) {
DEBUG_PRINTF("adding suffaig to i%zu\n", g[u].idx);
DEBUG_PRINTF("adding suffaig to i%zu\n", g[u].index);
g[u].suffix.haig = edge_props.haig;
} else {
DEBUG_PRINTF("adding boring accept to i%zu\n", g[u].idx);
DEBUG_PRINTF("adding boring accept to i%zu\n", g[u].index);
assert(!g[u].eod_accept);
g[u].reports = ig[iv].reports;
}
@ -803,7 +799,6 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi,
if (!edge_props.graph) {
RoseVertex w = add_vertex(g);
g[w].idx = tbi->vertexIndex++;
g[w].eod_accept = true;
g[w].reports = ig[iv].reports;
g[w].min_offset = g[u].min_offset;
@ -812,7 +807,7 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi,
g[e].minBound = 0;
g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
DEBUG_PRINTF("accept eod vertex (idx=%zu)\n", g[w].idx);
DEBUG_PRINTF("accept eod vertex (index=%zu)\n", g[w].index);
continue;
}
@ -824,7 +819,7 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi,
assert(h.kind == NFA_SUFFIX);
assert(!tbi->isAnyStart(u));
/* etable can't/shouldn't use eod event */
DEBUG_PRINTF("adding suffix to i%zu\n", g[u].idx);
DEBUG_PRINTF("adding suffix to i%zu\n", g[u].index);
g[u].suffix.graph = edge_props.graph;
continue;
}
@ -976,7 +971,7 @@ void populateRoseGraph(RoseBuildImpl *tbi, RoseBuildData &bd) {
|| ig[v_order.front()].type == RIV_ANCHORED_START);
for (RoseInVertex iv : v_order) {
DEBUG_PRINTF("vertex %p\n", iv);
DEBUG_PRINTF("vertex %zu\n", ig[iv].index);
if (ig[iv].type == RIV_START) {
DEBUG_PRINTF("is root\n");
@ -1588,6 +1583,7 @@ bool RoseBuildImpl::addRose(const RoseInGraph &ig, bool prefilter,
bool finalChance) {
DEBUG_PRINTF("trying to rose\n");
assert(validateKinds(ig));
assert(hasCorrectlyNumberedVertices(ig));
if (::ue2::empty(ig)) {
assert(0);
@ -1603,7 +1599,8 @@ bool RoseBuildImpl::addRose(const RoseInGraph &ig, bool prefilter,
transformAnchoredLiteralOverlap(in, bd, cc);
transformSuffixDelay(in, cc);
assert(validateKinds(ig));
renumber_vertices(in);
assert(validateKinds(in));
map<NGHolder *, vector<RoseInEdge> > graphs;
vector<NGHolder *> ordered_graphs; // Stored in first-encounter order.
@ -1762,8 +1759,7 @@ static
u32 findMaxBAWidth(const NGHolder &h) {
// Must be bi-anchored: no out-edges from startDs (other than its
// self-loop), no in-edges to accept.
if (hasGreaterOutDegree(1, h.startDs, h) ||
hasGreaterInDegree(0, h.accept, h)) {
if (out_degree(h.startDs, h) > 1 || in_degree(h.accept, h)) {
return ROSE_BOUND_INF;
}
depth d = findMaxWidth(h);
@ -1889,9 +1885,9 @@ bool prepAcceptForAddAnchoredNFA(RoseBuildImpl &tbi, const NGHolder &w,
map<ReportID, u32> &allocated_reports,
flat_set<u32> &added_lit_ids) {
const depth max_anchored_depth(tbi.cc.grey.maxAnchoredRegion);
const u32 idx = w[u].index;
assert(idx < vertexDepths.size());
const DepthMinMax &d = vertexDepths.at(idx);
const size_t index = w[u].index;
assert(index < vertexDepths.size());
const DepthMinMax &d = vertexDepths.at(index);
for (const auto &int_report : w[u].reports) {
assert(int_report != MO_INVALID_IDX);
@ -2008,7 +2004,6 @@ bool RoseBuildImpl::addAnchoredAcyclic(const NGHolder &h) {
RoseVertex v
= createAnchoredVertex(this, lit_id, minBound, maxBound);
RoseVertex eod = add_vertex(g);
g[eod].idx = vertexIndex++;
g[eod].eod_accept = true;
g[eod].reports.insert(report);
g[eod].min_offset = g[v].min_offset;

View File

@ -532,7 +532,7 @@ void addTransientMask(RoseBuildImpl &build, const vector<CharReach> &mask,
g[v].left.leftfix_report = mask_report;
} else {
// Make sure our edge bounds are correct.
auto e = edge_by_target(parent, v, g).first;
auto e = edge(parent, v, g).first;
g[e].minBound = 0;
g[e].maxBound = anchored ? 0 : ROSE_BOUND_INF;
g[e].history = anchored ? ROSE_ROLE_HISTORY_ANCH

View File

@ -549,7 +549,7 @@ bool isSimple(const NGHolder &h, u32 *min_bound, u32 *max_bound,
/* lit should only be connected to dot vertices */
for (auto u : inv_adjacent_vertices_range(lit_head, h)) {
DEBUG_PRINTF("checking %u\n", h[u].index);
DEBUG_PRINTF("checking %zu\n", h[u].index);
if (!h[u].char_reach.all()) {
return false;
}

View File

@ -314,7 +314,7 @@ bool needsCatchup(const RoseBuildImpl &build,
continue;
}
if (g[v].suffix) {
DEBUG_PRINTF("vertex %zu has suffix\n", g[v].idx);
DEBUG_PRINTF("vertex %zu has suffix\n", g[v].index);
return true;
}
@ -947,7 +947,7 @@ void appendTailToHolder(NGHolder &h, const vector<CharReach> &tail) {
appendTailToHolder(h, e.first, e.second, tail);
}
h.renumberEdges();
renumber_edges(h);
}
static
@ -1232,11 +1232,11 @@ void updateTops(const RoseGraph &g, const TamaInfo &tamaInfo,
for (const auto &n : tamaInfo.subengines) {
for (const auto &v : subengines[i].vertices) {
if (is_suffix) {
tamaProto.add(n, g[v].idx, g[v].suffix.top,
tamaProto.add(n, g[v].index, g[v].suffix.top,
out_top_remap);
} else {
for (const auto &e : in_edges_range(v, g)) {
tamaProto.add(n, g[v].idx, g[e].rose_top,
tamaProto.add(n, g[v].index, g[e].rose_top,
out_top_remap);
}
}
@ -1280,7 +1280,7 @@ void buildInfixContainer(RoseGraph &g, build_context &bc,
for (const auto &sub : subengines) {
const auto &verts = sub.vertices;
for (const auto &v : verts) {
DEBUG_PRINTF("vert id:%zu\n", g[v].idx);
DEBUG_PRINTF("vert id:%zu\n", g[v].index);
g[v].left.tamarama = tamaProto;
}
}
@ -1299,7 +1299,7 @@ void buildSuffixContainer(RoseGraph &g, build_context &bc,
for (const auto &sub : subengines) {
const auto &verts = sub.vertices;
for (const auto &v : verts) {
DEBUG_PRINTF("vert id:%zu\n", g[v].idx);
DEBUG_PRINTF("vert id:%zu\n", g[v].index);
g[v].suffix.tamarama = tamaProto;
}
const auto &v = verts[0];
@ -1790,7 +1790,7 @@ void assignSuffixQueues(RoseBuildImpl &build, build_context &bc) {
const suffix_id s(g[v].suffix);
DEBUG_PRINTF("vertex %zu triggers suffix %p\n", g[v].idx, s.graph());
DEBUG_PRINTF("vertex %zu triggers suffix %p\n", g[v].index, s.graph());
// We may have already built this NFA.
if (contains(bc.suffixes, s)) {
@ -1887,7 +1887,7 @@ void findExclusiveSuffixes(RoseBuildImpl &tbi, build_context &bc,
const suffix_id s(g[v].suffix);
DEBUG_PRINTF("vertex %zu triggers suffix %p\n", g[v].idx, s.graph());
DEBUG_PRINTF("vertex %zu triggers suffix %p\n", g[v].index, s.graph());
// We may have already built this NFA.
if (contains(suffixes, s)) {
@ -1977,24 +1977,13 @@ bool buildSuffixes(const RoseBuildImpl &tbi, build_context &bc,
}
static
void buildCountingMiracles(RoseBuildImpl &build, build_context &bc) {
void buildCountingMiracles(build_context &bc) {
map<pair<CharReach, u8>, u32> pre_built;
// To ensure compile determinism, we need to iterate over our leftfixes in
// a stronger order than directly over bc.leftfix_info.
vector<RoseVertex> cm_vertices;
for (const auto &m : bc.leftfix_info) {
if (m.second.countingMiracleCount) {
cm_vertices.push_back(m.first);
for (left_build_info &lbi : bc.leftfix_info | map_values) {
if (!lbi.countingMiracleCount) {
continue;
}
}
sort(begin(cm_vertices), end(cm_vertices), VertexIndexComp(build.g));
DEBUG_PRINTF("%zu vertices with counting miracles\n", cm_vertices.size());
for (const auto &v : cm_vertices) {
auto &lbi = bc.leftfix_info.at(v);
assert(lbi.countingMiracleCount);
const CharReach &cr = lbi.countingMiracleReach;
assert(!cr.all() && !cr.none());
@ -2255,12 +2244,12 @@ u32 findMinFloatingLiteralMatch(const RoseBuildImpl &build,
u32 minWidth = ROSE_BOUND_INF;
for (auto v : vertices_range(g)) {
if (build.isAnchored(v) || build.isVirtualVertex(v)) {
DEBUG_PRINTF("skipping %zu anchored or root\n", g[v].idx);
DEBUG_PRINTF("skipping %zu anchored or root\n", g[v].index);
continue;
}
u32 w = g[v].min_offset;
DEBUG_PRINTF("%zu m_o = %u\n", g[v].idx, w);
DEBUG_PRINTF("%zu m_o = %u\n", g[v].index, w);
if (w < minWidth) {
minWidth = w;
@ -3540,7 +3529,7 @@ void makeRoleSuffix(RoseBuildImpl &build, build_context &bc, RoseVertex v,
auto tamaProto = g[v].suffix.tamarama.get();
assert(tamaProto);
u32 top = (u32)MQE_TOP_FIRST +
tamaProto->top_remap.at(make_pair(g[v].idx,
tamaProto->top_remap.at(make_pair(g[v].index,
g[v].suffix.top));
assert(top < MQE_INVALID);
suffixEvent = top;
@ -3622,7 +3611,7 @@ void makeRoleInfixTriggers(RoseBuildImpl &build, build_context &bc,
auto tamaProto = g[v].left.tamarama.get();
assert(tamaProto);
top = MQE_TOP_FIRST + tamaProto->top_remap.at(
make_pair(g[v].idx, g[e].rose_top));
make_pair(g[v].index, g[e].rose_top));
assert(top < MQE_INVALID);
} else if (!isMultiTopType(nfa->type)) {
assert(num_tops(g[v].left) == 1);
@ -3782,7 +3771,7 @@ RoseProgram makeProgram(RoseBuildImpl &build, build_context &bc,
// This program may be triggered by different predecessors, with different
// offset bounds. We must ensure we put this check/set operation after the
// bounds check to deal with this case.
if (hasGreaterInDegree(1, v, g)) {
if (in_degree(v, g) > 1) {
makeRoleCheckNotHandled(bc, v, program);
}
@ -4438,8 +4427,8 @@ RoseProgram buildLiteralProgram(RoseBuildImpl &build, build_context &bc,
if (build.isAnyStart(u)) {
continue; // Root roles are not handled with sparse iterator.
}
DEBUG_PRINTF("sparse iter edge (%zu,%zu)\n", g[u].idx,
g[target(e, g)].idx);
DEBUG_PRINTF("sparse iter edge (%zu,%zu)\n", g[u].index,
g[target(e, g)].index);
assert(contains(bc.roleStateIndices, u));
u32 pred_state = bc.roleStateIndices.at(u);
pred_blocks[pred_state].add_block(makeProgram(build, bc, e));
@ -4455,7 +4444,8 @@ RoseProgram buildLiteralProgram(RoseBuildImpl &build, build_context &bc,
if (!build.isAnyStart(u)) {
continue;
}
DEBUG_PRINTF("root edge (%zu,%zu)\n", g[u].idx, g[target(e, g)].idx);
DEBUG_PRINTF("root edge (%zu,%zu)\n", g[u].index,
g[target(e, g)].index);
program.add_block(makeProgram(build, bc, e));
}
@ -4531,8 +4521,8 @@ map<u32, vector<RoseEdge>> findEdgesByLiteral(const RoseBuildImpl &build) {
auto edge_list = vector<RoseEdge>(begin(m.second), end(m.second));
sort(begin(edge_list), end(edge_list),
[&g](const RoseEdge &a, const RoseEdge &b) {
return tie(g[source(a, g)].idx, g[target(a, g)].idx) <
tie(g[source(b, g)].idx, g[target(b, g)].idx);
return tie(g[source(a, g)].index, g[target(a, g)].index) <
tie(g[source(b, g)].index, g[target(b, g)].index);
});
lit_edge_map.emplace(m.first, edge_list);
}
@ -4658,7 +4648,7 @@ bool hasEodAnchoredSuffix(const RoseBuildImpl &build) {
for (auto v : vertices_range(g)) {
if (g[v].suffix && build.isInETable(v)) {
DEBUG_PRINTF("vertex %zu is in eod table and has a suffix\n",
g[v].idx);
g[v].index);
return true;
}
}
@ -4670,7 +4660,7 @@ bool hasEodMatcher(const RoseBuildImpl &build) {
const RoseGraph &g = build.g;
for (auto v : vertices_range(g)) {
if (build.isInETable(v)) {
DEBUG_PRINTF("vertex %zu is in eod table\n", g[v].idx);
DEBUG_PRINTF("vertex %zu is in eod table\n", g[v].index);
return true;
}
}
@ -4690,19 +4680,19 @@ void addEodAnchorProgram(RoseBuildImpl &build, build_context &bc,
continue;
}
DEBUG_PRINTF("vertex %zu (with %zu preds) fires on EOD\n", g[v].idx,
DEBUG_PRINTF("vertex %zu (with %zu preds) fires on EOD\n", g[v].index,
in_degree(v, g));
vector<RoseEdge> edge_list;
for (const auto &e : in_edges_range(v, g)) {
RoseVertex u = source(e, g);
if (build.isInETable(u) != in_etable) {
DEBUG_PRINTF("pred %zu %s in etable\n", g[u].idx,
DEBUG_PRINTF("pred %zu %s in etable\n", g[u].index,
in_etable ? "is not" : "is");
continue;
}
if (canEagerlyReportAtEod(build, e)) {
DEBUG_PRINTF("already done report for vertex %zu\n", g[u].idx);
DEBUG_PRINTF("already done report for vertex %zu\n", g[u].index);
continue;
}
edge_list.push_back(e);
@ -4745,8 +4735,8 @@ void addEodEventProgram(RoseBuildImpl &build, build_context &bc,
// Sort edge list for determinism, prettiness.
sort(begin(edge_list), end(edge_list),
[&g](const RoseEdge &a, const RoseEdge &b) {
return tie(g[source(a, g)].idx, g[target(a, g)].idx) <
tie(g[source(b, g)].idx, g[target(b, g)].idx);
return tie(g[source(a, g)].index, g[target(a, g)].index) <
tie(g[source(b, g)].index, g[target(b, g)].index);
});
program.add_block(
@ -5247,7 +5237,7 @@ aligned_unique_ptr<RoseEngine> RoseBuildImpl::buildFinalEngine(u32 minWidth) {
return nullptr;
}
u32 eodNfaIterOffset = buildEodNfaIterator(bc, leftfixBeginQueue);
buildCountingMiracles(*this, bc);
buildCountingMiracles(bc);
u32 queue_count = qif.allocated_count(); /* excludes anchored matcher q;
* som rev nfas */

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:
@ -163,7 +163,7 @@ void renovateCastle(RoseBuildImpl &tbi, CastleProto *castle,
for (RoseVertex v : verts) {
assert(g[v].left.castle.get() == castle);
DEBUG_PRINTF("%zu checks at lag %u\n", g[v].idx, g[v].left.lag);
DEBUG_PRINTF("%zu checks at lag %u\n", g[v].index, g[v].left.lag);
vector<rose_literal_id> lits = literals_for_vertex(tbi, v);
for (const auto &e : lits) {
DEBUG_PRINTF("%s +%u\n", dumpString(e.s).c_str(), e.delay);

View File

@ -205,14 +205,6 @@ bool RoseBuildImpl::hasOnlyPseudoStarInEdges(RoseVertex v) const {
return true;
}
void RoseBuildImpl::renumberVertices() {
vertexIndex = 0;
DEBUG_PRINTF("renumbering vertices\n");
for (auto v : vertices_range(g)) {
g[v].idx = vertexIndex++;
}
}
static
size_t trailerDueToSelf(const rose_literal_id &lit) {
size_t trailer = lit.s.length() - maxPeriod(lit.s);
@ -231,7 +223,7 @@ RoseRoleHistory findHistoryScheme(const RoseBuildImpl &tbi, const RoseEdge &e) {
const RoseVertex u = source(e, g); /* pred role */
const RoseVertex v = target(e, g); /* current role */
DEBUG_PRINTF("find history for [%zu,%zu]\n", g[u].idx, g[v].idx);
DEBUG_PRINTF("find history for [%zu,%zu]\n", g[u].index, g[v].index);
DEBUG_PRINTF("u has min_offset=%u, max_offset=%u\n", g[u].min_offset,
g[u].max_offset);
@ -285,7 +277,7 @@ RoseRoleHistory findHistoryScheme(const RoseBuildImpl &tbi, const RoseEdge &e) {
// Non-EOD cases.
DEBUG_PRINTF("examining edge [%zu,%zu] with bounds {%u,%u}\n",
g[u].idx, g[v].idx, g[e].minBound, g[e].maxBound);
g[u].index, g[v].index, g[e].minBound, g[e].maxBound);
if (tbi.isAnchored(v)) {
// Matches for literals in the anchored table will always arrive at the
@ -875,8 +867,8 @@ bool reduceTopTriggerLoad(RoseBuildImpl &build, NGHolder &h, RoseVertex u) {
if (tops.size() <= 1) {
return false;
}
DEBUG_PRINTF("%zu triggers %zu tops for %p\n", build.g[u].idx, tops.size(),
&h);
DEBUG_PRINTF("%zu triggers %zu tops for %p\n", build.g[u].index,
tops.size(), &h);
auto h_top_info = getTopInfo(h);
flat_set<NFAEdge> edges_to_trigger;
@ -976,7 +968,7 @@ void packInfixTops(NGHolder &h, RoseGraph &g,
}
h[e].tops = move(updated_tops);
if (h[e].tops.empty()) {
DEBUG_PRINTF("edge (start,%u) has only unused tops\n", h[v].index);
DEBUG_PRINTF("edge (start,%zu) has only unused tops\n", h[v].index);
dead.push_back(e);
}
}
@ -1311,15 +1303,9 @@ void addSmallBlockLiteral(RoseBuildImpl &tbi, const simple_anchored_info &sai,
assert(old_id < tbi.literal_info.size());
const rose_literal_info &li = tbi.literal_info[old_id];
// For compile determinism, operate over literal vertices in index
// order.
vector<RoseVertex> lit_verts(begin(li.vertices), end(li.vertices));
sort(begin(lit_verts), end(lit_verts), VertexIndexComp(g));
for (auto lit_v : lit_verts) {
for (auto lit_v : li.vertices) {
// Clone vertex with the new literal ID.
RoseVertex v = add_vertex(g[lit_v], g);
g[v].idx = tbi.vertexIndex++;
g[v].literals.clear();
g[v].literals.insert(lit_id);
g[v].min_offset = sai.min_bound + sai.literal.length();
@ -1347,7 +1333,6 @@ void addSmallBlockLiteral(RoseBuildImpl &tbi, const ue2_literal &lit,
RoseGraph &g = tbi.g;
RoseVertex v = add_vertex(g);
g[v].idx = tbi.vertexIndex++;
g[v].literals.insert(lit_id);
g[v].reports = reports;
@ -1557,7 +1542,7 @@ bool historiesAreValid(const RoseGraph &g) {
for (const auto &e : edges_range(g)) {
if (g[e].history == ROSE_ROLE_HISTORY_INVALID) {
DEBUG_PRINTF("edge [%zu,%zu] has invalid history\n",
g[source(e, g)].idx, g[target(e, g)].idx);
g[source(e, g)].index, g[target(e, g)].index);
return false;
}
}
@ -1576,18 +1561,20 @@ bool danglingVertexRef(RoseBuildImpl &tbi) {
const ue2::unordered_set<RoseVertex> valid_vertices(vi, ve);
if (!contains(valid_vertices, tbi.anchored_root)) {
DEBUG_PRINTF("anchored root vertex %p not in graph\n",
tbi.anchored_root);
DEBUG_PRINTF("anchored root vertex %zu not in graph\n",
tbi.g[tbi.anchored_root].index);
return true;
}
for (const auto &e : tbi.ghost) {
if (!contains(valid_vertices, e.first)) {
DEBUG_PRINTF("ghost key vertex %p not in graph\n", e.first);
DEBUG_PRINTF("ghost key vertex %zu not in graph\n",
tbi.g[e.first].index);
return true;
}
if (!contains(valid_vertices, e.second)) {
DEBUG_PRINTF("ghost value vertex %p not in graph\n", e.second);
DEBUG_PRINTF("ghost value vertex %zu not in graph\n",
tbi.g[e.second].index);
return true;
}
}
@ -1599,11 +1586,11 @@ static
bool roleOffsetsAreValid(const RoseGraph &g) {
for (auto v : vertices_range(g)) {
if (g[v].min_offset >= ROSE_BOUND_INF) {
DEBUG_PRINTF("invalid min_offset for role %zu\n", g[v].idx);
DEBUG_PRINTF("invalid min_offset for role %zu\n", g[v].index);
return false;
}
if (g[v].min_offset > g[v].max_offset) {
DEBUG_PRINTF("min_offset > max_offset for %zu\n", g[v].idx);
DEBUG_PRINTF("min_offset > max_offset for %zu\n", g[v].index);
return false;
}
}

View File

@ -290,7 +290,7 @@ bool isUnconvertibleLeaf(const RoseBuildImpl &tbi, const RoseVertex v) {
// Find all of the leaves with literals whose length is <= len.
static
void findBadLeaves(RoseBuildImpl &tbi, RoseVertexSet &bad) {
void findBadLeaves(RoseBuildImpl &tbi, set<RoseVertex> &bad) {
RoseGraph &g = tbi.g;
u32 len = tbi.cc.grey.roseMaxBadLeafLength;
@ -309,15 +309,7 @@ void findBadLeaves(RoseBuildImpl &tbi, RoseVertexSet &bad) {
const rose_literal_info &info = tbi.literal_info[lid];
// Because we do the "clone pred and re-home" trick below, we need to
// iterate over our vertices in a defined ordering, otherwise we'll get
// non-determinism in our bytecode. So, copy and sort this literal's
// vertices.
vector<RoseVertex> verts(info.vertices.begin(), info.vertices.end());
sort(verts.begin(), verts.end(), VertexIndexComp(g));
for (auto v : verts) {
for (auto v : info.vertices) {
if (!isLeafNode(v, g)) {
continue;
}
@ -331,7 +323,7 @@ void findBadLeaves(RoseBuildImpl &tbi, RoseVertexSet &bad) {
const RoseEdge &e = *in_edges(v, g).first;
RoseVertex u = source(e, g);
if (out_degree(u, g) != 1) {
DEBUG_PRINTF("re-homing %zu to cloned pred\n", g[v].idx);
DEBUG_PRINTF("re-homing %zu to cloned pred\n", g[v].index);
RoseVertex u2 = tbi.cloneVertex(u);
for (const auto &e_in : in_edges_range(u, g)) {
add_edge(source(e_in, g), u2, g[e_in], g);
@ -340,7 +332,7 @@ void findBadLeaves(RoseBuildImpl &tbi, RoseVertexSet &bad) {
remove_edge(e, g);
}
DEBUG_PRINTF("%zu is a bad leaf vertex\n", g[v].idx);
DEBUG_PRINTF("%zu is a bad leaf vertex\n", g[v].index);
bad.insert(v);
}
}
@ -348,7 +340,7 @@ void findBadLeaves(RoseBuildImpl &tbi, RoseVertexSet &bad) {
void convertBadLeaves(RoseBuildImpl &tbi) {
RoseGraph &g = tbi.g;
RoseVertexSet bad(g);
set<RoseVertex> bad;
findBadLeaves(tbi, bad);
DEBUG_PRINTF("found %zu bad leaves\n", bad.size());
@ -371,7 +363,7 @@ void convertBadLeaves(RoseBuildImpl &tbi) {
RoseVertex u = source(e, g);
assert(!g[u].suffix);
g[u].suffix.graph = h;
DEBUG_PRINTF("%zu's nfa holder %p\n", g[u].idx, h.get());
DEBUG_PRINTF("%zu's nfa holder %p\n", g[u].index, h.get());
dead.push_back(v);
}
@ -784,7 +776,7 @@ bool handleMixedPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
assert(in_degree(h.acceptEod, h) == 1);
bool anchored = !proper_out_degree(h.startDs, h);
NFAVertex key = nullptr;
NFAVertex key = NGHolder::null_vertex();
NFAVertex base = anchored ? h.start : h.startDs;
if (!anchored) {
@ -798,7 +790,7 @@ bool handleMixedPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
}
for (auto w : adjacent_vertices_range(base, h)) {
DEBUG_PRINTF("checking %u\n", h[w].index);
DEBUG_PRINTF("checking %zu\n", h[w].index);
if (!h[w].char_reach.all()) {
continue;
}
@ -833,7 +825,7 @@ bool handleMixedPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
set<NFAVertex> exits_and_repeat_verts;
for (auto repeat_v : ri.vertices) {
DEBUG_PRINTF("repeat vertex %u\n", h[repeat_v].index);
DEBUG_PRINTF("repeat vertex %zu\n", h[repeat_v].index);
succ(h, repeat_v, &exits_and_repeat_verts);
exits_and_repeat_verts.insert(repeat_v);
}
@ -963,7 +955,7 @@ void convertPrefixToBounds(RoseBuildImpl &tbi) {
continue;
}
DEBUG_PRINTF("inspecting prefix of %zu\n", g[v].idx);
DEBUG_PRINTF("inspecting prefix of %zu\n", g[v].index);
if (!proper_out_degree(h.startDs, h)) {
if (handleStartPrefixCliche(h, g, v, e, ar, &to_delete)) {
@ -1009,7 +1001,7 @@ void convertPrefixToBounds(RoseBuildImpl &tbi) {
continue;
}
DEBUG_PRINTF("inspecting prefix of %zu\n", g[v].idx);
DEBUG_PRINTF("inspecting prefix of %zu\n", g[v].index);
if (!proper_out_degree(h.startDs, h)) {
if (handleStartPrefixCliche(h, g, v, e, ar, &to_delete)) {
@ -1044,7 +1036,7 @@ void convertAnchPrefixToBounds(RoseBuildImpl &tbi) {
continue;
}
DEBUG_PRINTF("vertex %zu\n", g[v].idx);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
// This pass runs after makeCastles, so we use the fact that bounded
// repeat detection has already been done for us.

View File

@ -104,7 +104,7 @@ public:
}
os << "[label=\"";
os << "idx=" << g[v].idx <<"\\n";
os << "index=" << g[v].index <<"\\n";
for (u32 lit_id : g[v].literals) {
writeLiteral(os, lit_id);
@ -267,14 +267,14 @@ void dumpRoseGraph(const RoseBuild &build_base, const RoseEngine *t,
ofstream os(ss.str());
RoseGraphWriter writer(build, t);
writeGraphviz(os, build.g, writer, get(&RoseVertexProps::idx, build.g));
writeGraphviz(os, build.g, writer, get(boost::vertex_index, build.g));
}
namespace {
struct CompareVertexRole {
explicit CompareVertexRole(const RoseGraph &g_in) : g(g_in) {}
inline bool operator()(const RoseVertex &a, const RoseVertex &b) const {
return g[a].idx < g[b].idx;
return g[a].index < g[b].index;
}
private:
const RoseGraph &g;
@ -372,7 +372,7 @@ void dumpRoseLiterals(const RoseBuildImpl &build, const char *filename) {
for (RoseVertex v : verts) {
// role info
os << " Index " << g[v].idx << ": groups=0x" << hex << setw(16)
os << " Index " << g[v].index << ": groups=0x" << hex << setw(16)
<< setfill('0') << g[v].groups << dec;
if (g[v].reports.empty()) {
@ -386,13 +386,13 @@ void dumpRoseLiterals(const RoseBuildImpl &build, const char *filename) {
// pred info
for (const auto &ie : in_edges_range(v, g)) {
const auto &u = source(ie, g);
os << " Predecessor idx=";
os << " Predecessor index=";
if (u == build.root) {
os << "ROOT";
} else if (u == build.anchored_root) {
os << "ANCHORED_ROOT";
} else {
os << g[u].idx;
os << g[u].index;
}
os << ": bounds [" << g[ie].minBound << ", ";
if (g[ie].maxBound == ROSE_BOUND_INF) {

View File

@ -136,7 +136,7 @@ rose_group calcLocalGroup(const RoseVertex v, const RoseGraph &g,
}
} else {
DEBUG_PRINTF("not sibling different mother %zu %zu\n",
g[v].idx, g[w].idx);
g[v].index, g[w].index);
}
}
}
@ -382,7 +382,7 @@ void assignGroupsToRoles(RoseBuildImpl &build) {
g[ghost_it->second].groups |= succ_groups;
}
DEBUG_PRINTF("vertex %zu: groups=%llx\n", g[v].idx, g[v].groups);
DEBUG_PRINTF("vertex %zu: groups=%llx\n", g[v].index, g[v].groups);
}
}
@ -397,8 +397,7 @@ getVertexGroupMap(const RoseBuildImpl &build) {
vector<RoseVertex> v_order;
v_order.reserve(num_vertices(g));
boost::topological_sort(g, back_inserter(v_order),
vertex_index_map(get(&RoseVertexProps::idx, g)));
boost::topological_sort(g, back_inserter(v_order));
unordered_map<RoseVertex, rose_group> vertex_group_map;
vertex_group_map.reserve(num_vertices(g));
@ -406,7 +405,7 @@ getVertexGroupMap(const RoseBuildImpl &build) {
const rose_group initial_groups = build.getInitialGroups();
for (const auto &v : boost::adaptors::reverse(v_order)) {
DEBUG_PRINTF("vertex %zu\n", g[v].idx);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
if (build.isAnyStart(v)) {
DEBUG_PRINTF("start vertex, groups=0x%llx\n", initial_groups);
@ -419,7 +418,7 @@ getVertexGroupMap(const RoseBuildImpl &build) {
assert(in_degree(v, g) > 0);
rose_group pred_groups = ~rose_group{0};
for (auto u : inv_adjacent_vertices_range(v, g)) {
DEBUG_PRINTF("pred %zu\n", g[u].idx);
DEBUG_PRINTF("pred %zu\n", g[u].index);
assert(contains(vertex_group_map, u));
pred_groups &= vertex_group_map.at(u);
}

View File

@ -527,8 +527,6 @@ public:
// max overlap considered for every pair (ulit, vlit).
size_t maxLiteralOverlap(RoseVertex u, RoseVertex v) const;
void renumberVertices(void);
bool isPseudoStar(const RoseEdge &e) const;
bool isPseudoStarOrFirstOnly(const RoseEdge &e) const;
bool hasOnlyPseudoStarInEdges(RoseVertex v) const;
@ -551,7 +549,6 @@ public:
const RoseVertex anchored_root;
RoseLiteralMap literals;
std::map<RoseVertex, RoseVertex> ghost;
size_t vertexIndex;
ReportID getNewNfaReport() override {
return next_nfa_report++;
}

View File

@ -110,7 +110,7 @@ void contractVertex(NGHolder &g, NFAVertex v,
static
u32 findMaxLiteralMatches(const NGHolder &h, const set<ue2_literal> &lits) {
DEBUG_PRINTF("h=%p, %zu literals\n", &h, lits.size());
//dumpGraph("infix.dot", h.g);
//dumpGraph("infix.dot", h);
// Indices of vertices that could terminate any of the literals in 'lits'.
set<u32> terms;
@ -163,7 +163,7 @@ u32 findMaxLiteralMatches(const NGHolder &h, const set<ue2_literal> &lits) {
}
remove_vertices(dead, g);
//dumpGraph("relaxed.dot", g.g);
//dumpGraph("relaxed.dot", g);
depth maxWidth = findMaxWidth(g);
DEBUG_PRINTF("maxWidth=%s\n", maxWidth.str().c_str());
@ -286,7 +286,7 @@ void findCountingMiracleInfo(const left_id &left, const vector<u8> &stopTable,
CharReach cyclic_cr;
for (NFAVertex v : cyclics) {
DEBUG_PRINTF("considering %u ||=%zu\n", g[v].index,
DEBUG_PRINTF("considering %zu ||=%zu\n", g[v].index,
g[v].char_reach.count());
cyclic_cr |= g[v].char_reach;
}

View File

@ -261,7 +261,7 @@ void findForwardReach(const RoseGraph &g, const RoseVertex v,
for (const auto &e : out_edges_range(v, g)) {
RoseVertex t = target(e, g);
if (!g[t].left) {
DEBUG_PRINTF("successor %zu has no leftfix\n", g[t].idx);
DEBUG_PRINTF("successor %zu has no leftfix\n", g[t].index);
return;
}
rose_look.push_back(map<s32, CharReach>());
@ -585,7 +585,7 @@ bool getTransientPrefixReach(const NGHolder &g, u32 lag,
NFAVertex v = *(inv_adjacent_vertices(g.accept, g).first);
u32 i = lag + 1;
while (v != g.startDs) {
DEBUG_PRINTF("i=%u, v=%u\n", i, g[v].index);
DEBUG_PRINTF("i=%u, v=%zu\n", i, g[v].index);
if (is_special(v, g)) {
DEBUG_PRINTF("special\n");
return false;

View File

@ -102,7 +102,7 @@ bool maskFromLeftGraph(const LeftEngInfo &left, vector<u8> &msk,
CharReach cr;
for (NFAVertex v : curr) {
const auto &v_cr = h[v].char_reach;
DEBUG_PRINTF("vertex %u, reach %s\n", h[v].index,
DEBUG_PRINTF("vertex %zu, reach %s\n", h[v].index,
describeClass(v_cr).c_str());
cr |= v_cr;
insert(&next, inv_adjacent_vertices(v, h));
@ -438,45 +438,45 @@ static
bool isNoRunsVertex(const RoseBuildImpl &build, RoseVertex u) {
const RoseGraph &g = build.g;
if (!g[u].isBoring()) {
DEBUG_PRINTF("u=%zu is not boring\n", g[u].idx);
DEBUG_PRINTF("u=%zu is not boring\n", g[u].index);
return false;
}
if (!g[u].reports.empty()) {
DEBUG_PRINTF("u=%zu has accept\n", g[u].idx);
DEBUG_PRINTF("u=%zu has accept\n", g[u].index);
return false;
}
/* TODO: handle non-root roles as well. It can't be that difficult... */
if (!in_degree_equal_to(u, g, 1)) {
DEBUG_PRINTF("u=%zu is not a root role\n", g[u].idx);
if (in_degree(u, g) != 1) {
DEBUG_PRINTF("u=%zu is not a root role\n", g[u].index);
return false;
}
RoseEdge e;
bool exists;
tie(e, exists) = edge_by_target(build.root, u, g);
tie(e, exists) = edge(build.root, u, g);
if (!exists) {
DEBUG_PRINTF("u=%zu is not a root role\n", g[u].idx);
DEBUG_PRINTF("u=%zu is not a root role\n", g[u].index);
return false;
}
if (g[e].minBound != 0 || g[e].maxBound != ROSE_BOUND_INF) {
DEBUG_PRINTF("u=%zu has bounds from root\n", g[u].idx);
DEBUG_PRINTF("u=%zu has bounds from root\n", g[u].index);
return false;
}
for (const auto &oe : out_edges_range(u, g)) {
RoseVertex v = target(oe, g);
if (g[oe].maxBound != ROSE_BOUND_INF) {
DEBUG_PRINTF("edge (%zu,%zu) has max bound\n", g[u].idx,
g[target(oe, g)].idx);
DEBUG_PRINTF("edge (%zu,%zu) has max bound\n", g[u].index,
g[v].index);
return false;
}
if (g[v].left) {
DEBUG_PRINTF("v=%zu has rose prefix\n", g[v].idx);
DEBUG_PRINTF("v=%zu has rose prefix\n", g[v].index);
return false;
}
}
@ -563,7 +563,7 @@ u64a literalMinReportOffset(const RoseBuildImpl &build,
u64a lit_min_offset = UINT64_MAX;
for (const auto &v : info.vertices) {
DEBUG_PRINTF("vertex %zu min_offset=%u\n", g[v].idx, g[v].min_offset);
DEBUG_PRINTF("vertex %zu min_offset=%u\n", g[v].index, g[v].min_offset);
u64a vert_offset = g[v].min_offset;

View File

@ -206,8 +206,9 @@ void mergeDupeLeaves(RoseBuildImpl &tbi) {
continue;
}
DEBUG_PRINTF("inspecting vertex idx=%zu in_degree %zu out_degree %zu\n",
g[v].idx, in_degree(v, g), out_degree(v, g));
DEBUG_PRINTF("inspecting vertex index=%zu in_degree %zu "
"out_degree %zu\n", g[v].index, in_degree(v, g),
out_degree(v, g));
// Vertex must be a reporting leaf node
if (g[v].reports.empty() || !isLeafNode(v, g)) {
@ -227,13 +228,13 @@ void mergeDupeLeaves(RoseBuildImpl &tbi) {
}
RoseVertex t = leaves.find(dupe)->second;
DEBUG_PRINTF("found two leaf dupe roles, idx=%zu,%zu\n", g[v].idx,
g[t].idx);
DEBUG_PRINTF("found two leaf dupe roles, index=%zu,%zu\n", g[v].index,
g[t].index);
vector<RoseEdge> deadEdges;
for (const auto &e : in_edges_range(v, g)) {
RoseVertex u = source(e, g);
DEBUG_PRINTF("u idx=%zu\n", g[u].idx);
DEBUG_PRINTF("u index=%zu\n", g[u].index);
RoseEdge et;
bool exists;
tie (et, exists) = edge(u, t, g);
@ -244,7 +245,8 @@ void mergeDupeLeaves(RoseBuildImpl &tbi) {
deadEdges.push_back(e);
}
} else {
DEBUG_PRINTF("rehome edge: add %zu->%zu\n", g[u].idx, g[t].idx);
DEBUG_PRINTF("rehome edge: add %zu->%zu\n",
g[u].index, g[t].index);
add_edge(u, t, g[e], g);
deadEdges.push_back(e);
}
@ -279,7 +281,7 @@ void mergeDupeLeaves(RoseBuildImpl &tbi) {
// if we've removed anything, we need to renumber vertices
if (countRemovals) {
tbi.renumberVertices();
renumber_vertices(g);
DEBUG_PRINTF("removed %zu vertices.\n", countRemovals);
}
}
@ -350,7 +352,7 @@ void findUncalcLeavesCandidates(RoseBuildImpl &tbi,
// Ref count all suffixes, as we don't want to merge a suffix
// that happens to be shared with a non-leaf vertex somewhere.
DEBUG_PRINTF("vertex %zu has suffix %p\n", g[v].idx,
DEBUG_PRINTF("vertex %zu has suffix %p\n", g[v].index,
g[v].suffix.graph.get());
fcount[g[v].suffix.graph.get()]++;
@ -459,7 +461,7 @@ struct RoseGroup {
const RoseGraph &g = build.g;
assert(in_degree(v, g) == 1);
RoseVertex u = *inv_adjacent_vertices(v, g).first;
parent = g[u].idx;
parent = g[u].index;
}
bool operator<(const RoseGroup &b) const {
@ -580,14 +582,14 @@ bool dedupeLeftfixes(RoseBuildImpl &tbi) {
}
// Scan the rest of the list for dupes.
for (auto kt = next(jt); kt != jte; ++kt) {
for (auto kt = std::next(jt); kt != jte; ++kt) {
if (g[v].left == g[*kt].left || !rosecmp(v, *kt)) {
continue;
}
// Dupe found.
DEBUG_PRINTF("rose at vertex %zu is a dupe of %zu\n",
g[*kt].idx, g[v].idx);
g[*kt].index, g[v].index);
assert(g[v].left.lag == g[*kt].left.lag);
g[*kt].left = g[v].left;
work_done = true;
@ -1070,8 +1072,8 @@ bool mergeableRoseVertices(const RoseBuildImpl &tbi, RoseVertex u,
return false;
}
DEBUG_PRINTF("roses on %zu and %zu are mergeable\n", tbi.g[u].idx,
tbi.g[v].idx);
DEBUG_PRINTF("roses on %zu and %zu are mergeable\n", tbi.g[u].index,
tbi.g[v].index);
return true;
}
@ -1387,7 +1389,7 @@ void processMergeQueue(RoseBuildImpl &tbi, RoseBouquet &roses,
static
bool nfaHasNarrowStart(const NGHolder &g) {
if (hasGreaterOutDegree(1, g.startDs, g)) {
if (out_degree(g.startDs, g) > 1) {
return false; // unanchored
}
@ -1409,7 +1411,7 @@ bool nfaHasFiniteMaxWidth(const NGHolder &g) {
namespace {
struct RoseMergeKey {
RoseMergeKey(const RoseVertexSet &parents_in,
RoseMergeKey(const set<RoseVertex> &parents_in,
bool narrowStart_in, bool hasMaxWidth_in) :
narrowStart(narrowStart_in),
hasMaxWidth(hasMaxWidth_in),
@ -1427,7 +1429,7 @@ struct RoseMergeKey {
bool narrowStart;
bool hasMaxWidth;
RoseVertexSet parents;
set<RoseVertex> parents;
};
}
@ -1491,7 +1493,7 @@ void mergeLeftfixesVariableLag(RoseBuildImpl &tbi) {
map<RoseMergeKey, RoseBouquet> rosesByParent;
RoseGraph &g = tbi.g;
RoseVertexSet parents(g);
set<RoseVertex> parents;
DEBUG_PRINTF("-----\n");
DEBUG_PRINTF("entry\n");
@ -1626,7 +1628,7 @@ struct DedupeLeftKey {
: left_hash(hashLeftfix(build.g[v].left)) {
const auto &g = build.g;
for (const auto &e : in_edges_range(v, g)) {
preds.emplace(g[source(e, g)].idx, g[e].rose_top);
preds.emplace(g[source(e, g)].index, g[e].rose_top);
}
}
@ -1726,7 +1728,7 @@ void dedupeLeftfixesVariableLag(RoseBuildImpl &tbi) {
for (auto v : verts1) {
DEBUG_PRINTF("replacing report %u with %u on %zu\n",
g[v].left.leftfix_report,
v2_left.leftfix_report, g[v].idx);
v2_left.leftfix_report, g[v].index);
u32 orig_lag = g[v].left.lag;
g[v].left = v2_left;
g[v].left.lag = orig_lag;
@ -1758,7 +1760,7 @@ void replaceTops(NGHolder &h, const map<u32, u32> &top_mapping) {
}
flat_set<u32> new_tops;
for (u32 t : h[e].tops) {
DEBUG_PRINTF("vertex %u has top %u\n", h[v].index, t);
DEBUG_PRINTF("vertex %zu has top %u\n", h[v].index, t);
new_tops.insert(top_mapping.at(t));
}
h[e].tops = move(new_tops);
@ -1806,7 +1808,7 @@ bool setDistinctRoseTops(RoseGraph &g, NGHolder &h1, const NGHolder &h2,
}
for (auto v : verts1) {
DEBUG_PRINTF("vertex %zu\n", g[v].idx);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
assert(!g[v].left.haig);
assert(!g[v].left.dfa);
for (const auto &e : in_edges_range(v, g)) {
@ -1815,7 +1817,7 @@ bool setDistinctRoseTops(RoseGraph &g, NGHolder &h1, const NGHolder &h2,
assert(contains(top_mapping, t));
g[e].rose_top = top_mapping[t];
DEBUG_PRINTF("edge (%zu,%zu) went from top %u to %u\n",
g[source(e, g)].idx, g[target(e, g)].idx, t,
g[source(e, g)].index, g[target(e, g)].index, t,
top_mapping[t]);
}
}
@ -1836,7 +1838,7 @@ bool setDistinctSuffixTops(RoseGraph &g, NGHolder &h1, const NGHolder &h2,
}
for (auto v : verts1) {
DEBUG_PRINTF("vertex %zu\n", g[v].idx);
DEBUG_PRINTF("vertex %zu\n", g[v].index);
u32 t = g[v].suffix.top;
assert(contains(top_mapping, t));
g[v].suffix.top = top_mapping[t];

View File

@ -75,7 +75,6 @@ RoseBuildImpl::RoseBuildImpl(ReportManager &rm_in,
: cc(cc_in),
root(add_vertex(g)),
anchored_root(add_vertex(g)),
vertexIndex(0),
delay_base_id(MO_INVALID_IDX),
hasSom(false),
group_end(0),
@ -89,11 +88,9 @@ RoseBuildImpl::RoseBuildImpl(ReportManager &rm_in,
boundary(boundary_in),
next_nfa_report(0) {
// add root vertices to graph
g[root].idx = vertexIndex++;
g[root].min_offset = 0;
g[root].max_offset = 0;
g[anchored_root].idx = vertexIndex++;
g[anchored_root].min_offset = 0;
g[anchored_root].max_offset = 0;
}
@ -193,7 +190,7 @@ bool RoseBuildImpl::hasLiteralInTable(RoseVertex v,
bool RoseBuildImpl::hasNoFloatingRoots() const {
for (auto v : adjacent_vertices_range(root, g)) {
if (isFloating(v)) {
DEBUG_PRINTF("direct floating root %zu\n", g[v].idx);
DEBUG_PRINTF("direct floating root %zu\n", g[v].index);
return false;
}
}
@ -201,7 +198,7 @@ bool RoseBuildImpl::hasNoFloatingRoots() const {
/* need to check if the anchored_root has any literals which are too deep */
for (auto v : adjacent_vertices_range(anchored_root, g)) {
if (isFloating(v)) {
DEBUG_PRINTF("indirect floating root %zu\n", g[v].idx);
DEBUG_PRINTF("indirect floating root %zu\n", g[v].index);
return false;
}
}
@ -337,14 +334,14 @@ size_t RoseBuildImpl::maxLiteralOverlap(RoseVertex u, RoseVertex v) const {
void RoseBuildImpl::removeVertices(const vector<RoseVertex> &dead) {
for (auto v : dead) {
assert(!isAnyStart(v));
DEBUG_PRINTF("removing vertex %zu\n", g[v].idx);
DEBUG_PRINTF("removing vertex %zu\n", g[v].index);
for (auto lit_id : g[v].literals) {
literal_info[lit_id].vertices.erase(v);
}
clear_vertex_faster(v, g);
clear_vertex(v, g);
remove_vertex(v, g);
}
renumberVertices();
renumber_vertices(g);
}
// Find the maximum bound on the edges to this vertex's successors ignoring
@ -893,7 +890,6 @@ bool operator<(const RoseEdgeProps &a, const RoseEdgeProps &b) {
// Note: only clones the vertex, you'll have to wire up your own edges.
RoseVertex RoseBuildImpl::cloneVertex(RoseVertex v) {
RoseVertex v2 = add_vertex(g[v], g);
g[v2].idx = vertexIndex++;
for (const auto &lit_id : g[v2].literals) {
literal_info[lit_id].vertices.insert(v2);
@ -1277,7 +1273,7 @@ bool canImplementGraphs(const RoseBuildImpl &tbi) {
// First, check the Rose leftfixes.
for (auto v : vertices_range(g)) {
DEBUG_PRINTF("leftfix: check vertex %zu\n", g[v].idx);
DEBUG_PRINTF("leftfix: check vertex %zu\n", g[v].index);
if (g[v].left.castle) {
DEBUG_PRINTF("castle ok\n");
@ -1295,8 +1291,8 @@ bool canImplementGraphs(const RoseBuildImpl &tbi) {
assert(g[v].left.graph->kind
== (tbi.isRootSuccessor(v) ? NFA_PREFIX : NFA_INFIX));
if (!isImplementableNFA(*g[v].left.graph, nullptr, tbi.cc)) {
DEBUG_PRINTF("nfa prefix %zu failed (%zu vertices)\n", g[v].idx,
num_vertices(*g[v].left.graph));
DEBUG_PRINTF("nfa prefix %zu failed (%zu vertices)\n",
g[v].index, num_vertices(*g[v].left.graph));
return false;
}
}
@ -1305,7 +1301,7 @@ bool canImplementGraphs(const RoseBuildImpl &tbi) {
// Suffix graphs.
for (auto v : vertices_range(g)) {
DEBUG_PRINTF("suffix: check vertex %zu\n", g[v].idx);
DEBUG_PRINTF("suffix: check vertex %zu\n", g[v].index);
const RoseSuffixInfo &suffix = g[v].suffix;
if (suffix.castle) {
@ -1323,8 +1319,8 @@ bool canImplementGraphs(const RoseBuildImpl &tbi) {
if (suffix.graph) {
assert(suffix.graph->kind == NFA_SUFFIX);
if (!isImplementableNFA(*suffix.graph, &tbi.rm, tbi.cc)) {
DEBUG_PRINTF("nfa suffix %zu failed (%zu vertices)\n", g[v].idx,
num_vertices(*suffix.graph));
DEBUG_PRINTF("nfa suffix %zu failed (%zu vertices)\n",
g[v].index, num_vertices(*suffix.graph));
return false;
}
}

View File

@ -111,11 +111,9 @@ struct AliasInEdge : EdgeAndVertex {
class CandidateSet {
public:
typedef RoseVertexSet::iterator iterator;
typedef set<RoseVertex>::iterator iterator;
typedef RoseVertex key_type;
explicit CandidateSet(const VertexIndexComp &comp) : main_cont(comp) {}
iterator begin() { return main_cont.begin(); }
iterator end() { return main_cont.end(); }
@ -151,7 +149,7 @@ public:
private:
/* if a vertex is worth storing, it is worth storing twice */
RoseVertexSet main_cont; /* deterministic iterator */
set<RoseVertex> main_cont; /* deterministic iterator */
ue2::unordered_set<RoseVertex> hash_cont; /* member checks */
};
@ -258,7 +256,7 @@ bool samePredecessors(RoseVertex a, RoseVertex b, const RoseGraph &g) {
for (const auto &e_a : in_edges_range(a, g)) {
bool exists;
RoseEdge e;
tie(e, exists) = edge_by_target(source(e_a, g), b, g);
tie(e, exists) = edge(source(e_a, g), b, g);
if (!exists || g[e].rose_top != g[e_a].rose_top) {
DEBUG_PRINTF("bad tops\n");
return false;
@ -297,7 +295,7 @@ bool hasCommonPredWithBadBounds(RoseVertex a, RoseVertex b,
for (const auto &e_a : in_edges_range(a, g)) {
bool exists;
RoseEdge e;
tie(e, exists) = edge_by_target(source(e_a, g), b, g);
tie(e, exists) = edge(source(e_a, g), b, g);
if (exists) {
if (g[e_a].maxBound < g[e].minBound
|| g[e].maxBound < g[e_a].minBound) {
@ -498,11 +496,11 @@ void mergeEdgeAdd(RoseVertex u, RoseVertex v, const RoseEdge &from_edge,
const RoseEdgeProps &from_props = g[from_edge];
if (!to_edge) {
DEBUG_PRINTF("adding edge [%zu,%zu]\n", g[u].idx, g[v].idx);
DEBUG_PRINTF("adding edge [%zu,%zu]\n", g[u].index, g[v].index);
add_edge(u, v, from_props, g);
} else {
// union of the two edges.
DEBUG_PRINTF("updating edge [%zu,%zu]\n", g[u].idx, g[v].idx);
DEBUG_PRINTF("updating edge [%zu,%zu]\n", g[u].index, g[v].index);
RoseEdgeProps &to_props = g[*to_edge];
to_props.minBound = min(to_props.minBound, from_props.minBound);
to_props.maxBound = max(to_props.maxBound, from_props.maxBound);
@ -626,7 +624,7 @@ static
void mergeVerticesLeft(RoseVertex a, RoseVertex b, RoseBuildImpl &build,
RoseAliasingInfo &rai) {
RoseGraph &g = build.g;
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].index, g[b].index);
insert(&g[b].reports, g[a].reports);
@ -648,7 +646,7 @@ static
void mergeVerticesRight(RoseVertex a, RoseVertex b, RoseBuildImpl &build,
RoseAliasingInfo &rai) {
RoseGraph &g = build.g;
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].index, g[b].index);
insert(&g[b].reports, g[a].reports);
g[b].min_offset = min(g[a].min_offset, g[b].min_offset);
@ -666,7 +664,7 @@ static
void mergeVerticesDiamond(RoseVertex a, RoseVertex b, RoseBuildImpl &build,
RoseAliasingInfo &rai) {
RoseGraph &g = build.g;
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].idx, g[b].idx);
DEBUG_PRINTF("merging vertex %zu into %zu\n", g[a].index, g[b].index);
// For a diamond merge, most properties are already the same (with the
// notable exception of the literal set).
@ -683,7 +681,7 @@ static never_inline
void findCandidates(const RoseBuildImpl &build, CandidateSet *candidates) {
for (auto v : vertices_range(build.g)) {
if (isAliasingCandidate(v, build)) {
DEBUG_PRINTF("candidate %zu\n", build.g[v].idx);
DEBUG_PRINTF("candidate %zu\n", build.g[v].index);
DEBUG_PRINTF("lits: %u\n", *build.g[v].literals.begin());
candidates->insert(v);
}
@ -748,7 +746,7 @@ bool hasCommonPredWithDiffRoses(RoseVertex a, RoseVertex b,
for (const auto &e_a : in_edges_range(a, g)) {
bool exists;
RoseEdge e;
tie(e, exists) = edge_by_target(source(e_a, g), b, g);
tie(e, exists) = edge(source(e_a, g), b, g);
if (exists) {
DEBUG_PRINTF("common pred, e_r=%d r_t %u,%u\n",
(int)equal_roses, g[e].rose_top, g[e_a].rose_top);
@ -890,7 +888,7 @@ void pruneUnusedTops(NGHolder &h, const RoseGraph &g,
used_tops.begin(), used_tops.end(), pt_inserter);
h[e].tops = move(pruned_tops);
if (h[e].tops.empty()) {
DEBUG_PRINTF("edge (start,%u) has only unused tops\n", h[v].index);
DEBUG_PRINTF("edge (start,%zu) has only unused tops\n", h[v].index);
dead.push_back(e);
}
}
@ -1295,7 +1293,7 @@ bool attemptRoseGraphMerge(RoseBuildImpl &build, bool preds_same, RoseVertex a,
}
DEBUG_PRINTF("attempting merge of roses on vertices %zu and %zu\n",
g[a].idx, g[b].idx);
g[a].index, g[b].index);
set<RoseVertex> &b_verts = rai.rev_leftfix[b_left];
set<RoseVertex> aa;
@ -1387,7 +1385,7 @@ bool attemptRoseMerge(RoseBuildImpl &build, bool preds_same, RoseVertex a,
RoseVertex b, bool trivialCasesOnly,
RoseAliasingInfo &rai) {
DEBUG_PRINTF("attempting rose merge, vertices a=%zu, b=%zu\n",
build.g[a].idx, build.g[b].idx);
build.g[a].index, build.g[b].index);
assert(a != b);
RoseGraph &g = build.g;
@ -1600,7 +1598,7 @@ void diamondMergePass(CandidateSet &candidates, RoseBuildImpl &build,
assert(contains(candidates, a));
DEBUG_PRINTF("trying to merge %zu into somebody\n", g[a].idx);
DEBUG_PRINTF("trying to merge %zu into somebody\n", g[a].index);
for (auto jt = it; jt != siblings.end(); ++jt) {
RoseVertex b = *jt;
assert(contains(candidates, b));
@ -1714,8 +1712,8 @@ void leftMergePass(CandidateSet &candidates, RoseBuildImpl &build,
RoseVertex pred = pickPred(a, g, build);
siblings.clear();
if (pred == RoseGraph::null_vertex() || build.isAnyStart(pred) ||
hasGreaterOutDegree(verts.size(), pred, g)) {
if (pred == RoseGraph::null_vertex() || build.isAnyStart(pred)
|| out_degree(pred, g) > verts.size()) {
// Select sibling from amongst the vertices that share a literal.
siblings.insert(siblings.end(), verts.begin(), verts.end());
} else {
@ -1724,8 +1722,6 @@ void leftMergePass(CandidateSet &candidates, RoseBuildImpl &build,
insert(&siblings, siblings.end(), adjacent_vertices(pred, g));
}
sort(siblings.begin(), siblings.end(), VertexIndexComp(g));
auto jt = findLeftMergeSibling(siblings.begin(), siblings.end(), a,
build, rai, candidates);
if (jt == siblings.end()) {
@ -1754,12 +1750,12 @@ bool safeRootPreds(RoseVertex a, RoseVertex b, const RoseGraph &g) {
set<RoseVertex> a_roots, b_roots;
for (auto u : inv_adjacent_vertices_range(a, g)) {
if (!hasGreaterInDegree(0, u, g)) {
if (!in_degree(u, g)) {
a_roots.insert(u);
}
}
for (auto u : inv_adjacent_vertices_range(b, g)) {
if (!hasGreaterInDegree(0, u, g)) {
if (!in_degree(u, g)) {
b_roots.insert(u);
}
}
@ -1867,8 +1863,8 @@ void buildCandidateRightSiblings(CandidateSet &candidates, RoseBuildImpl &build,
u32 lit_id = *g[a].literals.begin();
RoseVertex succ = pickSucc(a, g);
const auto &verts = build.literal_info.at(lit_id).vertices;
if (succ != RoseGraph::null_vertex() &&
!hasGreaterInDegree(verts.size(), succ, g)) {
if (succ != RoseGraph::null_vertex()
&& in_degree(succ, g) < verts.size()) {
if (!done_succ.insert(succ).second) {
continue; // succ already in done_succ.
}
@ -1901,7 +1897,7 @@ void buildCandidateRightSiblings(CandidateSet &candidates, RoseBuildImpl &build,
}
for (auto &siblings : sibling_cache | map_values) {
sort(siblings.begin(), siblings.end(), VertexIndexComp(build.g));
sort(siblings.begin(), siblings.end());
}
}
@ -1976,7 +1972,7 @@ bool hasNoDiamondSiblings(const RoseGraph &g, RoseVertex v) {
if (has_successor(v, g)) {
bool only_succ = true;
for (const auto &w : adjacent_vertices_range(v, g)) {
if (hasGreaterInDegree(1, w, g)) {
if (in_degree(w, g) > 1) {
only_succ = false;
break;
}
@ -1992,7 +1988,7 @@ bool hasNoDiamondSiblings(const RoseGraph &g, RoseVertex v) {
bool only_pred = true;
for (const auto &u : inv_adjacent_vertices_range(v, g)) {
if (hasGreaterOutDegree(1, u, g)) {
if (out_degree(u, g) > 1) {
only_pred = false;
break;
}
@ -2040,7 +2036,7 @@ void aliasRoles(RoseBuildImpl &build, bool mergeRoses) {
mergeRoses &= cc.grey.mergeRose & cc.grey.roseMergeRosesDuringAliasing;
CandidateSet candidates(g);
CandidateSet candidates;
findCandidates(build, &candidates);
DEBUG_PRINTF("candidates %zu\n", candidates.size());

View File

@ -39,31 +39,6 @@ namespace ue2 {
/** Max allowed width for transient graphs in block mode */
#define ROSE_BLOCK_TRANSIENT_MAX_WIDTH 255U
// Comparator for vertices using their index property.
struct VertexIndexComp {
VertexIndexComp(const RoseGraph &gg) : g(gg) {}
bool operator()(const RoseVertex &a, const RoseVertex &b) const {
const RoseVertexProps &pa = g[a];
const RoseVertexProps &pb = g[b];
if (pa.idx < pb.idx) {
return true;
}
if (pa.idx > pb.idx) {
return false;
}
assert(a == b); // All vertex indices should be distinct.
return a < b;
}
const RoseGraph &g;
};
// Vertex set type, ordered by index. Construct with a graph reference.
typedef std::set<RoseVertex, VertexIndexComp> RoseVertexSet;
/**
* \brief Add two Rose depths together, coping correctly with infinity at
* ROSE_BOUND_INF.

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,19 +77,20 @@ u32 findMinWidth(const RoseBuildImpl &tbi, enum rose_literal_table table) {
u32 minWidth = ROSE_BOUND_INF;
for (auto v : reachable) {
if (g[v].eod_accept) {
DEBUG_PRINTF("skipping %zu - not a real vertex\n", g[v].idx);
DEBUG_PRINTF("skipping %zu - not a real vertex\n", g[v].index);
continue;
}
const u32 w = g[v].min_offset;
if (!g[v].reports.empty()) {
DEBUG_PRINTF("%zu can fire report at offset %u\n", g[v].idx, w);
DEBUG_PRINTF("%zu can fire report at offset %u\n", g[v].index, w);
minWidth = min(minWidth, w);
}
if (is_end_anchored(g, v)) {
DEBUG_PRINTF("%zu can fire eod report at offset %u\n", g[v].idx, w);
DEBUG_PRINTF("%zu can fire eod report at offset %u\n", g[v].index,
w);
minWidth = min(minWidth, w);
}
@ -98,7 +99,7 @@ u32 findMinWidth(const RoseBuildImpl &tbi, enum rose_literal_table table) {
assert(suffix_width.is_reachable());
DEBUG_PRINTF("%zu has suffix with top %u (width %s), can fire "
"report at %u\n",
g[v].idx, g[v].suffix.top, suffix_width.str().c_str(),
g[v].index, g[v].suffix.top, suffix_width.str().c_str(),
w + suffix_width);
minWidth = min(minWidth, w + suffix_width);
}
@ -203,10 +204,10 @@ u32 findMaxBAWidth(const RoseBuildImpl &tbi, enum rose_literal_table table) {
// Everyone's anchored, so the max width can be taken from the max
// max_offset on our vertices (so long as all accepts are ACCEPT_EOD).
for (auto v : reachable) {
DEBUG_PRINTF("inspecting vert %zu\n", g[v].idx);
DEBUG_PRINTF("inspecting vert %zu\n", g[v].index);
if (g[v].eod_accept) {
DEBUG_PRINTF("skipping %zu - not a real vertex\n", g[v].idx);
DEBUG_PRINTF("skipping %zu - not a real vertex\n", g[v].index);
continue;
}

View File

@ -44,11 +44,10 @@
#include "util/charreach.h"
#include "util/depth.h"
#include "util/ue2_containers.h"
#include "util/ue2_graph.h"
#include <memory>
#include <set>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
namespace ue2 {
@ -139,7 +138,7 @@ struct RoseSuffixInfo {
/** \brief Properties attached to each Rose graph vertex. */
struct RoseVertexProps {
/** \brief Unique dense vertex index. Used for BGL algorithms. */
size_t idx = ~size_t{0};
size_t index = ~size_t{0};
/** \brief IDs of literals in the Rose literal map. */
flat_set<u32> literals;
@ -183,6 +182,9 @@ struct RoseVertexProps {
/** \brief Properties attached to each Rose graph edge. */
/* bounds are distance from end of prev to start of the next */
struct RoseEdgeProps {
/** \brief Unique dense vertex index. Used for BGL algorithms. */
size_t index = ~size_t{0};
/**
* \brief Minimum distance from the end of the source role's match to the
* start of the target role's match.
@ -215,18 +217,10 @@ bool operator<(const RoseEdgeProps &a, const RoseEdgeProps &b);
/**
* \brief Core Rose graph structure.
*
* Note that we use the list selector for the edge and vertex lists: we depend
* on insertion order for determinism, so we must use these containers.
*/
using RoseGraph = boost::adjacency_list<boost::listS, // out edge list per vertex
boost::listS, // vertex list
boost::bidirectionalS, // bidirectional
RoseVertexProps, // bundled vertex properties
RoseEdgeProps, // bundled edge properties
boost::listS // graph edge list
>;
struct RoseGraph : public ue2_graph<RoseGraph, RoseVertexProps, RoseEdgeProps> {
friend class RoseBuildImpl; /* to allow index renumbering */
};
using RoseVertex = RoseGraph::vertex_descriptor;
using RoseEdge = RoseGraph::edge_descriptor;

View File

@ -122,7 +122,7 @@ void dumpPreRoseGraph(const RoseInGraph &ig, const Grey &grey,
ostringstream name;
name << grey.dumpPath << "pre_rose_" << id << ".dot";
dumpGraph(name.str().c_str(), h->g);
dumpGraph(name.str().c_str(), *h);
assert(allMatchStatesHaveReports(*h));
}

View File

@ -46,13 +46,11 @@
#include "ue2common.h"
#include "rose/rose_common.h"
#include "util/ue2_containers.h"
#include "util/ue2_graph.h"
#include "util/ue2string.h"
#include <memory>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
namespace ue2 {
class NGHolder;
@ -128,6 +126,7 @@ public:
flat_set<ReportID> reports; /**< for RIV_ACCEPT/RIV_ACCEPT_EOD */
u32 min_offset; /**< Minimum offset at which this vertex can match. */
u32 max_offset; /**< Maximum offset at which this vertex can match. */
size_t index = 0;
};
struct RoseInEdgeProps {
@ -174,11 +173,12 @@ struct RoseInEdgeProps {
std::shared_ptr<raw_som_dfa> haig;
u32 graph_lag;
size_t index = 0;
};
typedef boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS,
RoseInVertexProps,
RoseInEdgeProps> RoseInGraph;
struct RoseInGraph
: public ue2_graph<RoseInGraph, RoseInVertexProps, RoseInEdgeProps> {
};
typedef RoseInGraph::vertex_descriptor RoseInVertex;
typedef RoseInGraph::edge_descriptor RoseInEdge;

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:
@ -48,27 +48,15 @@ using namespace std;
namespace ue2 {
static
void populateIndexMap(const RoseInGraph &in,
map<RoseInVertex, size_t> *index_map) {
size_t i = 0;
for (auto v : vertices_range(in)) {
(*index_map)[v] = i++;
}
}
/* Returns a topological ordering of the vertices in g. That is the starts are
* at the front and all the predecessors of a vertex occur earlier in the list
* than the vertex. */
vector<RoseInVertex> topo_order(const RoseInGraph &g) {
map<RoseInVertex, size_t> index_map;
populateIndexMap(g, &index_map);
assert(hasCorrectlyNumberedVertices(g));
vector<RoseInVertex> v_order;
v_order.reserve(index_map.size());
v_order.reserve(num_vertices(g));
topological_sort(g, back_inserter(v_order),
vertex_index_map(boost::make_assoc_property_map(index_map)));
boost::topological_sort(g, back_inserter(v_order));
reverse(v_order.begin(), v_order.end()); /* put starts at the front */
@ -105,6 +93,7 @@ private:
}
unique_ptr<RoseInGraph> cloneRoseGraph(const RoseInGraph &ig) {
assert(hasCorrectlyNumberedVertices(ig));
unique_ptr<RoseInGraph> out = make_unique<RoseInGraph>();
unordered_map<const NGHolder *, shared_ptr<NGHolder>> graph_map;
@ -120,12 +109,8 @@ unique_ptr<RoseInGraph> cloneRoseGraph(const RoseInGraph &ig) {
}
}
map<RoseInVertex, size_t> index_map;
populateIndexMap(ig, &index_map);
copy_graph(ig, *out,
boost::edge_copy(RoseEdgeCopier(ig, *out, graph_map, haig_map))
.vertex_index_map(boost::make_assoc_property_map(index_map)));
boost::edge_copy(RoseEdgeCopier(ig, *out, graph_map, haig_map)));
return out;
}

View File

@ -126,7 +126,7 @@ bool pruneOverlongReports(NFAVertex v, NGHolder &g, const depth &max_depth,
}
if (g[v].reports.empty()) {
DEBUG_PRINTF("none of vertex %u's reports can match, cut accepts\n",
DEBUG_PRINTF("none of vertex %zu's reports can match, cut accepts\n",
g[v].index);
remove_edge(v, g.accept, g);
remove_edge(v, g.acceptEod, 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:
@ -34,7 +34,7 @@
#define SLOT_MANAGER_H
#include "ue2common.h"
#include "nfagraph/ng_graph.h"
#include "nfagraph/ng_holder.h"
#include "util/alloc.h"
#include "util/ue2_containers.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:
@ -249,6 +249,15 @@ string describeClass(const CharReach &cr, size_t maxLength,
return oss.str();
}
string describeClasses(const std::vector<CharReach> &v, size_t maxClassLength,
enum cc_output_t out_type) {
std::ostringstream oss;
for (const auto &cr : v) {
describeClass(oss, cr, maxClassLength, out_type);
}
return oss.str();
}
// C stdio wrapper
void describeClass(FILE *f, const CharReach &cr, size_t maxLength,
enum cc_output_t out_type) {

View File

@ -38,6 +38,7 @@
#include <cstdio>
#include <ostream>
#include <string>
#include <vector>
namespace ue2 {
@ -54,6 +55,10 @@ void describeClass(std::ostream &os, const CharReach &cr, size_t maxLength = 16,
std::string describeClass(const CharReach &cr, size_t maxLength = 16,
enum cc_output_t out_type = CC_OUT_TEXT);
std::string describeClasses(const std::vector<CharReach> &v,
size_t maxClassLength = 16,
enum cc_output_t out_type = CC_OUT_TEXT);
void describeClass(FILE *f, const CharReach &cr, size_t maxLength,
enum cc_output_t out_type);

View File

@ -38,71 +38,18 @@
#include "util/graph_range.h"
#include "util/ue2_containers.h"
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/graph_traits.hpp>
#include <algorithm>
#include <utility>
#include <vector>
namespace ue2 {
/** \brief True if the given vertex has no out-edges. */
template<class Graph>
bool isLeafNode(const typename Graph::vertex_descriptor& v, const Graph& g) {
typename Graph::adjacency_iterator ai, ae;
std::tie(ai, ae) = adjacent_vertices(v, g);
return ai == ae; // no out edges
}
/** \brief True if the out-degree of vertex \a v is greater than the given
* limit. */
template<class Graph>
bool hasGreaterOutDegree(size_t limit,
const typename Graph::vertex_descriptor& v,
const Graph& g) {
typename Graph::out_edge_iterator ei, ee;
for (std::tie(ei, ee) = out_edges(v, g); ei != ee; ++ei) {
if (limit-- == 0) {
return true;
}
}
return false;
}
/** \brief Returns true if the in-degree of vertex \a v is greater than the
* given limit. */
template<class Graph>
bool hasGreaterInDegree(size_t limit,
const typename Graph::vertex_descriptor& v,
const Graph& g) {
typename Graph::in_edge_iterator ei, ee;
for (std::tie(ei, ee) = in_edges(v, g); ei != ee; ++ei) {
if (limit-- == 0) {
return true;
}
}
return false;
}
/**
* \brief True if the degree of vertex \a v is greater than the given limit.
*/
template <class Graph>
bool has_greater_degree(size_t limit,
const typename Graph::vertex_descriptor &v,
const Graph &g) {
typename Graph::in_edge_iterator ei, ee;
for (std::tie(ei, ee) = in_edges(v, g); ei != ee; ++ei) {
if (limit-- == 0) {
return true;
}
}
typename Graph::out_edge_iterator oi, oe;
for (std::tie(oi, oe) = out_edges(v, g); oi != oe; ++oi) {
if (limit-- == 0) {
return true;
}
}
return false;
return out_degree(v, g) == 0;
}
/** \brief True if vertex \a v has an edge to itself. */
@ -137,48 +84,10 @@ size_t proper_in_degree(const typename Graph::vertex_descriptor &v,
return in_degree(v, g) - (edge(v, v, g).second ? 1 : 0);
}
/** \brief Returns true iff the in-degree of vertex \a v is \a expected */
template<class Graph>
bool in_degree_equal_to(const typename Graph::vertex_descriptor &v,
const Graph &g, size_t expected) {
size_t seen = 0;
typename Graph::in_edge_iterator ei, ee;
for (std::tie(ei, ee) = in_edges(v, g);; ++ei, seen++) {
if (seen == expected) {
return ei == ee;
}
if (ei == ee) {
return false;
}
}
}
/** \brief same as edge(s, t, g) by finds edge by inspecting in-edges of target.
* Should be used when it is known that t has a small in-degree and when s
* may have a large out-degree.
*/
template<class Graph>
std::pair<typename Graph::edge_descriptor, bool>
edge_by_target(const typename Graph::vertex_descriptor &s,
const typename Graph::vertex_descriptor &t, const Graph &g) {
typename Graph::in_edge_iterator ei, ee;
for (std::tie(ei, ee) = in_edges(t, g); ei != ee; ++ei) {
if (source(*ei, g) == s) {
return std::make_pair(*ei, true);
}
}
return std::make_pair(typename Graph::edge_descriptor(), false);
}
/** \brief True if vertex \a v has at least one successor. */
template<class Graph>
bool has_successor(const typename Graph::vertex_descriptor &v, const Graph &g) {
typename Graph::adjacency_iterator ai, ae;
std::tie(ai, ae) = adjacent_vertices(v, g);
return ai != ae;
return out_degree(v, g) > 0;
}
/** \brief True if vertex \a v has at least one successor other than itself. */
@ -197,26 +106,6 @@ bool has_proper_successor(const typename Graph::vertex_descriptor &v,
return ai != ae;
}
/** \brief A version of clear_vertex that explicitly removes in- and out-edges
* for vertex \a v. For many graphs, this is faster than the BGL clear_vertex
* function, which walks the graph's full edge list. */
template <class Graph>
void clear_vertex_faster(typename Graph::vertex_descriptor v, Graph &g) {
typename Graph::in_edge_iterator ei, ee;
tie(ei, ee) = in_edges(v, g);
while (ei != ee) {
remove_edge(*ei++, g);
}
typename Graph::out_edge_iterator oi, oe;
tie(oi, oe) = out_edges(v, g);
while (oi != oe) {
// NOTE: version that takes out_edge_iterator is faster according to
// the BGL docs.
remove_edge(oi++, g);
}
}
/** \brief Find the set of vertices that are reachable from the vertices in \a
* sources. */
template<class Graph, class SourceCont, class OutCont>
@ -329,6 +218,40 @@ std::pair<typename Graph::edge_descriptor, bool> add_edge_if_not_present(
return e;
}
#ifndef NDEBUG
template <class Graph>
bool hasCorrectlyNumberedVertices(const Graph &g) {
auto count = num_vertices(g);
std::vector<bool> ids(count, false);
for (auto v : vertices_range(g)) {
auto id = g[v].index;
if (id >= count || ids[id]) {
return false; // duplicate
}
ids[id] = true;
}
return std::find(ids.begin(), ids.end(), false) == ids.end()
&& count == vertex_index_upper_bound(g);
}
template <class Graph>
bool hasCorrectlyNumberedEdges(const Graph &g) {
auto count = num_edges(g);
std::vector<bool> ids(count, false);
for (const auto &e : edges_range(g)) {
auto id = g[e].index;
if (id >= count || ids[id]) {
return false; // duplicate
}
ids[id] = true;
}
return std::find(ids.begin(), ids.end(), false) == ids.end()
&& count == edge_index_upper_bound(g);
}
#endif
} // namespace ue2
#endif // UTIL_GRAPH_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:
@ -51,7 +51,6 @@
#ifndef UTIL_GRAPH_RANGE_H
#define UTIL_GRAPH_RANGE_H
#include <boost/graph/adjacency_list.hpp>
#include <boost/range/iterator_range.hpp>
namespace ue2 {

1083
src/util/ue2_graph.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -84,7 +84,7 @@ TEST(NFAGraph, RemoveEquivalence1) {
ASSERT_TRUE(tmpcr.test('a'));
}
// check if we found our vertex
ASSERT_TRUE(a != nullptr);
ASSERT_TRUE(a != NGHolder::null_vertex());
// There should be two edges from v to nodes with reachability 'b' and 'c'
NFAVertex b = NGHolder::null_vertex();
@ -101,8 +101,8 @@ TEST(NFAGraph, RemoveEquivalence1) {
}
}
// check if we found our vertices
ASSERT_TRUE(b != nullptr);
ASSERT_TRUE(c != nullptr);
ASSERT_TRUE(b != NGHolder::null_vertex());
ASSERT_TRUE(c != NGHolder::null_vertex());
// both vertices should have an edge to accept
ASSERT_TRUE(edge(b, g.accept, g).second);
@ -145,7 +145,7 @@ TEST(NFAGraph, RemoveEquivalence2) {
ASSERT_TRUE(tmpcr.test('a'));
}
// check if we found our vertex
ASSERT_TRUE(a != nullptr);
ASSERT_TRUE(a != NGHolder::null_vertex());
// There should be two edges from v to nodes with reachability 'b' and 'c'
NFAVertex b = NGHolder::null_vertex();
@ -162,8 +162,8 @@ TEST(NFAGraph, RemoveEquivalence2) {
}
}
// check if we found our vertices
ASSERT_TRUE(b != nullptr);
ASSERT_TRUE(c != nullptr);
ASSERT_TRUE(b != NGHolder::null_vertex());
ASSERT_TRUE(c != NGHolder::null_vertex());
// both new vertices should have edges from startDs
ASSERT_TRUE(edge(g.startDs, b, g).second);
@ -207,7 +207,7 @@ TEST(NFAGraph, RemoveEquivalence3) {
ASSERT_TRUE(tmpcr.test('a'));
}
// check if we found our 'a'
ASSERT_TRUE(a != nullptr);
ASSERT_TRUE(a != NGHolder::null_vertex());
// There should be an edge from 'a' to '.'
ASSERT_EQ(1U, out_degree(a, g));
@ -234,7 +234,6 @@ TEST(NFAGraph, RemoveEquivalence3) {
NFAVertex X = NGHolder::null_vertex();
NFAVertex Y = NGHolder::null_vertex();
for (NFAVertex tmp : adjacent_vertices_range(dot2, g)) {
// we already know about dot1, so skip it
if (tmp == dot1) {
continue;
@ -251,8 +250,8 @@ TEST(NFAGraph, RemoveEquivalence3) {
}
}
// check if we found both vertices
ASSERT_TRUE(X != nullptr);
ASSERT_TRUE(Y != nullptr);
ASSERT_TRUE(X != NGHolder::null_vertex());
ASSERT_TRUE(Y != NGHolder::null_vertex());
// finally, check if these two vertices only have edges to accept
ASSERT_EQ(1U, out_degree(X, g));
@ -306,8 +305,8 @@ TEST(NFAGraph, RemoveEquivalence4) {
}
}
// check if we found both vertices
ASSERT_TRUE(X != nullptr);
ASSERT_TRUE(Y != nullptr);
ASSERT_TRUE(X != NGHolder::null_vertex());
ASSERT_TRUE(Y != NGHolder::null_vertex());
// now, find first dot from X
ASSERT_EQ(1U, out_degree(X, g));
@ -351,7 +350,7 @@ TEST(NFAGraph, RemoveEquivalence4) {
}
}
// make sure we found our 'a'
ASSERT_TRUE(a != nullptr);
ASSERT_TRUE(a != NGHolder::null_vertex());
// now, check if 'a' has an edge to accept
ASSERT_EQ(1U, out_degree(a, g));
@ -396,7 +395,7 @@ TEST(NFAGraph, RemoveEquivalence5) {
ASSERT_TRUE(edge(v, v, g).second);
}
// check if we found our vertex
ASSERT_TRUE(v != nullptr);
ASSERT_TRUE(v != NGHolder::null_vertex());
// now, find the vertex leading to accept
NFAVertex v2 = NGHolder::null_vertex();
@ -414,7 +413,7 @@ TEST(NFAGraph, RemoveEquivalence5) {
ASSERT_TRUE(edge(tmp, g.accept, g).second);
}
// check if we found our vertex
ASSERT_TRUE(v2 != nullptr);
ASSERT_TRUE(v2 != NGHolder::null_vertex());
}
// catching UE-2692
@ -452,7 +451,7 @@ TEST(NFAGraph, RemoveEquivalence6) {
ASSERT_TRUE(edge(v, g.accept, g).second);
}
// check if we found our vertex
ASSERT_TRUE(v != nullptr);
ASSERT_TRUE(v != NGHolder::null_vertex());
}
// catching UE-2692
@ -492,7 +491,7 @@ TEST(NFAGraph, RemoveEquivalence7) {
ASSERT_EQ(1U, proper_out_degree(v, g));
}
// check if we found our vertex
ASSERT_TRUE(v != nullptr);
ASSERT_TRUE(v != NGHolder::null_vertex());
// find the next vertex and ensure it has an edge to accept
NFAVertex v2 = NGHolder::null_vertex();
@ -511,7 +510,7 @@ TEST(NFAGraph, RemoveEquivalence7) {
ASSERT_TRUE(edge(v2, g.accept, g).second);
}
// check if we found our vertex
ASSERT_TRUE(v2 != nullptr);
ASSERT_TRUE(v2 != NGHolder::null_vertex());
}
TEST(NFAGraph, RemoveEquivalence_Reports1) {

View File

@ -55,13 +55,13 @@ TEST(NFAGraph, RemoveRedundancy1) {
unique_ptr<NGWrapper> graph(constructGraphWithCC("(a|b)c", cc, 0));
ASSERT_TRUE(graph.get() != nullptr);
NGHolder &g = *graph;
// Run removeRedundancy
removeRedundancy(*graph, SOM_NONE);
NFAGraph &g = graph->g;
removeRedundancy(g, SOM_NONE);
// Our graph should only have two non-special nodes
ASSERT_EQ((size_t)N_SPECIALS + 2, num_vertices(*graph));
ASSERT_EQ((size_t)N_SPECIALS + 2, num_vertices(g));
// Dot-star start state should be connected to itself and a single other
// vertex
@ -98,13 +98,13 @@ TEST(NFAGraph, RemoveRedundancy2) {
unique_ptr<NGWrapper> graph(constructGraphWithCC("a.*b?c", cc,
HS_FLAG_DOTALL));
ASSERT_TRUE(graph.get() != nullptr);
NGHolder &g = *graph;
// Run removeRedundancy
removeRedundancy(*graph, SOM_NONE);
NFAGraph &g = graph->g;
removeRedundancy(g, SOM_NONE);
// Our graph should now have only 3 non-special vertices
ASSERT_EQ((size_t)N_SPECIALS + 3, num_vertices(*graph));
ASSERT_EQ((size_t)N_SPECIALS + 3, num_vertices(g));
// Dot-star start state should be connected to itself and a single other
// vertex
@ -156,12 +156,12 @@ TEST(NFAGraph, RemoveRedundancy3) {
cc, 0));
ASSERT_TRUE(graph.get() != nullptr);
unsigned countBefore = num_vertices(graph->g);
unsigned countBefore = num_vertices(*graph);
removeRedundancy(*graph, SOM_NONE);
// The '(a|b)?' construction (two states) should have disappeared, leaving
// this expr as 'foobar.*teakettle'
ASSERT_EQ(countBefore - 2, num_vertices(graph->g));
ASSERT_EQ(countBefore - 2, num_vertices(*graph));
}
TEST(NFAGraph, RemoveRedundancy4) {
@ -169,11 +169,11 @@ TEST(NFAGraph, RemoveRedundancy4) {
unique_ptr<NGWrapper> graph(constructGraphWithCC("foo([A-Z]|a|b|q)", cc, 0));
ASSERT_TRUE(graph.get() != nullptr);
unsigned countBefore = num_vertices(graph->g);
unsigned countBefore = num_vertices(*graph);
removeRedundancy(*graph, SOM_NONE);
// We should end up with the alternation collapsing into one state
ASSERT_EQ(countBefore - 3, num_vertices(graph->g));
ASSERT_EQ(countBefore - 3, num_vertices(*graph));
}
TEST(NFAGraph, RemoveRedundancy5) {
@ -182,12 +182,12 @@ TEST(NFAGraph, RemoveRedundancy5) {
cc, 0));
ASSERT_TRUE(graph.get() != nullptr);
unsigned countBefore = num_vertices(graph->g);
unsigned countBefore = num_vertices(*graph);
removeRedundancy(*graph, SOM_NONE);
// Since we don't return a start offset, the first state ('[0-9]?') is
// redundant.
ASSERT_EQ(countBefore - 1, num_vertices(graph->g));
ASSERT_EQ(countBefore - 1, num_vertices(*graph));
}
TEST(NFAGraph, RemoveEdgeRedundancy1) {
@ -196,12 +196,12 @@ TEST(NFAGraph, RemoveEdgeRedundancy1) {
auto graph = constructGraphWithCC("A+hatstand", cc, HS_FLAG_DOTALL);
ASSERT_TRUE(graph.get() != nullptr);
unsigned countBefore = num_edges(graph->g);
unsigned countBefore = num_edges(*graph);
removeEdgeRedundancy(*graph, SOM_NONE, cc);
// One edge (the self-loop on the leading A+) should have been removed.
ASSERT_EQ(countBefore - 1, num_edges(graph->g));
ASSERT_EQ(countBefore - 1, num_edges(*graph));
}
TEST(NFAGraph, RemoveEdgeRedundancy2) {
@ -210,12 +210,12 @@ TEST(NFAGraph, RemoveEdgeRedundancy2) {
auto graph = constructGraphWithCC("foo.*A*bar", cc, HS_FLAG_DOTALL);
ASSERT_TRUE(graph.get() != nullptr);
size_t numEdgesBefore = num_edges(graph->g);
size_t numVertsBefore = num_vertices(graph->g);
size_t numEdgesBefore = num_edges(*graph);
size_t numVertsBefore = num_vertices(*graph);
removeEdgeRedundancy(*graph, SOM_NONE, cc);
// The .* should swallow up the A* and its self-loop.
ASSERT_EQ(numEdgesBefore - 4, num_edges(graph->g));
ASSERT_EQ(numVertsBefore - 1, num_vertices(graph->g));
ASSERT_EQ(numEdgesBefore - 4, num_edges(*graph));
ASSERT_EQ(numVertsBefore - 1, num_vertices(*graph));
}

View File

@ -64,7 +64,6 @@ RoseVertex addVertex(RoseBuildImpl &build, RoseVertex parent, u32 lit_id) {
RoseGraph &g = build.g;
RoseVertex v = add_vertex(g);
g[v].idx = build.vertexIndex++;
g[v].min_offset = 0;
g[v].max_offset = ROSE_BOUND_INF;
g[v].literals.insert(lit_id);

View File

@ -144,7 +144,7 @@ void findPaths(const NGHolder &g, CorpusProperties &cProps,
ue2::unordered_set<NFAVertex> one_way_in;
for (const auto &v : vertices_range(g)) {
if (!hasGreaterInDegree(1, v, g)) {
if (in_degree(v, g) <= 1) {
one_way_in.insert(v);
}
}
@ -155,7 +155,7 @@ void findPaths(const NGHolder &g, CorpusProperties &cProps,
ptr_vector<VertexPath>::auto_type p = open.pop_back();
NFAVertex u = p->back();
DEBUG_PRINTF("dequeuing path %s, back %u\n",
DEBUG_PRINTF("dequeuing path %s, back %zu\n",
pathToString(g, *p).c_str(), g[u].index);
NGHolder::adjacency_iterator ai, ae;
@ -187,7 +187,7 @@ void findPaths(const NGHolder &g, CorpusProperties &cProps,
// Note that vertices that only have one predecessor don't need
// their cycle limit checked, as their predecessors will have
// the same count.
DEBUG_PRINTF("exceeded cycle limit for v=%u, pruning path\n",
DEBUG_PRINTF("exceeded cycle limit for v=%zu, pruning path\n",
g[v].index);
continue;
}
@ -301,7 +301,7 @@ void CorpusGeneratorImpl::addRandom(const min_max &mm, string *out) {
}
unsigned char CorpusGeneratorImpl::getChar(NFAVertex v) {
const CharReach &cr = graph.g[v].char_reach;
const CharReach &cr = graph[v].char_reach;
switch (cProps.throwDice()) {
case CorpusProperties::ROLLED_MATCH:
@ -521,7 +521,7 @@ CorpusGeneratorUtf8::pathToCorpus(const vector<CodePointSet> &path) {
}
static
u32 classify_vertex(const NFAGraph &g, NFAVertex v) {
u32 classify_vertex(const NGHolder &g, NFAVertex v) {
const CharReach &cr = g[v].char_reach;
if (cr.isSubsetOf(UTF_ASCII_CR)) {
return 1;
@ -560,7 +560,7 @@ void expandCodePointSet(const CharReach &cr, CodePointSet *out, u32 mask,
}
static
void decodePath(const NFAGraph &g, const VertexPath &in,
void decodePath(const NGHolder &g, const VertexPath &in,
vector<CodePointSet> &out) {
VertexPath::const_iterator it = in.begin();
while (it != in.end()) {
@ -618,7 +618,7 @@ void translatePaths(const NGHolder &graph,
assert(out);
for (const auto &path : allPathsTemp) {
out->push_back(vector<CodePointSet>());
decodePath(graph.g, path, out->back());
decodePath(graph, path, out->back());
}
}

View File

@ -34,7 +34,7 @@
#include "ng_find_matches.h"
#include "nfagraph/ng_graph.h"
#include "nfagraph/ng_holder.h"
#include "nfagraph/ng_util.h"
#include "parser/position.h"
#include "util/container.h"