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

@@ -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;
}