aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravevad <avevad@yandex-team.com>2023-11-21 10:56:15 +0300
committeravevad <avevad@yandex-team.com>2023-11-21 11:54:22 +0300
commit4358278d7659145f2b87830fc78413499e6c51cb (patch)
treea1cffb8ec9e1bc032bdc39818deb6009c2ecdfec
parent90255fbb9d46ed371b9a85c4123f04f7037a406f (diff)
downloadydb-4358278d7659145f2b87830fc78413499e6c51cb.tar.gz
YQL-16823 Add optimization of single epsilon transitions in match_recognize NFA
-rw-r--r--ydb/library/yql/minikql/comp_nodes/mkql_match_recognize_nfa.h16
-rw-r--r--ydb/library/yql/minikql/comp_nodes/ut/mkql_match_recognize_nfa_ut.cpp19
2 files changed, 35 insertions, 0 deletions
diff --git a/ydb/library/yql/minikql/comp_nodes/mkql_match_recognize_nfa.h b/ydb/library/yql/minikql/comp_nodes/mkql_match_recognize_nfa.h
index a5918f17b4..540b9d005e 100644
--- a/ydb/library/yql/minikql/comp_nodes/mkql_match_recognize_nfa.h
+++ b/ydb/library/yql/minikql/comp_nodes/mkql_match_recognize_nfa.h
@@ -75,6 +75,7 @@ public:
void DoOptimizations() {
EliminateEpsilonChains();
+ EliminateSingleEpsilons();
CollectGarbage();
}
private:
@@ -98,6 +99,21 @@ private:
}
}
}
+ void EliminateSingleEpsilons() {
+ for (size_t node = 0; node != Graph->Transitions.size(); node++) {
+ if (std::holds_alternative<TEpsilonTransitions>(Graph->Transitions[node])) {
+ continue;
+ }
+ Graph->Transitions[node] = std::visit(TNfaTransitionDestinationVisitor([&](size_t toNode) -> size_t {
+ if (auto *tr = std::get_if<TEpsilonTransitions>(&Graph->Transitions[toNode])) {
+ if (tr->size() == 1) {
+ return (*tr)[0];
+ }
+ }
+ return toNode;
+ }), Graph->Transitions[node]);
+ }
+ }
void CollectGarbage() {
auto oldInput = Graph->Input;
auto oldOutput = Graph->Output;
diff --git a/ydb/library/yql/minikql/comp_nodes/ut/mkql_match_recognize_nfa_ut.cpp b/ydb/library/yql/minikql/comp_nodes/ut/mkql_match_recognize_nfa_ut.cpp
index 897a973f64..7d116d6563 100644
--- a/ydb/library/yql/minikql/comp_nodes/ut/mkql_match_recognize_nfa_ut.cpp
+++ b/ydb/library/yql/minikql/comp_nodes/ut/mkql_match_recognize_nfa_ut.cpp
@@ -169,6 +169,25 @@ Y_UNIT_TEST_SUITE(MatchRecognizeNfa) {
UNIT_ASSERT_GT(nonEpsIns[node] + nonEpsOuts[node], 0);
}
}
+ Y_UNIT_TEST(SingleEpsilonsEliminated) {
+ TScopedAlloc alloc(__LOCATION__);
+ const TRowPattern pattern{{
+ TRowPatternFactor{"A", 1, 1, false, false},
+ TRowPatternFactor{"B", 1, 1, false, false},
+ }};
+ const auto graph = TNfaTransitionGraphBuilder::Create(pattern, TNfaSetup::BuildVarLookup(pattern));
+ for (size_t node = 0; node != graph->Transitions.size(); node++) {
+ if (std::holds_alternative<TEpsilonTransitions>(graph->Transitions[node])) {
+ continue;
+ }
+ std::visit(TNfaTransitionDestinationVisitor([&](size_t toNode) -> size_t {
+ if (auto *tr = std::get_if<TEpsilonTransitions>(&graph->Transitions[toNode])) {
+ UNIT_ASSERT_UNEQUAL(tr->size(), 1);
+ }
+ return toNode;
+ }), graph->Transitions[node]);
+ }
+ }
//Tests for NFA-based engine for MATCH_RECOGNIZE