allow edge_descriptors to be created from pair<edge_descriptor, bool>

This commit is contained in:
Alex Coyte 2016-08-30 16:08:49 +10:00 committed by Matthew Barr
parent e1e9010cac
commit 530d84c6f3
23 changed files with 86 additions and 130 deletions

View File

@ -174,7 +174,7 @@ void replaceAssertVertex(NGWrapper &g, NFAVertex t, edge_cache_t &edge_cache,
auto ecit = edge_cache.find(cache_key); auto ecit = edge_cache.find(cache_key);
if (ecit == edge_cache.end()) { if (ecit == edge_cache.end()) {
DEBUG_PRINTF("adding edge %zu %zu\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; NFAEdge e = add_edge(u, v, g);
edge_cache.emplace(cache_key, e); edge_cache.emplace(cache_key, e);
g[e].assert_flags = flags; g[e].assert_flags = flags;
if (++assert_edge_count > MAX_ASSERT_EDGES) { if (++assert_edge_count > MAX_ASSERT_EDGES) {

View File

@ -904,7 +904,7 @@ void addToHolder(NGHolder &g, u32 top, const PureRepeat &pr) {
u32 min_bound = pr.bounds.min; // always finite u32 min_bound = pr.bounds.min; // always finite
if (min_bound == 0) { // Vacuous case, we can only do this once. if (min_bound == 0) { // Vacuous case, we can only do this once.
assert(!edge(g.start, g.accept, g).second); assert(!edge(g.start, g.accept, g).second);
NFAEdge e = add_edge(g.start, g.accept, g).first; NFAEdge e = add_edge(g.start, g.accept, g);
g[e].tops.insert(top); g[e].tops.insert(top);
g[u].reports.insert(pr.reports.begin(), pr.reports.end()); g[u].reports.insert(pr.reports.begin(), pr.reports.end());
min_bound = 1; min_bound = 1;
@ -913,7 +913,7 @@ void addToHolder(NGHolder &g, u32 top, const PureRepeat &pr) {
for (u32 i = 0; i < min_bound; i++) { for (u32 i = 0; i < min_bound; i++) {
NFAVertex v = add_vertex(g); NFAVertex v = add_vertex(g);
g[v].char_reach = pr.reach; g[v].char_reach = pr.reach;
NFAEdge e = add_edge(u, v, g).first; NFAEdge e = add_edge(u, v, g);
if (u == g.start) { if (u == g.start) {
g[e].tops.insert(top); g[e].tops.insert(top);
} }
@ -932,7 +932,7 @@ void addToHolder(NGHolder &g, u32 top, const PureRepeat &pr) {
if (head != u) { if (head != u) {
add_edge(head, v, g); add_edge(head, v, g);
} }
NFAEdge e = add_edge(u, v, g).first; NFAEdge e = add_edge(u, v, g);
if (u == g.start) { if (u == g.start) {
g[e].tops.insert(top); g[e].tops.insert(top);
} }

View File

@ -544,7 +544,7 @@ void filterAccelStates(NGHolder &g, const map<u32, set<NFAVertex>> &tops,
// Similarly, connect (start, startDs) if necessary. // Similarly, connect (start, startDs) if necessary.
if (!edge(g.start, g.startDs, g).second) { if (!edge(g.start, g.startDs, g).second) {
auto e = add_edge(g.start, g.startDs, g).first; NFAEdge e = add_edge(g.start, g.startDs, g);
tempEdges.push_back(e); // Remove edge later. tempEdges.push_back(e); // Remove edge later.
} }

View File

@ -377,17 +377,14 @@ void resolveEdges(ReportManager &rm, NGWrapper &g, set<NFAEdge> *dead) {
add_edge(vv, g.accept, g); add_edge(vv, g.accept, g);
g[e].assert_flags = 0; g[e].assert_flags = 0;
add_edge(u, vv, g[e], g); add_edge(u, vv, g[e], g);
if (!edge(u, g.acceptEod, g).second) { /* there may already be a different edge from start to eod if so
add_edge(u, g.acceptEod, g[e], g); * we need to make it unconditional and alive
} else { */
/* there may already be a different edge from start to eod if (NFAEdge start_eod = edge(u, g.acceptEod, g)) {
* if so we need to make it unconditional and alive
*/
NFAEdge start_eod = edge(u, g.acceptEod, g).first;
g[start_eod].assert_flags = 0; g[start_eod].assert_flags = 0;
dead->erase(start_eod); dead->erase(start_eod);
} else {
add_edge(u, g.acceptEod, g[e], g);
} }
dead->insert(e); dead->insert(e);
} }
@ -433,17 +430,14 @@ void resolveEdges(ReportManager &rm, NGWrapper &g, set<NFAEdge> *dead) {
add_edge(vv, g.accept, g); add_edge(vv, g.accept, g);
g[e].assert_flags = 0; g[e].assert_flags = 0;
add_edge(u, vv, g[e], g); add_edge(u, vv, g[e], g);
if (!edge(u, g.acceptEod, g).second) { /* there may already be a different edge from start to eod if so
add_edge(u, g.acceptEod, g[e], g); * we need to make it unconditional and alive
} else { */
/* there may already be a different edge from start to eod if (NFAEdge start_eod = edge(u, g.acceptEod, g)) {
* if so we need to make it unconditional and alive
*/
NFAEdge start_eod = edge(u, g.acceptEod, g).first;
g[start_eod].assert_flags = 0; g[start_eod].assert_flags = 0;
dead->erase(start_eod); dead->erase(start_eod);
} else {
add_edge(u, g.acceptEod, g[e], g);
} }
dead->insert(e); dead->insert(e);
} }
@ -496,10 +490,8 @@ void ensureCodePointStart(ReportManager &rm, NGWrapper &g) {
* boundaries. Assert resolution handles the badness coming from asserts. * boundaries. Assert resolution handles the badness coming from asserts.
* The only other source of trouble is startDs->accept connections. * The only other source of trouble is startDs->accept connections.
*/ */
bool exists; NFAEdge orig = edge(g.startDs, g.accept, g);
NFAEdge orig; if (g.utf8 && orig) {
tie(orig, exists) = edge(g.startDs, g.accept, g);
if (g.utf8 && exists) {
DEBUG_PRINTF("rectifying %u\n", g.reportId); DEBUG_PRINTF("rectifying %u\n", g.reportId);
Report ir = rm.getBasicInternalReport(g); Report ir = rm.getBasicInternalReport(g);
ReportID rep = rm.getInternalId(ir); ReportID rep = rm.getInternalId(ir);

View File

@ -194,9 +194,7 @@ pair<NFAEdge, bool> NFABuilderImpl::addEdge(NFAVertex u, NFAVertex v) {
// assert that the edge doesn't already exist // assert that the edge doesn't already exist
assert(edge(u, v, *graph).second == false); assert(edge(u, v, *graph).second == false);
pair<NFAEdge, bool> e = add_edge(u, v, *graph); return add_edge(u, v, *graph);
assert(e.second);
return e;
} }
void NFABuilderImpl::addEdge(Position startPos, Position endPos) { void NFABuilderImpl::addEdge(Position startPos, Position endPos) {

View File

@ -564,7 +564,7 @@ void mergeClass(vector<unique_ptr<VertexInfo>> &infos, NGHolder &g,
pred_info->succ.erase(old_vertex_info); pred_info->succ.erase(old_vertex_info);
// if edge doesn't exist, create it // if edge doesn't exist, create it
NFAEdge e = add_edge_if_not_present(pred_info->v, new_v, g).first; NFAEdge e = add_edge_if_not_present(pred_info->v, new_v, g);
// put edge tops, if applicable // put edge tops, if applicable
if (!edgetops.empty()) { if (!edgetops.empty()) {
@ -576,7 +576,7 @@ void mergeClass(vector<unique_ptr<VertexInfo>> &infos, NGHolder &g,
if (new_v_eod) { if (new_v_eod) {
NFAEdge ee = add_edge_if_not_present(pred_info->v, new_v_eod, NFAEdge ee = add_edge_if_not_present(pred_info->v, new_v_eod,
g).first; g);
// put edge tops, if applicable // put edge tops, if applicable
if (!edgetops.empty()) { if (!edgetops.empty()) {

View File

@ -92,7 +92,7 @@ void addReverseEdges(NGHolder &g, vector<NFAEdge> &reverseEdge,
if (it == allEdges.end()) { if (it == allEdges.end()) {
// No reverse edge, add one. // No reverse edge, add one.
NFAVertex u = source(fwd, g), v = target(fwd, g); NFAVertex u = source(fwd, g), v = target(fwd, g);
NFAEdge rev = add_edge(v, u, g).first; NFAEdge rev = add_edge(v, u, g);
it = allEdges.insert(make_pair(make_pair(vidx, uidx), rev)).first; it = allEdges.insert(make_pair(make_pair(vidx, uidx), rev)).first;
// Add to capacity map. // Add to capacity map.
u32 revIndex = g[rev].index; u32 revIndex = g[rev].index;

View File

@ -307,10 +307,8 @@ void markForRemoval(const NFAVertex v, VertexInfoMap &infoMap,
static static
bool hasInEdgeTops(const NGHolder &g, NFAVertex v) { bool hasInEdgeTops(const NGHolder &g, NFAVertex v) {
bool exists; NFAEdge e = edge(g.start, v, g);
NFAEdge e; return e && !g[e].tops.empty();
tie(e, exists) = edge(g.start, v, g);
return exists && !g[e].tops.empty();
} }
/** Transform (1), removal of redundant vertices. */ /** Transform (1), removal of redundant vertices. */
@ -737,11 +735,10 @@ u32 findCyclic(const NGHolder &g, vector<bool> &cyclic) {
for (auto v : vertices_range(g)) { for (auto v : vertices_range(g)) {
assert(g[v].index < cyclic.size()); assert(g[v].index < cyclic.size());
bool c = edge(v, v, g).second; if (hasSelfLoop(v, g)) {
if (c) {
count++; count++;
cyclic[g[v].index] = true;
} }
cyclic[g[v].index] = c;
} }
return count; return count;

View File

@ -1121,7 +1121,7 @@ NFAVertex buildTriggerStates(NGHolder &g, const vector<CharReach> &trigger,
g[v].char_reach = cr; g[v].char_reach = cr;
add_edge(u, v, g); add_edge(u, v, g);
if (u == g.start) { if (u == g.start) {
g[edge(u, v, g).first].tops.insert(top); g[edge(u, v, g)].tops.insert(top);
} }
u = v; u = v;
} }

View File

@ -55,7 +55,7 @@ void wireStartToTops(NGHolder &g, const flat_set<NFAVertex> &tops,
for (NFAVertex v : tops) { for (NFAVertex v : tops) {
assert(!isLeafNode(v, g)); assert(!isLeafNode(v, g));
const NFAEdge &e = add_edge(g.start, v, g).first; const NFAEdge &e = add_edge(g.start, v, g);
tempEdges.push_back(e); tempEdges.push_back(e);
} }
} }

View File

@ -871,7 +871,7 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
clearReports(g); clearReports(g);
for (auto v : pred) { for (auto v : pred) {
NFAEdge e = add_edge(v, g.accept, g).first; NFAEdge e = add_edge(v, g.accept, g);
g[v].reports.insert(0); g[v].reports.insert(0);
if (is_triggered(g) && v == g.start) { if (is_triggered(g) && v == g.start) {
g[e].tops.insert(DEFAULT_TOP); g[e].tops.insert(DEFAULT_TOP);
@ -904,7 +904,7 @@ void restoreTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
} }
for (auto v : preds) { for (auto v : preds) {
NFAEdge e = add_edge(v, prev, g).first; NFAEdge e = add_edge(v, prev, g);
if (v == g.start && is_triggered(g)) { if (v == g.start && is_triggered(g)) {
g[e].tops.insert(DEFAULT_TOP); g[e].tops.insert(DEFAULT_TOP);
} }
@ -2408,14 +2408,14 @@ void explodeLiteral(RoseInGraph &g, RoseInVertex v,
g[v_new].s = lit; g[v_new].s = lit;
for (const auto &e : in_edges_range(v, g)) { for (const auto &e : in_edges_range(v, g)) {
RoseInEdge e2 = add_edge(source(e, g), v_new, g[e], g).first; RoseInEdge e2 = add_edge(source(e, g), v_new, g[e], g);
// FIXME: are we safe to share graphs here? For now, make our very // FIXME: are we safe to share graphs here? For now, make our very
// own copy. // own copy.
g[e2].graph = makeGraphCopy(g[e].graph.get()); g[e2].graph = makeGraphCopy(g[e].graph.get());
} }
for (const auto &e : out_edges_range(v, g)) { for (const auto &e : out_edges_range(v, g)) {
RoseInEdge e2 = add_edge(v_new, target(e, g), g[e], g).first; RoseInEdge e2 = add_edge(v_new, target(e, g), g[e], g);
// FIXME: are we safe to share graphs here? For now, make our very // FIXME: are we safe to share graphs here? For now, make our very
// own copy. // own copy.
g[e2].graph = makeGraphCopy(g[e].graph.get()); g[e2].graph = makeGraphCopy(g[e].graph.get());

View File

@ -151,7 +151,7 @@ void splitRHS(const NGHolder &base, const vector<NFAVertex> &pivots,
for (auto pivot : pivots) { for (auto pivot : pivots) {
assert(contains(*rhs_map, pivot)); assert(contains(*rhs_map, pivot));
NFAEdge e = add_edge(rhs->start, (*rhs_map)[pivot], *rhs).first; NFAEdge e = add_edge(rhs->start, (*rhs_map)[pivot], *rhs);
(*rhs)[e].tops.insert(DEFAULT_TOP); (*rhs)[e].tops.insert(DEFAULT_TOP);
} }

View File

@ -197,12 +197,9 @@ u32 commonPrefixLength(const NGHolder &ga, const ranking_info &a_ranking,
a_count++; a_count++;
NFAEdge b_edge; NFAEdge b_edge = edge(b_ranking.at(i), b_ranking.at(sid), gb);
bool has_b_edge;
tie(b_edge, has_b_edge) = edge(b_ranking.at(i),
b_ranking.at(sid), gb);
if (!has_b_edge) { if (!b_edge) {
max = i; max = i;
DEBUG_PRINTF("lowering max to %u due to edge %zu->%u\n", DEBUG_PRINTF("lowering max to %u due to edge %zu->%u\n",
max, i, sid); max, i, sid);
@ -322,7 +319,7 @@ void mergeNfaComponent(NGHolder &dest, const NGHolder &vic, size_t common_len) {
DEBUG_PRINTF("skipping common edge\n"); DEBUG_PRINTF("skipping common edge\n");
assert(edge(u, v, dest).second); assert(edge(u, v, dest).second);
// Should never merge edges with different top values. // Should never merge edges with different top values.
assert(vic[e].tops == dest[edge(u, v, dest).first].tops); assert(vic[e].tops == dest[edge(u, v, dest)].tops);
continue; continue;
} else { } else {
assert(is_any_accept(v, dest)); assert(is_any_accept(v, dest));
@ -508,25 +505,22 @@ bool mergeableStarts(const NGHolder &h1, const NGHolder &h2) {
/* TODO: relax top checks if reports match */ /* TODO: relax top checks if reports match */
// If both graphs have edge (start, accept), the tops must match. // If both graphs have edge (start, accept), the tops must match.
auto e1_accept = edge(h1.start, h1.accept, h1); NFAEdge e1_accept = edge(h1.start, h1.accept, h1);
auto e2_accept = edge(h2.start, h2.accept, h2); NFAEdge e2_accept = edge(h2.start, h2.accept, h2);
if (e1_accept.second && e2_accept.second && if (e1_accept && e2_accept && h1[e1_accept].tops != h2[e2_accept].tops) {
h1[e1_accept.first].tops != h2[e2_accept.first].tops) {
return false; return false;
} }
// If both graphs have edge (start, acceptEod), the tops must match. // If both graphs have edge (start, acceptEod), the tops must match.
auto e1_eod = edge(h1.start, h1.acceptEod, h1); NFAEdge e1_eod = edge(h1.start, h1.acceptEod, h1);
auto e2_eod = edge(h2.start, h2.acceptEod, h2); NFAEdge e2_eod = edge(h2.start, h2.acceptEod, h2);
if (e1_eod.second && e2_eod.second && if (e1_eod && e2_eod && h1[e1_eod].tops != h2[e2_eod].tops) {
h1[e1_eod.first].tops != h2[e2_eod.first].tops) {
return false; return false;
} }
// If one graph has an edge to accept and the other has an edge to // If one graph has an edge to accept and the other has an edge to
// acceptEod, the reports must match for the merge to be safe. // acceptEod, the reports must match for the merge to be safe.
if ((e1_accept.second && e2_eod.second) || if ((e1_accept && e2_eod) || (e2_accept && e1_eod)) {
(e2_accept.second && e1_eod.second)) {
if (h1[h1.start].reports != h2[h2.start].reports) { if (h1[h1.start].reports != h2[h2.start].reports) {
return false; return false;
} }

View File

@ -146,7 +146,7 @@ void clone_out_edges(NGHolder &g, NFAVertex source, NFAVertex dest) {
if (edge(dest, t, g).second) { if (edge(dest, t, g).second) {
continue; continue;
} }
NFAEdge clone = add_edge(dest, t, g).first; NFAEdge clone = add_edge(dest, t, g);
u32 idx = g[clone].index; u32 idx = g[clone].index;
g[clone] = g[e]; g[clone] = g[e];
g[clone].index = idx; g[clone].index = idx;
@ -157,7 +157,7 @@ void clone_in_edges(NGHolder &g, NFAVertex s, NFAVertex dest) {
for (const auto &e : in_edges_range(s, g)) { for (const auto &e : in_edges_range(s, g)) {
NFAVertex ss = source(e, g); NFAVertex ss = source(e, g);
assert(!edge(ss, dest, g).second); assert(!edge(ss, dest, g).second);
NFAEdge clone = add_edge(ss, dest, g).first; NFAEdge clone = add_edge(ss, dest, g);
u32 idx = g[clone].index; u32 idx = g[clone].index;
g[clone] = g[e]; g[clone] = g[e];
g[clone].index = idx; g[clone].index = idx;
@ -324,11 +324,9 @@ bool can_only_match_at_eod(const NGHolder &g) {
} }
bool matches_everywhere(const NGHolder &h) { bool matches_everywhere(const NGHolder &h) {
NFAEdge e; NFAEdge e = edge(h.startDs, h.accept, h);
bool exists;
tie(e, exists) = edge(h.startDs, h.accept, h);
return exists && !h[e].assert_flags; return e && !h[e].assert_flags;
} }
bool is_virtual_start(NFAVertex v, const NGHolder &g) { bool is_virtual_start(NFAVertex v, const NGHolder &g) {
@ -623,10 +621,7 @@ void cloneHolder(NGHolder &out, const NGHolder &in) {
NFAVertex s = out_mapping[si]; NFAVertex s = out_mapping[si];
NFAVertex t = out_mapping[ti]; NFAVertex t = out_mapping[ti];
UNUSED bool added; NFAEdge e2 = add_edge(s, t, out);
NFAEdge e2;
tie(e2, added) = add_edge(s, t, out);
assert(added);
out[e2] = in[e]; out[e2] = in[e];
} }

View File

@ -1153,7 +1153,7 @@ void splitEdgesByCut(NGHolder &h, RoseInGraph &vg,
* makes a more svelte graphy */ * makes a more svelte graphy */
clear_in_edges(temp_map[pivot], *new_lhs); clear_in_edges(temp_map[pivot], *new_lhs);
NFAEdge pivot_edge = add_edge(temp_map[prev_v], temp_map[pivot], NFAEdge pivot_edge = add_edge(temp_map[prev_v], temp_map[pivot],
*new_lhs).first; *new_lhs);
if (is_triggered(h) && prev_v == h.start) { if (is_triggered(h) && prev_v == h.start) {
(*new_lhs)[pivot_edge].tops.insert(DEFAULT_TOP); (*new_lhs)[pivot_edge].tops.insert(DEFAULT_TOP);
} }
@ -2125,7 +2125,7 @@ void splitEdgesForSuffix(const NGHolder &base_graph, RoseInGraph &vg,
add_edge(lhs->accept, lhs->acceptEod, *lhs); add_edge(lhs->accept, lhs->acceptEod, *lhs);
clearReports(*lhs); clearReports(*lhs);
for (NFAVertex v : splitters) { for (NFAVertex v : splitters) {
NFAEdge e = add_edge(v_map[v], lhs->accept, *lhs).first; NFAEdge e = add_edge(v_map[v], lhs->accept, *lhs);
if (v == base_graph.start) { if (v == base_graph.start) {
(*lhs)[e].tops.insert(DEFAULT_TOP); (*lhs)[e].tops.insert(DEFAULT_TOP);
} }

View File

@ -136,10 +136,7 @@ RoseVertex createVertex(RoseBuildImpl *build, const RoseVertex parent,
/* fill in report information */ /* fill in report information */
g[v].reports.insert(reports.begin(), reports.end()); g[v].reports.insert(reports.begin(), reports.end());
RoseEdge e; RoseEdge e = add_edge(parent, v, g);
bool added;
tie(e, added) = add_edge(parent, v, g);
assert(added);
DEBUG_PRINTF("adding edge (%u, %u) to parent\n", minBound, maxBound); DEBUG_PRINTF("adding edge (%u, %u) to parent\n", minBound, maxBound);
g[e].minBound = minBound; g[e].minBound = minBound;
@ -169,7 +166,7 @@ RoseVertex createAnchoredVertex(RoseBuildImpl *build, u32 literalId,
DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].index, DEBUG_PRINTF("created anchored vertex %zu with lit id %u\n", g[v].index,
literalId); literalId);
RoseEdge e = add_edge(build->anchored_root, v, g).first; RoseEdge e = add_edge(build->anchored_root, v, g);
g[e].minBound = min_offset; g[e].minBound = min_offset;
g[e].maxBound = max_offset; g[e].maxBound = max_offset;
@ -315,10 +312,7 @@ void createVertices(RoseBuildImpl *tbi,
RoseVertex p = pv.first; RoseVertex p = pv.first;
RoseEdge e; RoseEdge e = add_edge(p, w, g);
bool added;
tie(e, added) = add_edge(p, w, g);
assert(added);
DEBUG_PRINTF("adding edge (%u,%u) to parent\n", edge_props.minBound, DEBUG_PRINTF("adding edge (%u,%u) to parent\n", edge_props.minBound,
edge_props.maxBound); edge_props.maxBound);
g[e].minBound = edge_props.minBound; g[e].minBound = edge_props.minBound;
@ -356,7 +350,7 @@ void createVertices(RoseBuildImpl *tbi,
for (const auto &pv : parents) { for (const auto &pv : parents) {
const RoseInEdgeProps &edge_props = bd.ig[pv.second]; const RoseInEdgeProps &edge_props = bd.ig[pv.second];
RoseEdge e = add_edge(pv.first, g_v, tbi->g).first; RoseEdge e = add_edge(pv.first, g_v, tbi->g);
g[e].minBound = edge_props.minBound; g[e].minBound = edge_props.minBound;
g[e].maxBound = edge_props.maxBound; g[e].maxBound = edge_props.maxBound;
g[e].history = selectHistory(*tbi, bd, pv.second, e); g[e].history = selectHistory(*tbi, bd, pv.second, e);
@ -709,7 +703,7 @@ void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u,
g[v].left.graph = eod_leftfix; g[v].left.graph = eod_leftfix;
g[v].left.leftfix_report = report_mapping.second; g[v].left.leftfix_report = report_mapping.second;
g[v].left.lag = 0; g[v].left.lag = 0;
RoseEdge e1 = add_edge(u, v, g).first; RoseEdge e1 = add_edge(u, v, g);
g[e1].minBound = 0; g[e1].minBound = 0;
g[e1].maxBound = ROSE_BOUND_INF; g[e1].maxBound = ROSE_BOUND_INF;
g[v].min_offset = add_rose_depth(g[u].min_offset, g[v].min_offset = add_rose_depth(g[u].min_offset,
@ -729,7 +723,7 @@ void makeEodEventLeftfix(RoseBuildImpl &build, RoseVertex u,
g[w].reports = report_mapping.first; g[w].reports = report_mapping.first;
g[w].min_offset = g[v].min_offset; g[w].min_offset = g[v].min_offset;
g[w].max_offset = g[v].max_offset; g[w].max_offset = g[v].max_offset;
RoseEdge e = add_edge(v, w, g).first; RoseEdge e = add_edge(v, w, g);
g[e].minBound = 0; g[e].minBound = 0;
g[e].maxBound = 0; g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE; g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
@ -803,7 +797,7 @@ void doRoseAcceptVertex(RoseBuildImpl *tbi,
g[w].reports = ig[iv].reports; g[w].reports = ig[iv].reports;
g[w].min_offset = g[u].min_offset; g[w].min_offset = g[u].min_offset;
g[w].max_offset = g[u].max_offset; g[w].max_offset = g[u].max_offset;
RoseEdge e = add_edge(u, w, g).first; RoseEdge e = add_edge(u, w, g);
g[e].minBound = 0; g[e].minBound = 0;
g[e].maxBound = 0; g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE; g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;

View File

@ -532,7 +532,7 @@ void addTransientMask(RoseBuildImpl &build, const vector<CharReach> &mask,
g[v].left.leftfix_report = mask_report; g[v].left.leftfix_report = mask_report;
} else { } else {
// Make sure our edge bounds are correct. // Make sure our edge bounds are correct.
auto e = edge(parent, v, g).first; RoseEdge e = edge(parent, v, g);
g[e].minBound = 0; g[e].minBound = 0;
g[e].maxBound = anchored ? 0 : ROSE_BOUND_INF; g[e].maxBound = anchored ? 0 : ROSE_BOUND_INF;
g[e].history = anchored ? ROSE_ROLE_HISTORY_ANCH g[e].history = anchored ? ROSE_ROLE_HISTORY_ANCH
@ -544,7 +544,7 @@ void addTransientMask(RoseBuildImpl &build, const vector<CharReach> &mask,
g[v].max_offset = v_max_offset; g[v].max_offset = v_max_offset;
if (eod) { if (eod) {
auto e = add_edge(v, eod_v, g).first; RoseEdge e = add_edge(v, eod_v, g);
g[e].minBound = 0; g[e].minBound = 0;
g[e].maxBound = 0; g[e].maxBound = 0;
g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE; g[e].history = ROSE_ROLE_HISTORY_LAST_BYTE;
@ -574,7 +574,7 @@ unique_ptr<NGHolder> buildMaskRhs(const ue2::flat_set<ReportID> &reports,
succ = u; succ = u;
} }
NFAEdge e = add_edge(h.start, succ, h).first; NFAEdge e = add_edge(h.start, succ, h);
h[e].tops.insert(DEFAULT_TOP); h[e].tops.insert(DEFAULT_TOP);
return rhs; return rhs;

View File

@ -1312,7 +1312,7 @@ void addSmallBlockLiteral(RoseBuildImpl &tbi, const simple_anchored_info &sai,
g[v].max_offset = sai.max_bound + sai.literal.length(); g[v].max_offset = sai.max_bound + sai.literal.length();
lit_info.vertices.insert(v); lit_info.vertices.insert(v);
RoseEdge e = add_edge(anchored_root, v, g).first; RoseEdge e = add_edge(anchored_root, v, g);
g[e].minBound = sai.min_bound; g[e].minBound = sai.min_bound;
g[e].maxBound = sai.max_bound; g[e].maxBound = sai.max_bound;
} }
@ -1336,7 +1336,7 @@ void addSmallBlockLiteral(RoseBuildImpl &tbi, const ue2_literal &lit,
g[v].literals.insert(lit_id); g[v].literals.insert(lit_id);
g[v].reports = reports; g[v].reports = reports;
RoseEdge e = add_edge(tbi.root, v, g).first; RoseEdge e = add_edge(tbi.root, v, g);
g[e].minBound = 0; g[e].minBound = 0;
g[e].maxBound = ROSE_BOUND_INF; g[e].maxBound = ROSE_BOUND_INF;
g[v].min_offset = 1; g[v].min_offset = 1;

View File

@ -394,7 +394,7 @@ unique_ptr<NGHolder> makeFloodProneSuffix(const ue2_literal &s, size_t len,
NFAVertex u = h->start; NFAVertex u = h->start;
for (auto it = s.begin() + s.length() - len; it != s.end(); ++it) { for (auto it = s.begin() + s.length() - len; it != s.end(); ++it) {
NFAVertex v = addHolderVertex(*it, *h); NFAVertex v = addHolderVertex(*it, *h);
NFAEdge e = add_edge(u, v, *h).first; NFAEdge e = add_edge(u, v, *h);
if (u == h->start) { if (u == h->start) {
(*h)[e].tops.insert(DEFAULT_TOP); (*h)[e].tops.insert(DEFAULT_TOP);
} }
@ -705,10 +705,7 @@ bool handleStartPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
assert(g[e_old].maxBound >= bound_max); assert(g[e_old].maxBound >= bound_max);
setEdgeBounds(g, e_old, bound_min, bound_max); setEdgeBounds(g, e_old, bound_min, bound_max);
} else { } else {
RoseEdge e_new; RoseEdge e_new = add_edge(ar, v, g);
UNUSED bool added;
tie(e_new, added) = add_edge(ar, v, g);
assert(added);
setEdgeBounds(g, e_new, bound_min, bound_max); setEdgeBounds(g, e_new, bound_min, bound_max);
to_delete->push_back(e_old); to_delete->push_back(e_old);
} }
@ -900,10 +897,7 @@ bool handleMixedPrefixCliche(const NGHolder &h, RoseGraph &g, RoseVertex v,
if (source(e_old, g) == ar) { if (source(e_old, g) == ar) {
setEdgeBounds(g, e_old, ri.repeatMin + width, ri.repeatMax + width); setEdgeBounds(g, e_old, ri.repeatMin + width, ri.repeatMax + width);
} else { } else {
RoseEdge e_new; RoseEdge e_new = add_edge(ar, v, g);
UNUSED bool added;
tie(e_new, added) = add_edge(ar, v, g);
assert(added);
setEdgeBounds(g, e_new, ri.repeatMin + width, ri.repeatMax + width); setEdgeBounds(g, e_new, ri.repeatMin + width, ri.repeatMax + width);
to_delete->push_back(e_old); to_delete->push_back(e_old);
} }

View File

@ -454,11 +454,9 @@ bool isNoRunsVertex(const RoseBuildImpl &build, RoseVertex u) {
return false; return false;
} }
RoseEdge e; RoseEdge e = edge(build.root, u, g);
bool exists;
tie(e, exists) = edge(build.root, u, g);
if (!exists) { if (!e) {
DEBUG_PRINTF("u=%zu is not a root role\n", g[u].index); DEBUG_PRINTF("u=%zu is not a root role\n", g[u].index);
return false; return false;
} }

View File

@ -235,18 +235,15 @@ void mergeDupeLeaves(RoseBuildImpl &tbi) {
for (const auto &e : in_edges_range(v, g)) { for (const auto &e : in_edges_range(v, g)) {
RoseVertex u = source(e, g); RoseVertex u = source(e, g);
DEBUG_PRINTF("u index=%zu\n", g[u].index); DEBUG_PRINTF("u index=%zu\n", g[u].index);
RoseEdge et; if (RoseEdge et = edge(u, t, g)) {
bool exists;
tie (et, exists) = edge(u, t, g);
if (exists) {
if (g[et].minBound <= g[e].minBound if (g[et].minBound <= g[e].minBound
&& g[et].maxBound >= g[e].maxBound) { && g[et].maxBound >= g[e].maxBound) {
DEBUG_PRINTF("remove more constrained edge\n"); DEBUG_PRINTF("remove more constrained edge\n");
deadEdges.push_back(e); deadEdges.push_back(e);
} }
} else { } else {
DEBUG_PRINTF("rehome edge: add %zu->%zu\n", DEBUG_PRINTF("rehome edge: add %zu->%zu\n", g[u].index,
g[u].index, g[t].index); g[t].index);
add_edge(u, t, g[e], g); add_edge(u, t, g[e], g);
deadEdges.push_back(e); deadEdges.push_back(e);
} }

View File

@ -254,10 +254,8 @@ bool samePredecessors(RoseVertex a, RoseVertex b, const RoseGraph &g) {
} }
for (const auto &e_a : in_edges_range(a, g)) { for (const auto &e_a : in_edges_range(a, g)) {
bool exists; RoseEdge e = edge(source(e_a, g), b, g);
RoseEdge e; if (!e || g[e].rose_top != g[e_a].rose_top) {
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"); DEBUG_PRINTF("bad tops\n");
return false; return false;
} }
@ -271,10 +269,7 @@ static
bool hasCommonSuccWithBadBounds(RoseVertex a, RoseVertex b, bool hasCommonSuccWithBadBounds(RoseVertex a, RoseVertex b,
const RoseGraph &g) { const RoseGraph &g) {
for (const auto &e_a : out_edges_range(a, g)) { for (const auto &e_a : out_edges_range(a, g)) {
bool exists; if (RoseEdge e = edge(b, target(e_a, g), g)) {
RoseEdge e;
tie(e, exists) = edge(b, target(e_a, g), g);
if (exists) {
if (g[e_a].maxBound < g[e].minBound if (g[e_a].maxBound < g[e].minBound
|| g[e].maxBound < g[e_a].minBound) { || g[e].maxBound < g[e_a].minBound) {
return true; return true;
@ -293,10 +288,7 @@ static
bool hasCommonPredWithBadBounds(RoseVertex a, RoseVertex b, bool hasCommonPredWithBadBounds(RoseVertex a, RoseVertex b,
const RoseGraph &g) { const RoseGraph &g) {
for (const auto &e_a : in_edges_range(a, g)) { for (const auto &e_a : in_edges_range(a, g)) {
bool exists; if (RoseEdge e = edge(source(e_a, g), b, g)) {
RoseEdge e;
tie(e, exists) = edge(source(e_a, g), b, g);
if (exists) {
if (g[e_a].maxBound < g[e].minBound if (g[e_a].maxBound < g[e].minBound
|| g[e].maxBound < g[e_a].minBound) { || g[e].maxBound < g[e_a].minBound) {
return true; return true;
@ -744,10 +736,7 @@ bool hasCommonPredWithDiffRoses(RoseVertex a, RoseVertex b,
const bool equal_roses = hasEqualLeftfixes(a, b, g); const bool equal_roses = hasEqualLeftfixes(a, b, g);
for (const auto &e_a : in_edges_range(a, g)) { for (const auto &e_a : in_edges_range(a, g)) {
bool exists; if (RoseEdge e = edge(source(e_a, g), b, g)) {
RoseEdge e;
tie(e, exists) = edge(source(e_a, g), b, g);
if (exists) {
DEBUG_PRINTF("common pred, e_r=%d r_t %u,%u\n", DEBUG_PRINTF("common pred, e_r=%d r_t %u,%u\n",
(int)equal_roses, g[e].rose_top, g[e_a].rose_top); (int)equal_roses, g[e].rose_top, g[e_a].rose_top);
if (!equal_roses) { if (!equal_roses) {
@ -1122,8 +1111,7 @@ bool attemptRoseCastleMerge(RoseBuildImpl &build, bool preds_same, RoseVertex a,
// We should be protected from merging common preds with tops leading // We should be protected from merging common preds with tops leading
// to completely different repeats by earlier checks, but just in // to completely different repeats by earlier checks, but just in
// case... // case...
if (edge(source(e, g), a, g).second) { if (RoseEdge a_edge = edge(source(e, g), a, g)) {
RoseEdge a_edge = edge(source(e, g), a, g).first;
u32 a_top = g[a_edge].rose_top; u32 a_top = g[a_edge].rose_top;
const PureRepeat &a_pr = m_castle->repeats[a_top]; // new report const PureRepeat &a_pr = m_castle->repeats[a_top]; // new report
if (pr != a_pr) { if (pr != a_pr) {

View File

@ -328,6 +328,15 @@ public:
edge_descriptor() : p(nullptr), serial(0) { } edge_descriptor() : p(nullptr), serial(0) { }
explicit edge_descriptor(edge_node *pp) : p(pp), serial(pp->serial) { } explicit edge_descriptor(edge_node *pp) : p(pp), serial(pp->serial) { }
/* Convenice ctor to allow us to directly get an edge_descriptor from
* edge() and add_edge(). As we have null_edges and we always allow
* parallel edges, the bool component of the return from these functions
* is not required. */
edge_descriptor(const std::pair<edge_descriptor, bool> &tup)
: p(tup.first.p), serial(tup.first.serial) {
assert(tup.second == (bool)tup.first);
}
operator bool() const { return p; } operator bool() const { return p; }
bool operator<(const edge_descriptor b) const { bool operator<(const edge_descriptor b) const {
if (p && b.p) { if (p && b.p) {