1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#pragma once
#include <yql/essentials/core/yql_type_annotation.h>
#include <yql/essentials/core/expr_nodes/yql_expr_nodes.h>
#include <string_view>
namespace NYql {
struct TOptimizeContext {
TTypeAnnotationContext* Types = nullptr;
TParentsMap* ParentsMap = nullptr;
const TExprNode* GetParentIfSingle(const TExprNode& node) const {
YQL_ENSURE(ParentsMap);
const auto it = ParentsMap->find(&node);
YQL_ENSURE(it != ParentsMap->cend());
auto& parents = it->second;
YQL_ENSURE(!parents.empty());
if (parents.size() > 1) {
return nullptr;
}
size_t usageCount = 0;
for (const auto& child : (*parents.cbegin())->ChildrenList()) {
if (child.Get() == &node && ++usageCount > 1) {
return nullptr;
}
}
YQL_ENSURE(usageCount == 1);
return *parents.cbegin();
}
bool IsSingleUsage(const TExprNode& node) const {
return bool(GetParentIfSingle(node));
}
bool IsSingleUsage(const NNodes::TExprBase& node) const {
return IsSingleUsage(node.Ref());
}
bool HasParent(const TExprNode& node) const {
YQL_ENSURE(ParentsMap);
return ParentsMap->contains(&node);
}
bool IsPersistentNode(const TExprNode& node) const {
if (Types) {
for (auto& source: Types->DataSources) {
if (source->IsPersistent(node)) {
return true;
}
}
for (auto& sink: Types->DataSinks) {
if (sink->IsPersistent(node)) {
return true;
}
}
}
return false;
}
bool IsPersistentNode(const NNodes::TExprBase& node) const {
return IsPersistentNode(node.Ref());
}
};
using TCallableOptimizerExt = std::function<TExprNode::TPtr (const TExprNode::TPtr&, TExprContext&, TOptimizeContext&)>;
using TCallableOptimizerMap = std::unordered_map<std::string_view, TCallableOptimizerExt>;
using TFinalizingOptimizerExt = std::function<bool (const TExprNode::TPtr&, TNodeOnNodeOwnedMap&, TExprContext&, TOptimizeContext&)>;
using TFinalizingOptimizerMap = std::unordered_map<std::string_view, TFinalizingOptimizerExt>;
struct TCoCallableRules {
enum {
SIMPLE_STEP_1,
SIMPLE_STEP_2,
SIMPLE_STEP_3,
SIMPLE_STEPS
};
enum {
FLOW_STEP_1,
FLOW_STEP_2,
FLOW_STEPS
};
// rules that don't make a flow fork - e.g. False || x -> x
TCallableOptimizerMap SimpleCallables[SIMPLE_STEPS];
// rules that make a flow fork - Join pushdown if Join has multiple usage
TCallableOptimizerMap FlowCallables[FLOW_STEPS];
TFinalizingOptimizerMap Finalizers;
// rules to be applied before execution
TCallableOptimizerMap FinalCallables;
TCoCallableRules();
static const TCoCallableRules& Instance();
};
void RegisterCoSimpleCallables1(TCallableOptimizerMap& map);
void RegisterCoSimpleCallables2(TCallableOptimizerMap& map);
void RegisterCoSimpleCallables3(TCallableOptimizerMap& map);
void RegisterCoFlowCallables1(TCallableOptimizerMap& map);
void RegisterCoFlowCallables2(TCallableOptimizerMap& map);
void RegisterCoFinalizers(TFinalizingOptimizerMap& map);
void RegisterCoFinalCallables(TCallableOptimizerMap& map);
}
|