dfa: adding new Sheng engine

A new shuffle-based DFA engine, complete with acceleration and smallwrite.
This commit is contained in:
Anatoly Burakov
2016-03-10 09:57:41 +00:00
committed by Matthew Barr
parent 56bf25b091
commit 6331da4e29
24 changed files with 2591 additions and 25 deletions

View File

@@ -50,6 +50,7 @@
#include "nfa/nfa_api_queue.h"
#include "nfa/nfa_build_util.h"
#include "nfa/nfa_internal.h"
#include "nfa/shengcompile.h"
#include "nfa/shufticompile.h"
#include "nfa/tamaramacompile.h"
#include "nfa/tamarama_internal.h"
@@ -863,13 +864,18 @@ aligned_unique_ptr<NFA> pickImpl(aligned_unique_ptr<NFA> dfa_impl,
aligned_unique_ptr<NFA> nfa_impl) {
assert(nfa_impl);
assert(dfa_impl);
assert(isMcClellanType(dfa_impl->type));
assert(isDfaType(dfa_impl->type));
// If our NFA is an LBR, it always wins.
if (isLbrType(nfa_impl->type)) {
return nfa_impl;
}
// if our DFA is an accelerated Sheng, it always wins.
if (isShengType(dfa_impl->type) && has_accel(*dfa_impl)) {
return dfa_impl;
}
bool d_accel = has_accel(*dfa_impl);
bool n_accel = has_accel(*nfa_impl);
bool d_big = dfa_impl->type == MCCLELLAN_NFA_16;
@@ -922,6 +928,18 @@ buildRepeatEngine(const CastleProto &proto,
return castle_nfa;
}
static
aligned_unique_ptr<NFA> getDfa(raw_dfa &rdfa, const CompileContext &cc,
const ReportManager &rm) {
// Unleash the Sheng!!
auto dfa = shengCompile(rdfa, cc, rm);
if (!dfa) {
// Sheng wasn't successful, so unleash McClellan!
dfa = mcclellanCompile(rdfa, cc, rm);
}
return dfa;
}
/* builds suffix nfas */
static
aligned_unique_ptr<NFA>
@@ -942,7 +960,7 @@ buildSuffix(const ReportManager &rm, const SomSlotManager &ssm,
}
if (suff.dfa()) {
auto d = mcclellanCompile(*suff.dfa(), cc, rm);
auto d = getDfa(*suff.dfa(), cc, rm);
assert(d);
return d;
}
@@ -971,7 +989,7 @@ buildSuffix(const ReportManager &rm, const SomSlotManager &ssm,
auto rdfa = buildMcClellan(holder, &rm, false, triggers.at(0),
cc.grey);
if (rdfa) {
auto d = mcclellanCompile(*rdfa, cc, rm);
auto d = getDfa(*rdfa, cc, rm);
assert(d);
if (cc.grey.roseMcClellanSuffix != 2) {
n = pickImpl(move(d), move(n));
@@ -1091,12 +1109,13 @@ makeLeftNfa(const RoseBuildImpl &tbi, left_id &left,
}
if (left.dfa()) {
n = mcclellanCompile(*left.dfa(), cc, rm);
n = getDfa(*left.dfa(), cc, rm);
} else if (left.graph() && cc.grey.roseMcClellanPrefix == 2 && is_prefix &&
!is_transient) {
auto rdfa = buildMcClellan(*left.graph(), nullptr, cc.grey);
if (rdfa) {
n = mcclellanCompile(*rdfa, cc, rm);
n = getDfa(*rdfa, cc, rm);
assert(n);
}
}
@@ -1122,7 +1141,7 @@ makeLeftNfa(const RoseBuildImpl &tbi, left_id &left,
&& (!n || !has_bounded_repeats_other_than_firsts(*n) || !is_fast(*n))) {
auto rdfa = buildMcClellan(*left.graph(), nullptr, cc.grey);
if (rdfa) {
auto d = mcclellanCompile(*rdfa, cc, rm);
auto d = getDfa(*rdfa, cc, rm);
assert(d);
n = pickImpl(move(d), move(n));
}
@@ -1857,8 +1876,8 @@ public:
};
aligned_unique_ptr<NFA> operator()(unique_ptr<raw_dfa> &rdfa) const {
// Unleash the McClellan!
return mcclellanCompile(*rdfa, build.cc, build.rm);
// Unleash the mighty DFA!
return getDfa(*rdfa, build.cc, build.rm);
}
aligned_unique_ptr<NFA> operator()(unique_ptr<raw_som_dfa> &haig) const {
@@ -1886,7 +1905,7 @@ public:
!has_bounded_repeats_other_than_firsts(*n)) {
auto rdfa = buildMcClellan(h, &rm, cc.grey);
if (rdfa) {
auto d = mcclellanCompile(*rdfa, cc, rm);
auto d = getDfa(*rdfa, cc, rm);
if (d) {
n = pickImpl(move(d), move(n));
}