mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
tidy mergeCastleSuffixes
This commit is contained in:
parent
6f452668ec
commit
ace592e247
@ -2706,8 +2706,8 @@ void mergePuffixes(RoseBuildImpl &tbi) {
|
|||||||
static
|
static
|
||||||
void updateCastleSuffix(RoseGraph &g, const shared_ptr<CastleProto> &m,
|
void updateCastleSuffix(RoseGraph &g, const shared_ptr<CastleProto> &m,
|
||||||
u32 top, const vector<RoseVertex> &verts) {
|
u32 top, const vector<RoseVertex> &verts) {
|
||||||
DEBUG_PRINTF("merged in as top %u, updating %zu vertices\n", top,
|
DEBUG_PRINTF("merged in as top %u of %p, updating %zu vertices\n", top,
|
||||||
verts.size());
|
m.get(), verts.size());
|
||||||
|
|
||||||
for (auto v : verts) {
|
for (auto v : verts) {
|
||||||
assert(g[v].suffix.castle);
|
assert(g[v].suffix.castle);
|
||||||
@ -2717,77 +2717,56 @@ void updateCastleSuffix(RoseGraph &g, const shared_ptr<CastleProto> &m,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void mergeCastleSuffixes(RoseBuildImpl &tbi,
|
void mergeCastleSuffixChunk(RoseGraph &g, const vector<CastleProto *> &castles,
|
||||||
vector<shared_ptr<CastleProto> > &castles,
|
const unordered_map<CastleProto *, vector<RoseVertex>> &eng_verts) {
|
||||||
map<shared_ptr<CastleProto>, vector<RoseVertex> > &castle_map) {
|
|
||||||
if (castles.size() <= 1) {
|
if (castles.size() <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RoseGraph &g = tbi.g;
|
DEBUG_PRINTF("merging reach %s, %zu elements\n",
|
||||||
const size_t max_size = CastleProto::max_occupancy;
|
describeClass(castles[0]->reach()).c_str(), castles.size());
|
||||||
|
|
||||||
shared_ptr<CastleProto> m = castles.front();
|
CastleProto *m = nullptr;
|
||||||
assert(m->repeats.size() == 1); // Not yet merged.
|
|
||||||
|
|
||||||
// Cache repeats we've already merged, mapped to (prototype, top). That
|
for (CastleProto *c : castles) {
|
||||||
// way, we can ensure that we don't construct more than one completely
|
|
||||||
// identical repeat.
|
|
||||||
typedef map<PureRepeat, pair<shared_ptr<CastleProto>, u32> > RepeatCache;
|
|
||||||
RepeatCache cache;
|
|
||||||
{
|
|
||||||
// Initial entry in cache.
|
|
||||||
const u32 top = m->repeats.begin()->first;
|
|
||||||
const PureRepeat &pr = m->repeats.begin()->second;
|
|
||||||
cache[pr] = make_pair(m, top);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 1; i < castles.size(); i++) {
|
|
||||||
shared_ptr<CastleProto> c = castles[i];
|
|
||||||
assert(c->repeats.size() == 1); // Not yet merged.
|
assert(c->repeats.size() == 1); // Not yet merged.
|
||||||
const PureRepeat &pr = c->repeats.begin()->second;
|
assert(g[eng_verts.at(c).front()].suffix.castle.get() == c);
|
||||||
RepeatCache::const_iterator it = cache.find(pr);
|
if (!m) {
|
||||||
if (it != cache.end()) {
|
m = c;
|
||||||
DEBUG_PRINTF("reusing cached merge, top=%u, proto=%p\n",
|
|
||||||
it->second.second, it->second.first.get());
|
|
||||||
updateCastleSuffix(g, it->second.first, it->second.second,
|
|
||||||
castle_map[c]);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->repeats.size() == max_size) {
|
u32 top = m->merge(c->repeats[0]);
|
||||||
|
if (top == CastleProto::max_occupancy) {
|
||||||
// No room left to merge into 'm'. This one becomes the new 'm'.
|
// No room left to merge into 'm'. This one becomes the new 'm'.
|
||||||
DEBUG_PRINTF("next mergee\n");
|
DEBUG_PRINTF("next mergee\n");
|
||||||
m = c;
|
m = c;
|
||||||
u32 top = m->repeats.begin()->first;
|
continue;
|
||||||
cache[pr] = make_pair(m, top);
|
|
||||||
} else {
|
|
||||||
u32 top = m->add(pr);
|
|
||||||
updateCastleSuffix(g, m, top, castle_map[c]);
|
|
||||||
DEBUG_PRINTF("added to %p, top %u\n", m.get(), top);
|
|
||||||
cache[pr] = make_pair(m, top);
|
|
||||||
}
|
}
|
||||||
|
updateCastleSuffix(g, g[eng_verts.at(m).front()].suffix.castle, top,
|
||||||
|
eng_verts.at(c));
|
||||||
|
DEBUG_PRINTF("added to %p, top %u\n", m, top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mergeCastleSuffixes(RoseBuildImpl &tbi) {
|
void mergeCastleSuffixes(RoseBuildImpl &build) {
|
||||||
DEBUG_PRINTF("entry\n");
|
DEBUG_PRINTF("entry\n");
|
||||||
|
|
||||||
if (!(tbi.cc.grey.allowCastle && tbi.cc.grey.mergeSuffixes)) {
|
if (!build.cc.grey.allowCastle || !build.cc.grey.mergeSuffixes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<shared_ptr<CastleProto>, vector<RoseVertex>> castles;
|
unordered_map<CastleProto *, vector<RoseVertex>> eng_verts;
|
||||||
map<CharReach, vector<shared_ptr<CastleProto>>> by_reach;
|
map<CharReach, vector<CastleProto *>> by_reach;
|
||||||
|
|
||||||
RoseGraph &g = tbi.g;
|
RoseGraph &g = build.g;
|
||||||
|
|
||||||
for (auto v : vertices_range(g)) {
|
for (auto v : vertices_range(g)) {
|
||||||
if (!g[v].suffix.castle) {
|
if (!g[v].suffix.castle) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<CastleProto> c = g[v].suffix.castle;
|
CastleProto *c = g[v].suffix.castle.get();
|
||||||
|
|
||||||
if (c->repeats.size() != 1) {
|
if (c->repeats.size() != 1) {
|
||||||
// This code assumes it's the only place merging is being done.
|
// This code assumes it's the only place merging is being done.
|
||||||
@ -2795,16 +2774,14 @@ void mergeCastleSuffixes(RoseBuildImpl &tbi) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!contains(castles, c)) {
|
if (!contains(eng_verts, c)) {
|
||||||
by_reach[c->reach()].push_back(c);
|
by_reach[c->reach()].push_back(c);
|
||||||
}
|
}
|
||||||
castles[c].push_back(v);
|
eng_verts[c].push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &m : by_reach) {
|
for (auto &chunk : by_reach | map_values) {
|
||||||
DEBUG_PRINTF("reach %s, %zu elements\n", describeClass(m.first).c_str(),
|
mergeCastleSuffixChunk(g, chunk, eng_verts);
|
||||||
m.second.size());
|
|
||||||
mergeCastleSuffixes(tbi, m.second, castles);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user