@@ -45,21 +45,51 @@ static THashSet<TStringBuf> SubqueryExpandFuncs = {
45
45
TStringBuf (" SubqueryAssumeOrderBy" )
46
46
};
47
47
48
- TString MakeCacheKey (const TExprNode& root, TExprContext& ctx) {
49
- TConvertToAstSettings settings;
50
- settings.NormalizeAtomFlags = true ;
51
- settings.AllowFreeArgs = false ;
52
- settings.RefAtoms = true ;
53
- settings.NoInlineFunc = [](const TExprNode&) { return true ; };
54
- auto ast = ConvertToAst (root, ctx, settings);
55
- YQL_ENSURE (ast.Root );
56
- auto str = ast.Root ->ToString ();
57
- SHA256_CTX sha;
58
- SHA256_Init (&sha);
59
- SHA256_Update (&sha, str.Data (), str.Size ());
60
- unsigned char hash[SHA256_DIGEST_LENGTH];
61
- SHA256_Final (hash, &sha);
62
- return TString ((const char *)hash, sizeof (hash));
48
+ class TCacheKeyBuilder {
49
+ public:
50
+ TString Process (const TExprNode& root) {
51
+ SHA256_Init (&Sha);
52
+ unsigned char hash[SHA256_DIGEST_LENGTH];
53
+ Visit (root);
54
+ SHA256_Final (hash, &Sha);
55
+ return TString ((const char *)hash, sizeof (hash));
56
+ }
57
+
58
+ private:
59
+ void Visit (const TExprNode& node) {
60
+ auto [it, inserted] = Visited.emplace (&node, Visited.size ());
61
+ SHA256_Update (&Sha, &it->second , sizeof (it->second ));
62
+ if (!inserted) {
63
+ return ;
64
+ }
65
+
66
+ ui32 type = node.Type ();
67
+ SHA256_Update (&Sha, &type, sizeof (type));
68
+ if (node.Type () == TExprNode::EType::Atom || node.Type () == TExprNode::EType::Callable) {
69
+ ui32 textLen = node.Content ().size ();
70
+ SHA256_Update (&Sha, &textLen, sizeof (textLen));
71
+ SHA256_Update (&Sha, node.Content ().Data (), textLen);
72
+ }
73
+
74
+ if (node.Type () == TExprNode::EType::Atom || node.Type () == TExprNode::EType::Argument || node.Type () == TExprNode::EType::World) {
75
+ return ;
76
+ }
77
+
78
+ ui32 len = node.ChildrenSize ();
79
+ SHA256_Update (&Sha, &len, sizeof (len));
80
+ for (const auto & child : node.Children ()) {
81
+ Visit (*child);
82
+ }
83
+ }
84
+
85
+ private:
86
+ SHA256_CTX Sha;
87
+ TNodeMap<ui64> Visited;
88
+ };
89
+
90
+ TString MakeCacheKey (const TExprNode& root) {
91
+ TCacheKeyBuilder builder;
92
+ return builder.Process (root);
63
93
}
64
94
65
95
bool CheckPendingArgs (const TExprNode& root, TNodeSet& visited, TNodeMap<const TExprNode*>& activeArgs, const TNodeMap<ui32>& externalWorlds, TExprContext& ctx,
@@ -1053,7 +1083,7 @@ IGraphTransformer::TStatus EvaluateExpression(const TExprNode::TPtr& input, TExp
1053
1083
TString yson;
1054
1084
TString key;
1055
1085
if (types.QContext ) {
1056
- key = MakeCacheKey (*clonedArg, ctx );
1086
+ key = MakeCacheKey (*clonedArg);
1057
1087
}
1058
1088
1059
1089
if (types.QContext .CanRead ()) {
0 commit comments