mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
rose: replace RoseLiteralMap use of bimap
This apoproach is simpler and more efficient for cases with large numbers of literals.
This commit is contained in:
parent
a75b2ba2e5
commit
8b9328fe9e
@ -295,7 +295,7 @@ void createVertices(RoseBuildImpl *tbi,
|
||||
if (bd.som && !g[w].left.haig) {
|
||||
/* no prefix - som based on literal start */
|
||||
assert(!prefix_graph);
|
||||
g[w].som_adjust = tbi->literals.right.at(literalId).elength();
|
||||
g[w].som_adjust = tbi->literals.at(literalId).elength();
|
||||
DEBUG_PRINTF("set som_adjust to %u\n", g[w].som_adjust);
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ void createVertices(RoseBuildImpl *tbi,
|
||||
u32 ghostId = tbi->literal_info[literalId].undelayed_id;
|
||||
DEBUG_PRINTF("creating delay ghost vertex, id=%u\n", ghostId);
|
||||
assert(ghostId != literalId);
|
||||
assert(tbi->literals.right.at(ghostId).delay == 0);
|
||||
assert(tbi->literals.at(ghostId).delay == 0);
|
||||
|
||||
// Adjust offsets, removing delay.
|
||||
u32 ghost_min = min_offset, ghost_max = max_offset;
|
||||
@ -1907,16 +1907,20 @@ void removeAddedLiterals(RoseBuildImpl &tbi, const flat_set<u32> &lit_ids) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("remove last %zu literals\n", lit_ids.size());
|
||||
|
||||
// lit_ids should be a contiguous range.
|
||||
assert(lit_ids.size() == *lit_ids.rbegin() - *lit_ids.begin() + 1);
|
||||
assert(*lit_ids.rbegin() == tbi.literals.size() - 1);
|
||||
|
||||
for (const u32 &lit_id : lit_ids) {
|
||||
assert(lit_id < tbi.literal_info.size());
|
||||
assert(tbi.literals.right.at(lit_id).table == ROSE_ANCHORED);
|
||||
assert(tbi.literal_info[lit_id].vertices.empty());
|
||||
assert(all_of_in(lit_ids, [&](u32 lit_id) {
|
||||
return lit_id < tbi.literal_info.size() &&
|
||||
tbi.literals.at(lit_id).table == ROSE_ANCHORED &&
|
||||
tbi.literal_info[lit_id].vertices.empty();
|
||||
}));
|
||||
|
||||
tbi.literals.right.erase(lit_id);
|
||||
}
|
||||
tbi.literals.erase_back(lit_ids.size());
|
||||
assert(tbi.literals.size() == *lit_ids.begin());
|
||||
|
||||
// lit_ids should be at the end of tbi.literal_info.
|
||||
assert(tbi.literal_info.size() == *lit_ids.rbegin() + 1);
|
||||
|
@ -746,8 +746,8 @@ void findTriggerSequences(const RoseBuildImpl &tbi,
|
||||
const u32 top = e.first;
|
||||
const set<u32> &lit_ids = e.second;
|
||||
|
||||
for (u32 id : lit_ids) {
|
||||
const rose_literal_id &lit = tbi.literals.right.at(id);
|
||||
for (u32 id : lit_ids) {
|
||||
const rose_literal_id &lit = tbi.literals.at(id);
|
||||
(*trigger_lits)[top].push_back(as_cr_seq(lit));
|
||||
}
|
||||
}
|
||||
@ -905,8 +905,8 @@ u32 decreaseLag(const RoseBuildImpl &build, NGHolder &h,
|
||||
for (RoseVertex v : succs) {
|
||||
u32 lag = rg[v].left.lag;
|
||||
for (u32 lit_id : rg[v].literals) {
|
||||
u32 delay = build.literals.right.at(lit_id).delay;
|
||||
const ue2_literal &literal = build.literals.right.at(lit_id).s;
|
||||
u32 delay = build.literals.at(lit_id).delay;
|
||||
const ue2_literal &literal = build.literals.at(lit_id).s;
|
||||
assert(lag <= literal.length() + delay);
|
||||
size_t base = literal.length() + delay - lag;
|
||||
if (base >= literal.length()) {
|
||||
@ -1134,7 +1134,7 @@ bool buildLeftfix(RoseBuildImpl &build, build_context &bc, bool prefix, u32 qi,
|
||||
for (RoseVertex v : succs) {
|
||||
for (auto u : inv_adjacent_vertices_range(v, g)) {
|
||||
for (u32 lit_id : g[u].literals) {
|
||||
lits.insert(build.literals.right.at(lit_id).s);
|
||||
lits.insert(build.literals.at(lit_id).s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1315,7 +1315,7 @@ void updateExclusiveInfixProperties(const RoseBuildImpl &build,
|
||||
set<ue2_literal> lits;
|
||||
for (auto u : inv_adjacent_vertices_range(v, build.g)) {
|
||||
for (u32 lit_id : build.g[u].literals) {
|
||||
lits.insert(build.literals.right.at(lit_id).s);
|
||||
lits.insert(build.literals.at(lit_id).s);
|
||||
}
|
||||
}
|
||||
DEBUG_PRINTF("%zu literals\n", lits.size());
|
||||
@ -2117,9 +2117,8 @@ u32 RoseBuildImpl::calcHistoryRequired() const {
|
||||
}
|
||||
|
||||
// Delayed literals contribute to history requirement as well.
|
||||
for (const auto &e : literals.right) {
|
||||
const u32 id = e.first;
|
||||
const auto &lit = e.second;
|
||||
for (u32 id = 0; id < literals.size(); id++) {
|
||||
const auto &lit = literals.at(id);
|
||||
if (lit.delay) {
|
||||
// If the literal is delayed _and_ has a mask that is longer than
|
||||
// the literal, we need enough history to match the whole mask as
|
||||
@ -2716,11 +2715,11 @@ void buildLeftInfoTable(const RoseBuildImpl &tbi, build_context &bc,
|
||||
} else {
|
||||
left.lagIndex = ROSE_OFFSET_INVALID;
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("rose %u is %s\n", left_index,
|
||||
left.infix ? "infix" : "prefix");
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("rose %u is %s\n", left_index,
|
||||
left.infix ? "infix" : "prefix");
|
||||
|
||||
// Update squash mask.
|
||||
left.squash_mask &= lbi.squash_mask;
|
||||
|
||||
@ -2853,9 +2852,8 @@ vector<LitFragment> groupByFragment(const RoseBuildImpl &build) {
|
||||
|
||||
map<rose_literal_id, FragmentInfo> frag_info;
|
||||
|
||||
for (const auto &m : build.literals.right) {
|
||||
const u32 lit_id = m.first;
|
||||
const auto &lit = m.second;
|
||||
for (u32 lit_id = 0; lit_id < build.literals.size(); lit_id++) {
|
||||
const auto &lit = build.literals.at(lit_id);
|
||||
const auto &info = build.literal_info.at(lit_id);
|
||||
|
||||
if (!isUsedLiteral(build, lit_id)) {
|
||||
@ -2993,7 +2991,7 @@ pair<u32, u32> writeAnchoredPrograms(const RoseBuildImpl &build,
|
||||
|
||||
for (const auto &frag : fragments) {
|
||||
for (const u32 lit_id : frag.lit_ids) {
|
||||
const auto &lit = build.literals.right.at(lit_id);
|
||||
const auto &lit = build.literals.at(lit_id);
|
||||
|
||||
if (lit.table != ROSE_ANCHORED) {
|
||||
continue;
|
||||
@ -3238,7 +3236,7 @@ void fillMatcherDistances(const RoseBuildImpl &build, RoseEngine *engine) {
|
||||
assert(g[v].min_offset <= g[v].max_offset);
|
||||
|
||||
for (u32 lit_id : g[v].literals) {
|
||||
const rose_literal_id &key = build.literals.right.at(lit_id);
|
||||
const rose_literal_id &key = build.literals.at(lit_id);
|
||||
u32 max_d = g[v].max_offset;
|
||||
u32 min_d = g[v].min_offset;
|
||||
|
||||
@ -3371,9 +3369,8 @@ pair<size_t, size_t> floatingCountAndMaxLen(const RoseBuildImpl &build) {
|
||||
size_t num = 0;
|
||||
size_t max_len = 0;
|
||||
|
||||
for (const auto &e : build.literals.right) {
|
||||
const u32 id = e.first;
|
||||
const rose_literal_id &lit = e.second;
|
||||
for (u32 id = 0; id < build.literals.size(); id++) {
|
||||
const rose_literal_id &lit = build.literals.at(id);
|
||||
|
||||
if (lit.table != ROSE_FLOATING) {
|
||||
continue;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016, Intel Corporation
|
||||
* Copyright (c) 2015-2017, Intel Corporation
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@ -131,7 +131,7 @@ vector<rose_literal_id> literals_for_vertex(const RoseBuildImpl &tbi,
|
||||
vector<rose_literal_id> rv;
|
||||
|
||||
for (const u32 id : tbi.g[v].literals) {
|
||||
rv.push_back(tbi.literals.right.at(id));
|
||||
rv.push_back(tbi.literals.at(id));
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -366,7 +366,7 @@ bool triggerKillsRoseCastle(const RoseBuildImpl &tbi, const left_id &left,
|
||||
/* check each pred literal to see if they all kill previous castle
|
||||
* state */
|
||||
for (u32 lit_id : tbi.g[source(e, tbi.g)].literals) {
|
||||
const rose_literal_id &pred_lit = tbi.literals.right.at(lit_id);
|
||||
const rose_literal_id &pred_lit = tbi.literals.at(lit_id);
|
||||
const ue2_literal s = findNonOverlappingTail(all_lits, pred_lit.s);
|
||||
const CharReach &cr = c.reach();
|
||||
|
||||
|
@ -119,7 +119,7 @@ void removeLiteralFromGraph(RoseBuildImpl &build, u32 id) {
|
||||
*/
|
||||
static
|
||||
void explodeLiteral(RoseBuildImpl &build, u32 id) {
|
||||
const auto &lit = build.literals.right.at(id);
|
||||
const auto &lit = build.literals.at(id);
|
||||
auto &info = build.literal_info[id];
|
||||
|
||||
assert(!info.group_mask); // not set yet
|
||||
@ -139,7 +139,7 @@ void explodeLiteral(RoseBuildImpl &build, u32 id) {
|
||||
DEBUG_PRINTF("adding exploded lit %u: '%s'\n", new_id,
|
||||
dumpString(new_str).c_str());
|
||||
|
||||
const auto &new_lit = build.literals.right.at(new_id);
|
||||
const auto &new_lit = build.literals.at(new_id);
|
||||
auto &new_info = build.literal_info.at(new_id);
|
||||
insert(&new_info.vertices, info.vertices);
|
||||
for (const auto &v : info.vertices) {
|
||||
@ -150,7 +150,7 @@ void explodeLiteral(RoseBuildImpl &build, u32 id) {
|
||||
if (!info.delayed_ids.empty()) {
|
||||
flat_set<u32> &del_ids = new_info.delayed_ids;
|
||||
for (u32 delay_id : info.delayed_ids) {
|
||||
const auto &dlit = build.literals.right.at(delay_id);
|
||||
const auto &dlit = build.literals.at(delay_id);
|
||||
u32 new_delay_id =
|
||||
build.getLiteralId(new_lit.s, new_lit.msk, new_lit.cmp,
|
||||
dlit.delay, dlit.table);
|
||||
@ -170,9 +170,8 @@ void explodeLiteral(RoseBuildImpl &build, u32 id) {
|
||||
|
||||
void RoseBuildImpl::handleMixedSensitivity(void) {
|
||||
vector<u32> explode;
|
||||
for (const auto &e : literals.right) {
|
||||
u32 id = e.first;
|
||||
const rose_literal_id &lit = e.second;
|
||||
for (u32 id = 0; id < literals.size(); id++) {
|
||||
const rose_literal_id &lit = literals.at(id);
|
||||
|
||||
if (lit.delay) {
|
||||
continue; /* delay id's are virtual-ish */
|
||||
@ -420,7 +419,7 @@ bool RoseBuildImpl::isDirectReport(u32 id) const {
|
||||
}
|
||||
}
|
||||
|
||||
if (literals.right.at(id).table == ROSE_ANCHORED) {
|
||||
if (literals.at(id).table == ROSE_ANCHORED) {
|
||||
/* in-edges are irrelevant for anchored region. */
|
||||
continue;
|
||||
}
|
||||
@ -439,7 +438,7 @@ bool RoseBuildImpl::isDirectReport(u32 id) const {
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("literal %u ('%s') is a %s report\n", id,
|
||||
dumpString(literals.right.at(id).s).c_str(),
|
||||
dumpString(literals.at(id).s).c_str(),
|
||||
info.vertices.size() > 1 ? "multi-direct" : "direct");
|
||||
return true;
|
||||
}
|
||||
@ -511,8 +510,7 @@ bool checkEodStealFloating(const RoseBuildImpl &build,
|
||||
|
||||
// Collect a set of all floating literals.
|
||||
unordered_set<ue2_literal> floating_lits;
|
||||
for (auto &m : build.literals) {
|
||||
const auto &lit = m.left;
|
||||
for (auto &lit : build.literals) {
|
||||
if (lit.table == ROSE_FLOATING) {
|
||||
floating_lits.insert(lit.s);
|
||||
}
|
||||
@ -524,7 +522,7 @@ bool checkEodStealFloating(const RoseBuildImpl &build,
|
||||
u32 new_floating_lits = 0;
|
||||
|
||||
for (u32 eod_id : eodLiteralsForFloating) {
|
||||
const rose_literal_id &lit = build.literals.right.at(eod_id);
|
||||
const rose_literal_id &lit = build.literals.at(eod_id);
|
||||
DEBUG_PRINTF("checking '%s'\n", dumpString(lit.s).c_str());
|
||||
|
||||
if (contains(floating_lits, lit.s)) {
|
||||
@ -558,12 +556,16 @@ bool checkEodStealFloating(const RoseBuildImpl &build,
|
||||
|
||||
static
|
||||
void promoteEodToFloating(RoseBuildImpl &tbi, const vector<u32> &eodLiterals) {
|
||||
DEBUG_PRINTF("promoting eod literals to floating table\n");
|
||||
DEBUG_PRINTF("promoting %zu eod literals to floating table\n",
|
||||
eodLiterals.size());
|
||||
|
||||
for (u32 eod_id : eodLiterals) {
|
||||
const rose_literal_id &lit = tbi.literals.right.at(eod_id);
|
||||
const rose_literal_id &lit = tbi.literals.at(eod_id);
|
||||
DEBUG_PRINTF("eod_id=%u, lit=%s\n", eod_id, dumpString(lit.s).c_str());
|
||||
u32 floating_id = tbi.getLiteralId(lit.s, lit.msk, lit.cmp, lit.delay,
|
||||
ROSE_FLOATING);
|
||||
DEBUG_PRINTF("floating_id=%u, lit=%s\n", floating_id,
|
||||
dumpString(tbi.literals.at(floating_id).s).c_str());
|
||||
auto &float_verts = tbi.literal_info[floating_id].vertices;
|
||||
auto &eod_verts = tbi.literal_info[eod_id].vertices;
|
||||
|
||||
@ -588,7 +590,7 @@ bool promoteEodToAnchored(RoseBuildImpl &tbi, const vector<u32> &eodLiterals) {
|
||||
bool rv = true;
|
||||
|
||||
for (u32 eod_id : eodLiterals) {
|
||||
const rose_literal_id &lit = tbi.literals.right.at(eod_id);
|
||||
const rose_literal_id &lit = tbi.literals.at(eod_id);
|
||||
|
||||
NGHolder h;
|
||||
add_edge(h.start, h.accept, h);
|
||||
@ -728,7 +730,7 @@ void stealEodVertices(RoseBuildImpl &tbi) {
|
||||
continue; // skip unused literals
|
||||
}
|
||||
|
||||
const rose_literal_id &lit = tbi.literals.right.at(i);
|
||||
const rose_literal_id &lit = tbi.literals.at(i);
|
||||
|
||||
if (lit.table == ROSE_EOD_ANCHORED) {
|
||||
if (suitableForAnchored(tbi, lit, info)) {
|
||||
@ -770,7 +772,7 @@ bool RoseBuildImpl::isDelayed(u32 id) const {
|
||||
|
||||
bool RoseBuildImpl::hasDelayedLiteral(RoseVertex v) const {
|
||||
for (u32 lit_id : g[v].literals) {
|
||||
if (literals.right.at(lit_id).delay) {
|
||||
if (literals.at(lit_id).delay) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1096,7 +1098,7 @@ bool triggerKillsRoseGraph(const RoseBuildImpl &build, const left_id &left,
|
||||
/* check each pred literal to see if they all kill previous graph
|
||||
* state */
|
||||
for (u32 lit_id : build.g[source(e, build.g)].literals) {
|
||||
const rose_literal_id &pred_lit = build.literals.right.at(lit_id);
|
||||
const rose_literal_id &pred_lit = build.literals.at(lit_id);
|
||||
const ue2_literal s = findNonOverlappingTail(all_lits, pred_lit.s);
|
||||
|
||||
DEBUG_PRINTF("running graph %zu\n", states.size());
|
||||
@ -1170,7 +1172,7 @@ void findTopTriggerCancels(RoseBuildImpl &build) {
|
||||
}
|
||||
|
||||
for (u32 lit_id : pred_lit_ids) {
|
||||
const rose_literal_id &p_lit = build.literals.right.at(lit_id);
|
||||
const rose_literal_id &p_lit = build.literals.at(lit_id);
|
||||
if (p_lit.delay || p_lit.table == ROSE_ANCHORED) {
|
||||
goto next_rose;
|
||||
}
|
||||
@ -1271,7 +1273,7 @@ void countFloatingLiterals(const RoseBuildImpl &tbi, u32 *total_count,
|
||||
u32 *short_count) {
|
||||
*total_count = 0;
|
||||
*short_count = 0;
|
||||
for (const rose_literal_id &lit : tbi.literals.right | map_values) {
|
||||
for (const rose_literal_id &lit : tbi.literals) {
|
||||
if (lit.delay) {
|
||||
continue; /* delay id's are virtual-ish */
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ void convertFloodProneSuffix(RoseBuildImpl &tbi, RoseVertex v, u32 lit_id,
|
||||
static
|
||||
size_t findFloodProneSuffixLen(const RoseBuildImpl &tbi) {
|
||||
size_t numLiterals = 0;
|
||||
for (const rose_literal_id &lit : tbi.literals.right | map_values) {
|
||||
for (const rose_literal_id &lit : tbi.literals) {
|
||||
if (lit.delay) {
|
||||
continue; // delay ids are virtual-ish
|
||||
}
|
||||
@ -293,7 +293,7 @@ void convertFloodProneSuffixes(RoseBuildImpl &tbi) {
|
||||
}
|
||||
|
||||
u32 lit_id = *g[v].literals.begin();
|
||||
const rose_literal_id &lit = tbi.literals.right.at(lit_id);
|
||||
const rose_literal_id &lit = tbi.literals.at(lit_id);
|
||||
|
||||
// anchored or delayed literals need thought.
|
||||
if (lit.table != ROSE_FLOATING || lit.delay) {
|
||||
|
@ -311,9 +311,9 @@ bool RoseDedupeAuxImpl::requiresDedupeSupport(
|
||||
}
|
||||
|
||||
for (auto it = begin(lits); it != end(lits); ++it) {
|
||||
const auto &lit1 = build.literals.right.at(it->first);
|
||||
const auto &lit1 = build.literals.at(it->first);
|
||||
for (auto jt = next(it); jt != end(lits); ++jt) {
|
||||
const auto &lit2 = build.literals.right.at(jt->first);
|
||||
const auto &lit2 = build.literals.at(jt->first);
|
||||
if (literalsCouldRace(lit1, lit2)) {
|
||||
DEBUG_PRINTF("literals could race\n");
|
||||
return true;
|
||||
|
@ -257,17 +257,13 @@ private:
|
||||
os << "/nofrag ";
|
||||
}
|
||||
|
||||
if (contains(build.literals.right, id)) {
|
||||
const auto &lit = build.literals.right.at(id);
|
||||
os << '\'' << dotEscapeString(lit.s.get_string()) << '\'';
|
||||
if (lit.s.any_nocase()) {
|
||||
os << " (nocase)";
|
||||
}
|
||||
if (lit.delay) {
|
||||
os << " +" << lit.delay;
|
||||
}
|
||||
} else {
|
||||
os << "<unknown>";
|
||||
const auto &lit = build.literals.at(id);
|
||||
os << '\'' << dotEscapeString(lit.s.get_string()) << '\'';
|
||||
if (lit.s.any_nocase()) {
|
||||
os << " (nocase)";
|
||||
}
|
||||
if (lit.delay) {
|
||||
os << " +" << lit.delay;
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,15 +354,16 @@ void dumpRoseLiterals(const RoseBuildImpl &build,
|
||||
DEBUG_PRINTF("dumping literals\n");
|
||||
ofstream os(grey.dumpPath + "rose_literals.txt");
|
||||
|
||||
os << "ROSE LITERALS: a total of " << build.literals.right.size()
|
||||
<< " literals and " << num_vertices(g) << " roles." << endl << endl;
|
||||
os << "ROSE LITERALS: a total of " << build.literals.size()
|
||||
<< " literals and " << num_vertices(g) << " roles." << endl
|
||||
<< endl;
|
||||
|
||||
for (const auto &e : build.literals.right) {
|
||||
u32 id = e.first;
|
||||
const ue2_literal &s = e.second.s;
|
||||
for (u32 id = 0; id < build.literals.size(); id++) {
|
||||
const auto &lit = build.literals.at(id);
|
||||
const ue2_literal &s = lit.s;
|
||||
const rose_literal_info &lit_info = build.literal_info[id];
|
||||
|
||||
switch (e.second.table) {
|
||||
switch (lit.table) {
|
||||
case ROSE_ANCHORED:
|
||||
os << "ANCHORED";
|
||||
break;
|
||||
@ -397,8 +394,8 @@ void dumpRoseLiterals(const RoseBuildImpl &build,
|
||||
os << " benefits,";
|
||||
}
|
||||
|
||||
if (e.second.delay) {
|
||||
os << " delayed "<< e.second.delay << ",";
|
||||
if (lit.delay) {
|
||||
os << " delayed "<< lit.delay << ",";
|
||||
}
|
||||
|
||||
os << " groups 0x" << hex << setw(16) << setfill('0')
|
||||
|
@ -238,9 +238,8 @@ void assignGroupsToLiterals(RoseBuildImpl &build) {
|
||||
u32 group_always_on = 0;
|
||||
|
||||
// First pass: handle always on literals.
|
||||
for (const auto &e : literals.right) {
|
||||
u32 id = e.first;
|
||||
const rose_literal_id &lit = e.second;
|
||||
for (u32 id = 0; id < literals.size(); id++) {
|
||||
const rose_literal_id &lit = literals.at(id);
|
||||
rose_literal_info &info = literal_info[id];
|
||||
|
||||
if (!requires_group_assignment(lit, info)) {
|
||||
@ -274,9 +273,8 @@ void assignGroupsToLiterals(RoseBuildImpl &build) {
|
||||
priority_queue<tuple<s32, s32, u32>> pq;
|
||||
|
||||
// Second pass: the other literals.
|
||||
for (const auto &e : literals.right) {
|
||||
u32 id = e.first;
|
||||
const rose_literal_id &lit = e.second;
|
||||
for (u32 id = 0; id < literals.size(); id++) {
|
||||
const rose_literal_id &lit = literals.at(id);
|
||||
rose_literal_info &info = literal_info[id];
|
||||
|
||||
if (!requires_group_assignment(lit, info)) {
|
||||
@ -290,7 +288,7 @@ void assignGroupsToLiterals(RoseBuildImpl &build) {
|
||||
while (!pq.empty()) {
|
||||
u32 id = get<2>(pq.top());
|
||||
pq.pop();
|
||||
UNUSED const rose_literal_id &lit = literals.right.at(id);
|
||||
UNUSED const rose_literal_id &lit = literals.at(id);
|
||||
DEBUG_PRINTF("assigning groups to lit %u (v %zu l %zu)\n", id,
|
||||
literal_info[id].vertices.size(), lit.s.length());
|
||||
|
||||
@ -361,9 +359,8 @@ void assignGroupsToLiterals(RoseBuildImpl &build) {
|
||||
}
|
||||
}
|
||||
/* assign delayed literals to the same group as their parent */
|
||||
for (const auto &e : literals.right) {
|
||||
u32 id = e.first;
|
||||
const rose_literal_id &lit = e.second;
|
||||
for (u32 id = 0; id < literals.size(); id++) {
|
||||
const rose_literal_id &lit = literals.at(id);
|
||||
|
||||
if (!lit.delay) {
|
||||
continue;
|
||||
@ -378,7 +375,7 @@ void assignGroupsToLiterals(RoseBuildImpl &build) {
|
||||
}
|
||||
|
||||
DEBUG_PRINTF("populate group to literal mapping\n");
|
||||
for (const u32 id : literals.right | map_keys) {
|
||||
for (u32 id = 0; id < literals.size(); id++) {
|
||||
rose_group groups = literal_info[id].group_mask;
|
||||
while (groups) {
|
||||
u32 group_id = findAndClearLSB_64(&groups);
|
||||
@ -561,10 +558,10 @@ bool isGroupSquasher(const RoseBuildImpl &build, const u32 id /* literal id */,
|
||||
const rose_literal_info &lit_info = build.literal_info.at(id);
|
||||
|
||||
DEBUG_PRINTF("checking if %u '%s' is a group squasher %016llx\n", id,
|
||||
dumpString(build.literals.right.at(id).s).c_str(),
|
||||
lit_info.group_mask);
|
||||
dumpString(build.literals.at(id).s).c_str(),
|
||||
lit_info.group_mask);
|
||||
|
||||
if (build.literals.right.at(id).table == ROSE_EVENT) {
|
||||
if (build.literals.at(id).table == ROSE_EVENT) {
|
||||
DEBUG_PRINTF("event literal\n");
|
||||
return false;
|
||||
}
|
||||
@ -693,9 +690,10 @@ bool isGroupSquasher(const RoseBuildImpl &build, const u32 id /* literal id */,
|
||||
|
||||
void findGroupSquashers(RoseBuildImpl &build) {
|
||||
rose_group forbidden_squash_group = build.boundary_group_mask;
|
||||
for (const auto &e : build.literals.right) {
|
||||
if (e.second.delay) {
|
||||
forbidden_squash_group |= build.literal_info[e.first].group_mask;
|
||||
for (u32 id = 0; id < build.literals.size(); id++) {
|
||||
const auto &lit = build.literals.at(id);
|
||||
if (lit.delay) {
|
||||
forbidden_squash_group |= build.literal_info[id].group_mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,16 +39,17 @@
|
||||
#include "nfagraph/ng_holder.h"
|
||||
#include "nfagraph/ng_revacc.h"
|
||||
#include "util/bytecode_ptr.h"
|
||||
#include "util/hash.h"
|
||||
#include "util/order_check.h"
|
||||
#include "util/queue_index_factory.h"
|
||||
#include "util/ue2_containers.h"
|
||||
#include "util/ue2string.h"
|
||||
#include "util/verify_types.h"
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <boost/bimap.hpp>
|
||||
#include <boost/functional/hash/hash.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
struct RoseEngine;
|
||||
@ -300,6 +301,11 @@ struct rose_literal_id {
|
||||
}
|
||||
return MAX(mask_len, s.length()) + delay;
|
||||
}
|
||||
|
||||
bool operator==(const rose_literal_id &b) const {
|
||||
return s == b.s && msk == b.msk && cmp == b.cmp && table == b.table &&
|
||||
delay == b.delay && distinctiveness == b.distinctiveness;
|
||||
}
|
||||
};
|
||||
|
||||
static inline
|
||||
@ -313,8 +319,60 @@ bool operator<(const rose_literal_id &a, const rose_literal_id &b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Literals are stored in a map from (string, nocase) -> ID
|
||||
typedef boost::bimap<rose_literal_id, u32> RoseLiteralMap;
|
||||
inline
|
||||
size_t hash_value(const rose_literal_id &lit) {
|
||||
return hash_all(lit.s, lit.msk, lit.cmp, lit.table, lit.delay,
|
||||
lit.distinctiveness);
|
||||
}
|
||||
|
||||
class RoseLiteralMap {
|
||||
/**
|
||||
* \brief Main storage for literals.
|
||||
*
|
||||
* Note that this cannot be a vector, as the present code relies on
|
||||
* iterator stability when iterating over this list and adding to it inside
|
||||
* the loop.
|
||||
*/
|
||||
std::deque<rose_literal_id> lits;
|
||||
|
||||
/** \brief Quick-lookup index from literal -> index in lits. */
|
||||
unordered_map<rose_literal_id, u32> lits_index;
|
||||
|
||||
public:
|
||||
std::pair<u32, bool> insert(const rose_literal_id &lit) {
|
||||
auto it = lits_index.find(lit);
|
||||
if (it != lits_index.end()) {
|
||||
return {it->second, false};
|
||||
}
|
||||
u32 id = verify_u32(lits.size());
|
||||
lits.push_back(lit);
|
||||
lits_index.emplace(lit, id);
|
||||
return {id, true};
|
||||
}
|
||||
|
||||
// Erase the last num elements.
|
||||
void erase_back(size_t num) {
|
||||
assert(num <= lits.size());
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
lits_index.erase(lits.back());
|
||||
lits.pop_back();
|
||||
}
|
||||
assert(lits.size() == lits_index.size());
|
||||
}
|
||||
|
||||
const rose_literal_id &at(u32 id) const {
|
||||
assert(id < lits.size());
|
||||
return lits.at(id);
|
||||
}
|
||||
|
||||
using const_iterator = decltype(lits)::const_iterator;
|
||||
const_iterator begin() const { return lits.begin(); }
|
||||
const_iterator end() const { return lits.end(); }
|
||||
|
||||
size_t size() const {
|
||||
return lits.size();
|
||||
}
|
||||
};
|
||||
|
||||
struct simple_anchored_info {
|
||||
simple_anchored_info(u32 min_b, u32 max_b, const ue2_literal &lit)
|
||||
|
@ -447,7 +447,7 @@ static
|
||||
void findFloodReach(const RoseBuildImpl &tbi, const RoseVertex v,
|
||||
set<CharReach> &flood_reach) {
|
||||
for (u32 lit_id : tbi.g[v].literals) {
|
||||
const ue2_literal &s = tbi.literals.right.at(lit_id).s;
|
||||
const ue2_literal &s = tbi.literals.at(lit_id).s;
|
||||
if (s.empty()) {
|
||||
continue;
|
||||
}
|
||||
@ -491,7 +491,7 @@ map<s32, CharReach> findLiteralReach(const RoseBuildImpl &build,
|
||||
map<s32, CharReach> look;
|
||||
|
||||
for (u32 lit_id : build.g[v].literals) {
|
||||
const rose_literal_id &lit = build.literals.right.at(lit_id);
|
||||
const rose_literal_id &lit = build.literals.at(lit_id);
|
||||
auto lit_look = findLiteralReach(lit);
|
||||
|
||||
if (first) {
|
||||
|
@ -211,7 +211,7 @@ bool maskFromPreds(const RoseBuildImpl &build, const rose_literal_id &id,
|
||||
}
|
||||
|
||||
u32 u_lit_id = *(g[u].literals.begin());
|
||||
const rose_literal_id &u_id = build.literals.right.at(u_lit_id);
|
||||
const rose_literal_id &u_id = build.literals.at(u_lit_id);
|
||||
DEBUG_PRINTF("u has lit: %s\n", escapeString(u_id.s).c_str());
|
||||
|
||||
// Number of characters to take from the back of u's literal.
|
||||
@ -346,9 +346,8 @@ void findMoreLiteralMasks(RoseBuildImpl &build) {
|
||||
}
|
||||
|
||||
vector<u32> candidates;
|
||||
for (const auto &e : build.literals.right) {
|
||||
const u32 id = e.first;
|
||||
const auto &lit = e.second;
|
||||
for (u32 id = 0; id < build.literals.size(); id++) {
|
||||
const auto &lit = build.literals.at(id);
|
||||
|
||||
if (lit.delay || build.isDelayed(id)) {
|
||||
continue;
|
||||
@ -377,7 +376,7 @@ void findMoreLiteralMasks(RoseBuildImpl &build) {
|
||||
}
|
||||
|
||||
for (const u32 &id : candidates) {
|
||||
const auto &lit = build.literals.right.at(id);
|
||||
const auto &lit = build.literals.at(id);
|
||||
auto &lit_info = build.literal_info.at(id);
|
||||
|
||||
vector<u8> msk, cmp;
|
||||
@ -492,7 +491,7 @@ bool isNoRunsLiteral(const RoseBuildImpl &build, const u32 id,
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t len = build.literals.right.at(id).s.length();
|
||||
size_t len = build.literals.at(id).s.length();
|
||||
if (len > max_len) {
|
||||
DEBUG_PRINTF("long literal, requires confirm\n");
|
||||
return false;
|
||||
@ -617,7 +616,7 @@ u64a literalMinReportOffset(const RoseBuildImpl &build,
|
||||
// If this literal in the undelayed literal corresponding to some delayed
|
||||
// literals, we must take their minimum offsets into account.
|
||||
for (const u32 &delayed_id : info.delayed_ids) {
|
||||
const auto &delayed_lit = build.literals.right.at(delayed_id);
|
||||
const auto &delayed_lit = build.literals.at(delayed_id);
|
||||
const auto &delayed_info = build.literal_info.at(delayed_id);
|
||||
u64a delayed_min_offset = literalMinReportOffset(build, delayed_lit,
|
||||
delayed_info);
|
||||
@ -682,7 +681,7 @@ MatcherProto makeMatcherProto(const RoseBuildImpl &build,
|
||||
|
||||
for (const auto &f : fragments) {
|
||||
for (u32 id : f.lit_ids) {
|
||||
const rose_literal_id &lit = build.literals.right.at(id);
|
||||
const rose_literal_id &lit = build.literals.at(id);
|
||||
|
||||
if (lit.table != table) {
|
||||
continue; /* wrong table */
|
||||
|
@ -1054,14 +1054,14 @@ bool mergeableRoseVertices(const RoseBuildImpl &tbi, RoseVertex u,
|
||||
vector<pair<const rose_literal_id *, u32>> ulits;
|
||||
ulits.reserve(tbi.g[u].literals.size());
|
||||
for (u32 id : tbi.g[u].literals) {
|
||||
ulits.push_back(make_pair(&tbi.literals.right.at(id), ulag));
|
||||
ulits.emplace_back(&tbi.literals.at(id), ulag);
|
||||
}
|
||||
|
||||
u32 vlag = tbi.g[v].left.lag;
|
||||
vector<pair<const rose_literal_id *, u32>> vlits;
|
||||
vlits.reserve(tbi.g[v].literals.size());
|
||||
for (u32 id : tbi.g[v].literals) {
|
||||
vlits.push_back(make_pair(&tbi.literals.right.at(id), vlag));
|
||||
vlits.emplace_back(&tbi.literals.at(id), vlag);
|
||||
}
|
||||
|
||||
if (!compatibleLiteralsForMerge(ulits, vlits)) {
|
||||
@ -1130,7 +1130,7 @@ bool checkPredDelays(const RoseBuildImpl &tbi, const deque<RoseVertex> &v1,
|
||||
vector<const rose_literal_id *> pred_rose_lits;
|
||||
pred_rose_lits.reserve(pred_lits.size());
|
||||
for (const auto &p : pred_lits) {
|
||||
pred_rose_lits.push_back(&tbi.literals.right.at(p));
|
||||
pred_rose_lits.push_back(&tbi.literals.at(p));
|
||||
}
|
||||
|
||||
for (auto v : v2) {
|
||||
@ -1140,7 +1140,7 @@ bool checkPredDelays(const RoseBuildImpl &tbi, const deque<RoseVertex> &v1,
|
||||
}
|
||||
|
||||
for (const u32 vlit : tbi.g[v].literals) {
|
||||
const rose_literal_id &vl = tbi.literals.right.at(vlit);
|
||||
const rose_literal_id &vl = tbi.literals.at(vlit);
|
||||
assert(!vl.delay); // this should never have got this far?
|
||||
for (const auto &ul : pred_rose_lits) {
|
||||
assert(!ul->delay); // this should never have got this far?
|
||||
@ -1195,7 +1195,7 @@ bool mergeableRoseVertices(const RoseBuildImpl &tbi,
|
||||
|
||||
u32 ulag = tbi.g[a].left.lag;
|
||||
for (u32 id : tbi.g[a].literals) {
|
||||
ulits.push_back(make_pair(&tbi.literals.right.at(id), ulag));
|
||||
ulits.emplace_back(&tbi.literals.at(id), ulag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1207,7 +1207,7 @@ bool mergeableRoseVertices(const RoseBuildImpl &tbi,
|
||||
|
||||
u32 vlag = tbi.g[a].left.lag;
|
||||
for (u32 id : tbi.g[a].literals) {
|
||||
vlits.push_back(make_pair(&tbi.literals.right.at(id), vlag));
|
||||
vlits.emplace_back(&tbi.literals.at(id), vlag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2730,7 +2730,7 @@ u32 allowedSquashDistance(const CharReach &cr, u32 min_width,
|
||||
|
||||
/* TODO: inspect further back in the pattern */
|
||||
for (u32 lit_id : g[tv].literals) {
|
||||
const rose_literal_id &lit = tbi.literals.right.at(lit_id);
|
||||
const rose_literal_id &lit = tbi.literals.at(lit_id);
|
||||
if (lit.delay) {
|
||||
return 0; /* TODO: better */
|
||||
}
|
||||
|
@ -154,14 +154,12 @@ bool isInTable(const RoseBuildImpl &tbi, RoseVertex v,
|
||||
|
||||
// All literals for a given vertex will be in the same table, so we need
|
||||
// only inspect the first one.
|
||||
const auto lit_table = tbi.literals.right.at(*lit_ids.begin()).table;
|
||||
const auto lit_table = tbi.literals.at(*lit_ids.begin()).table;
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Verify that all literals for this vertex are in the same table.
|
||||
for (auto lit_id : lit_ids) {
|
||||
assert(tbi.literals.right.at(lit_id).table == lit_table);
|
||||
}
|
||||
#endif
|
||||
assert(all_of_in(lit_ids, [&](u32 lit_id) {
|
||||
return tbi.literals.at(lit_id).table == lit_table;
|
||||
}));
|
||||
|
||||
return lit_table == table;
|
||||
}
|
||||
@ -211,7 +209,7 @@ size_t RoseBuildImpl::maxLiteralLen(RoseVertex v) const {
|
||||
size_t maxlen = 0;
|
||||
|
||||
for (const auto &lit_id : lit_ids) {
|
||||
maxlen = max(maxlen, literals.right.at(lit_id).elength());
|
||||
maxlen = max(maxlen, literals.at(lit_id).elength());
|
||||
}
|
||||
|
||||
return maxlen;
|
||||
@ -224,7 +222,7 @@ size_t RoseBuildImpl::minLiteralLen(RoseVertex v) const {
|
||||
size_t minlen = ROSE_BOUND_INF;
|
||||
|
||||
for (const auto &lit_id : lit_ids) {
|
||||
minlen = min(minlen, literals.right.at(lit_id).elength());
|
||||
minlen = min(minlen, literals.at(lit_id).elength());
|
||||
}
|
||||
|
||||
return minlen;
|
||||
@ -287,12 +285,11 @@ size_t maxOverlap(const rose_literal_id &a, const rose_literal_id &b) {
|
||||
static
|
||||
const rose_literal_id &getOverlapLiteral(const RoseBuildImpl &tbi,
|
||||
u32 literal_id) {
|
||||
map<u32, rose_literal_id>::const_iterator it =
|
||||
tbi.anchoredLitSuffix.find(literal_id);
|
||||
auto it = tbi.anchoredLitSuffix.find(literal_id);
|
||||
if (it != tbi.anchoredLitSuffix.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return tbi.literals.right.at(literal_id);
|
||||
return tbi.literals.at(literal_id);
|
||||
}
|
||||
|
||||
ue2_literal findNonOverlappingTail(const set<ue2_literal> &lits,
|
||||
@ -368,16 +365,14 @@ u32 RoseBuildImpl::calcSuccMaxBound(RoseVertex u) const {
|
||||
|
||||
u32 RoseBuildImpl::getLiteralId(const ue2_literal &s, u32 delay,
|
||||
rose_literal_table table) {
|
||||
DEBUG_PRINTF("getting id for %s\n", dumpString(s).c_str());
|
||||
DEBUG_PRINTF("getting id for %s in table %d\n", dumpString(s).c_str(),
|
||||
table);
|
||||
assert(table != ROSE_ANCHORED);
|
||||
rose_literal_id key(s, table, delay);
|
||||
u32 numLiterals = verify_u32(literals.left.size());
|
||||
|
||||
RoseLiteralMap::iterator it;
|
||||
bool inserted;
|
||||
tie(it, inserted)
|
||||
= literals.insert(RoseLiteralMap::value_type(key, numLiterals));
|
||||
u32 id = it->right;
|
||||
auto m = literals.insert(key);
|
||||
u32 id = m.first;
|
||||
bool inserted = m.second;
|
||||
|
||||
if (inserted) {
|
||||
literal_info.push_back(rose_literal_info());
|
||||
@ -457,19 +452,17 @@ rose_literal_id::rose_literal_id(const ue2_literal &s_in,
|
||||
u32 RoseBuildImpl::getLiteralId(const ue2_literal &s, const vector<u8> &msk,
|
||||
const vector<u8> &cmp, u32 delay,
|
||||
rose_literal_table table) {
|
||||
DEBUG_PRINTF("getting id for %s\n", dumpString(s).c_str());
|
||||
DEBUG_PRINTF("getting id for %s in table %d\n", dumpString(s).c_str(),
|
||||
table);
|
||||
assert(table != ROSE_ANCHORED);
|
||||
rose_literal_id key(s, msk, cmp, table, delay);
|
||||
u32 numLiterals = verify_u32(literals.left.size());
|
||||
|
||||
/* ue2_literals are always uppercased if nocase and must have an
|
||||
* alpha char */
|
||||
|
||||
RoseLiteralMap::iterator it;
|
||||
bool inserted;
|
||||
tie(it, inserted) = literals.insert(
|
||||
RoseLiteralMap::value_type(key, numLiterals));
|
||||
u32 id = it->right;
|
||||
auto m = literals.insert(key);
|
||||
u32 id = m.first;
|
||||
bool inserted = m.second;
|
||||
|
||||
if (inserted) {
|
||||
literal_info.push_back(rose_literal_info());
|
||||
@ -488,16 +481,12 @@ u32 RoseBuildImpl::getLiteralId(const ue2_literal &s, const vector<u8> &msk,
|
||||
|
||||
u32 RoseBuildImpl::getNewLiteralId() {
|
||||
rose_literal_id key(ue2_literal(), ROSE_ANCHORED, 0);
|
||||
u32 numLiterals = verify_u32(literals.left.size());
|
||||
u32 numLiterals = verify_u32(literals.size());
|
||||
key.distinctiveness = numLiterals;
|
||||
|
||||
RoseLiteralMap::iterator it;
|
||||
bool inserted;
|
||||
tie(it, inserted)
|
||||
= literals.insert(RoseLiteralMap::value_type(key, numLiterals));
|
||||
u32 id = it->right;
|
||||
|
||||
assert(inserted);
|
||||
auto m = literals.insert(key);
|
||||
assert(m.second);
|
||||
u32 id = m.first;
|
||||
|
||||
literal_info.push_back(rose_literal_info());
|
||||
assert(literal_info.size() == id + 1);
|
||||
|
@ -349,7 +349,7 @@ void makeAnchoredLiteralDelay(const RoseBuildImpl &build,
|
||||
const ProgramBuild &prog_build, u32 lit_id,
|
||||
RoseProgram &program) {
|
||||
// Only relevant for literals in the anchored table.
|
||||
const rose_literal_id &lit = build.literals.right.at(lit_id);
|
||||
const rose_literal_id &lit = build.literals.at(lit_id);
|
||||
if (lit.table != ROSE_ANCHORED) {
|
||||
return;
|
||||
}
|
||||
@ -686,7 +686,7 @@ void makePushDelayedInstructions(const RoseLiteralMap &literals,
|
||||
DEBUG_PRINTF("delayed lit id %u\n", delayed_lit_id);
|
||||
assert(contains(prog_build.delay_programs, delayed_lit_id));
|
||||
u32 delay_id = prog_build.delay_programs.at(delayed_lit_id);
|
||||
const auto &delay_lit = literals.right.at(delayed_lit_id);
|
||||
const auto &delay_lit = literals.at(delayed_lit_id);
|
||||
delay_instructions.emplace_back(verify_u8(delay_lit.delay), delay_id);
|
||||
}
|
||||
|
||||
@ -1335,7 +1335,7 @@ void makeCheckLitMaskInstruction(const RoseBuildImpl &build,
|
||||
|
||||
vector<LookEntry> look;
|
||||
|
||||
const ue2_literal &s = build.literals.right.at(lit_id).s;
|
||||
const ue2_literal &s = build.literals.at(lit_id).s;
|
||||
DEBUG_PRINTF("building mask for lit %u: %s\n", lit_id,
|
||||
dumpString(s).c_str());
|
||||
assert(s.length() <= MAX_MASK2_WIDTH);
|
||||
@ -1369,7 +1369,7 @@ void makeCheckLitEarlyInstruction(const RoseBuildImpl &build, u32 lit_id,
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &lit = build.literals.right.at(lit_id);
|
||||
const auto &lit = build.literals.at(lit_id);
|
||||
size_t min_len = lit.elength();
|
||||
u32 min_offset = findMinOffset(build, lit_id);
|
||||
DEBUG_PRINTF("has min_len=%zu, min_offset=%u, global min is %u\n", min_len,
|
||||
@ -1404,7 +1404,7 @@ void makeGroupCheckInstruction(const RoseBuildImpl &build, u32 lit_id,
|
||||
static
|
||||
bool hasDelayedLiteral(const RoseBuildImpl &build,
|
||||
const vector<RoseEdge> &lit_edges) {
|
||||
auto is_delayed = bind(&RoseBuildImpl::isDelayed, &build, _1);
|
||||
auto is_delayed = [&build](u32 lit_id) { return build.isDelayed(lit_id); };
|
||||
for (const auto &e : lit_edges) {
|
||||
auto v = target(e, build.g);
|
||||
const auto &lits = build.g[v].literals;
|
||||
@ -1425,7 +1425,7 @@ RoseProgram makeLitInitialProgram(const RoseBuildImpl &build,
|
||||
|
||||
// Check long literal info.
|
||||
if (!build.isDelayed(lit_id)) {
|
||||
makeCheckLiteralInstruction(build.literals.right.at(lit_id),
|
||||
makeCheckLiteralInstruction(build.literals.at(lit_id),
|
||||
prog_build.longLitLengthThreshold,
|
||||
program, build.cc);
|
||||
}
|
||||
@ -2121,7 +2121,7 @@ RoseProgram makeDelayRebuildProgram(const RoseBuildImpl &build,
|
||||
|
||||
RoseProgram prog;
|
||||
if (!build.isDelayed(lit_id)) {
|
||||
makeCheckLiteralInstruction(build.literals.right.at(lit_id),
|
||||
makeCheckLiteralInstruction(build.literals.at(lit_id),
|
||||
prog_build.longLitLengthThreshold, prog,
|
||||
build.cc);
|
||||
}
|
||||
|
@ -328,9 +328,9 @@ bool canMergeLiterals(RoseVertex a, RoseVertex b, const RoseBuildImpl &build) {
|
||||
|
||||
// Otherwise, all the literals involved must have the same length.
|
||||
for (u32 a_id : lits_a) {
|
||||
const rose_literal_id &la = build.literals.right.at(a_id);
|
||||
const rose_literal_id &la = build.literals.at(a_id);
|
||||
for (u32 b_id : lits_b) {
|
||||
const rose_literal_id &lb = build.literals.right.at(b_id);
|
||||
const rose_literal_id &lb = build.literals.at(b_id);
|
||||
|
||||
if (la.elength() != lb.elength()) {
|
||||
DEBUG_PRINTF("bad merge %zu!=%zu '%s', '%s'\n", la.elength(),
|
||||
@ -1483,7 +1483,7 @@ void splitByLiteralTable(const RoseBuildImpl &build,
|
||||
auto make_split_key = [&](RoseVertex v) {
|
||||
const auto &lits = g[v].literals;
|
||||
assert(!lits.empty());
|
||||
return build.literals.right.at(*lits.begin()).table;
|
||||
return build.literals.at(*lits.begin()).table;
|
||||
};
|
||||
splitAndFilterBuckets(buckets, make_split_key);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user