diff options
author | avevad <avevad@yandex-team.com> | 2023-11-21 10:56:15 +0300 |
---|---|---|
committer | avevad <avevad@yandex-team.com> | 2023-11-21 11:54:22 +0300 |
commit | 4358278d7659145f2b87830fc78413499e6c51cb (patch) | |
tree | a1cffb8ec9e1bc032bdc39818deb6009c2ecdfec | |
parent | 90255fbb9d46ed371b9a85c4123f04f7037a406f (diff) | |
download | ydb-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.h | 16 | ||||
-rw-r--r-- | ydb/library/yql/minikql/comp_nodes/ut/mkql_match_recognize_nfa_ut.cpp | 19 |
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 |