5
5
#include < ydb/library/yql/minikql/mkql_string_util.h>
6
6
7
7
#include < ydb/library/yql/minikql/computation/mkql_computation_node_holders.h>
8
+ #include < ydb/library/yql/minikql/computation/mock_spiller_factory_ut.h>
8
9
9
10
#include < cstring>
10
- #include < random>
11
11
#include < algorithm>
12
12
13
13
namespace NKikimr {
@@ -30,6 +30,7 @@ using TBaseComputation = TMutableComputationNode<TTestStreamWrapper>;
30
30
{}
31
31
private:
32
32
NUdf::EFetchStatus Fetch (NUdf::TUnboxedValue& result) override {
33
+
33
34
constexpr auto size = Y_ARRAY_SIZE (g_TestYieldStreamData);
34
35
if (Index == size) {
35
36
return NUdf::EFetchStatus::Finish;
@@ -47,6 +48,7 @@ using TBaseComputation = TMutableComputationNode<TTestStreamWrapper>;
47
48
items[1 ] = NUdf::TUnboxedValuePod (MakeString (ToString (val)));
48
49
49
50
++Index;
51
+
50
52
return NUdf::EFetchStatus::Ok;
51
53
}
52
54
@@ -117,6 +119,13 @@ TRuntimeNode Combine(TProgramBuilder& pb, TRuntimeNode stream, std::function<TRu
117
119
pb.CombineCore (stream, keyExtractor, init, update, finishLambda, 64ul << 20 );
118
120
}
119
121
122
+ template <bool SPILLING>
123
+ TRuntimeNode WideLastCombiner (TProgramBuilder& pb, TRuntimeNode flow, const TProgramBuilder::TWideLambda& extractor, const TProgramBuilder::TBinaryWideLambda& init, const TProgramBuilder::TTernaryWideLambda& update, const TProgramBuilder::TBinaryWideLambda& finish) {
124
+ return SPILLING ?
125
+ pb.WideLastCombinerWithSpilling (flow, extractor, init, update, finish):
126
+ pb.WideLastCombiner (flow, extractor, init, update, finish);
127
+ }
128
+
120
129
} // unnamed
121
130
122
131
#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 18u
@@ -996,8 +1005,13 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideCombinerPerfTest) {
996
1005
#endif
997
1006
#if !defined(MKQL_RUNTIME_VERSION) || MKQL_RUNTIME_VERSION >= 29u
998
1007
Y_UNIT_TEST_SUITE (TMiniKQLWideLastCombinerTest) {
999
- Y_UNIT_TEST_LLVM (TestLongStringsRefCounting) {
1000
- TSetup<LLVM> setup;
1008
+ Y_UNIT_TEST_LLVM_SPILLING (TestLongStringsRefCounting) {
1009
+ // Currently LLVM version doesn't support spilling.
1010
+ if (LLVM && SPILLING) return ;
1011
+ // callable WideLastCombinerWithSpilling was introduced in 49 version of runtime
1012
+ if (MKQL_RUNTIME_VERSION < 49U && SPILLING) return ;
1013
+
1014
+ TSetup<LLVM, SPILLING> setup;
1001
1015
TProgramBuilder& pb = *setup.PgmBuilder ;
1002
1016
1003
1017
const auto dataType = pb.NewDataType (NUdf::TDataType<const char *>::Id);
@@ -1035,7 +1049,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1035
1049
1036
1050
const auto list = pb.NewList (tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
1037
1051
1038
- const auto pgmReturn = pb.Collect (pb.NarrowMap (pb. WideLastCombiner ( pb.ExpandMap (pb.ToFlow (list),
1052
+ const auto pgmReturn = pb.Collect (pb.NarrowMap (WideLastCombiner<SPILLING>(pb, pb.ExpandMap (pb.ToFlow (list),
1039
1053
[&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth (item, 0U ), pb.Nth (item, 1U )}; }),
1040
1054
[&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front ()}; },
1041
1055
[&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
@@ -1059,22 +1073,37 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1059
1073
));
1060
1074
1061
1075
const auto graph = setup.BuildGraph (pgmReturn);
1076
+ if (SPILLING) {
1077
+ graph->GetContext ().SpillerFactory = std::make_shared<TMockSpillerFactory>();
1078
+ }
1062
1079
const auto iterator = graph->GetValue ().GetListIterator ();
1080
+
1081
+ std::unordered_set<TString> expected {
1082
+ " key one" ,
1083
+ " very long value 2 / key two" ,
1084
+ " very long key one" ,
1085
+ " very long value 8 / very long value 7 / very long value 6"
1086
+ };
1087
+
1063
1088
NUdf::TUnboxedValue item;
1064
- UNIT_ASSERT (iterator. Next (item));
1065
- UNBOXED_VALUE_STR_EQUAL (item, " key one " );
1066
- UNIT_ASSERT (iterator. Next (item ));
1067
- UNBOXED_VALUE_STR_EQUAL (item, " very long value 2 / key two " );
1068
- UNIT_ASSERT (iterator. Next (item) );
1069
- UNBOXED_VALUE_STR_EQUAL (item, " very long key one " );
1070
- UNIT_ASSERT (iterator. Next (item) );
1071
- UNBOXED_VALUE_STR_EQUAL (item, " very long value 8 / very long value 7 / very long value 6 " );
1089
+ while (!expected. empty ()) {
1090
+ UNIT_ASSERT (iterator. Next (item) );
1091
+ const auto actual = TString (item. AsStringRef ( ));
1092
+
1093
+ auto it = expected. find (actual );
1094
+ UNIT_ASSERT (it != expected. end () );
1095
+ expected. erase (it );
1096
+ }
1072
1097
UNIT_ASSERT (!iterator.Next (item));
1073
1098
UNIT_ASSERT (!iterator.Next (item));
1074
1099
}
1075
1100
1076
- Y_UNIT_TEST_LLVM (TestLongStringsPasstroughtRefCounting) {
1077
- TSetup<LLVM> setup;
1101
+ Y_UNIT_TEST_LLVM_SPILLING (TestLongStringsPasstroughtRefCounting) {
1102
+ // Currently LLVM version doesn't support spilling.
1103
+ if (LLVM && SPILLING) return ;
1104
+ // callable WideLastCombinerWithSpilling was introduced in 49 version of runtime
1105
+ if (MKQL_RUNTIME_VERSION < 49U && SPILLING) return ;
1106
+ TSetup<LLVM, SPILLING> setup;
1078
1107
TProgramBuilder& pb = *setup.PgmBuilder ;
1079
1108
1080
1109
const auto dataType = pb.NewDataType (NUdf::TDataType<const char *>::Id);
@@ -1111,7 +1140,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1111
1140
1112
1141
const auto list = pb.NewList (tupleType, {data1, data2, data3, data4, data5, data6, data7, data8, data9});
1113
1142
1114
- const auto pgmReturn = pb.Collect (pb.NarrowMap (pb. WideLastCombiner ( pb.ExpandMap (pb.ToFlow (list),
1143
+ const auto pgmReturn = pb.Collect (pb.NarrowMap (WideLastCombiner<SPILLING>(pb, pb.ExpandMap (pb.ToFlow (list),
1115
1144
[&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth (item, 0U ), pb.Nth (item, 1U )}; }),
1116
1145
[&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front ()}; },
1117
1146
[&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
@@ -1134,22 +1163,40 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1134
1163
));
1135
1164
1136
1165
const auto graph = setup.BuildGraph (pgmReturn);
1166
+ if (SPILLING) {
1167
+ graph->GetContext ().SpillerFactory = std::make_shared<TMockSpillerFactory>();
1168
+ }
1137
1169
const auto iterator = graph->GetValue ().GetListIterator ();
1170
+
1171
+ std::unordered_set<TString> expected {
1172
+ " very long value 1 / key one / very long value 1 / key one" ,
1173
+ " very long value 3 / key two / very long value 2 / key two" ,
1174
+ " very long value 4 / very long key one / very long value 4 / very long key one" ,
1175
+ " very long value 9 / very long key two / very long value 5 / very long key two"
1176
+ };
1177
+
1138
1178
NUdf::TUnboxedValue item;
1139
- UNIT_ASSERT (iterator. Next (item));
1140
- UNBOXED_VALUE_STR_EQUAL (item, " very long value 1 / key one / very long value 1 / key one " );
1141
- UNIT_ASSERT (iterator. Next (item ));
1142
- UNBOXED_VALUE_STR_EQUAL (item, " very long value 3 / key two / very long value 2 / key two " );
1143
- UNIT_ASSERT (iterator. Next (item) );
1144
- UNBOXED_VALUE_STR_EQUAL (item, " very long value 4 / very long key one / very long value 4 / very long key one " );
1145
- UNIT_ASSERT (iterator. Next (item) );
1146
- UNBOXED_VALUE_STR_EQUAL (item, " very long value 9 / very long key two / very long value 5 / very long key two " );
1179
+ while (!expected. empty ()) {
1180
+ UNIT_ASSERT (iterator. Next (item) );
1181
+ const auto actual = TString (item. AsStringRef ( ));
1182
+
1183
+ auto it = expected. find (actual );
1184
+ UNIT_ASSERT (it != expected. end () );
1185
+ expected. erase (it );
1186
+ }
1147
1187
UNIT_ASSERT (!iterator.Next (item));
1148
1188
UNIT_ASSERT (!iterator.Next (item));
1149
1189
}
1150
1190
1151
- Y_UNIT_TEST_LLVM (TestDoNotCalculateUnusedInput) {
1152
- TSetup<LLVM> setup;
1191
+ Y_UNIT_TEST_LLVM_SPILLING (TestDoNotCalculateUnusedInput) {
1192
+ // Test is broken. Remove this if after YQL-18808.
1193
+ if (SPILLING) return ;
1194
+
1195
+ // Currently LLVM version doesn't support spilling.
1196
+ if (LLVM && SPILLING) return ;
1197
+ // callable WideLastCombinerWithSpilling was introduced in 49 version of runtime
1198
+ if (MKQL_RUNTIME_VERSION < 49U && SPILLING) return ;
1199
+ TSetup<LLVM, SPILLING> setup;
1153
1200
TProgramBuilder& pb = *setup.PgmBuilder ;
1154
1201
1155
1202
const auto dataType = pb.NewDataType (NUdf::TDataType<const char *>::Id);
@@ -1183,7 +1230,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1183
1230
1184
1231
const auto landmine = pb.NewDataLiteral <NUdf::EDataSlot::String>(" ACHTUNG MINEN!" );
1185
1232
1186
- const auto pgmReturn = pb.Collect (pb.NarrowMap (pb. WideLastCombiner ( pb.ExpandMap (pb.ToFlow (list),
1233
+ const auto pgmReturn = pb.Collect (pb.NarrowMap (WideLastCombiner<SPILLING>(pb, pb.ExpandMap (pb.ToFlow (list),
1187
1234
[&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth (item, 0U ), pb.Unwrap (pb.Nth (item, 1U ), landmine, __FILE__, __LINE__, 0 ), pb.Nth (item, 2U )}; }),
1188
1235
[&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front ()}; },
1189
1236
[&](TRuntimeNode::TList keys, TRuntimeNode::TList items) -> TRuntimeNode::TList {
@@ -1207,18 +1254,34 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1207
1254
));
1208
1255
1209
1256
const auto graph = setup.BuildGraph (pgmReturn);
1257
+ if (SPILLING) {
1258
+ graph->GetContext ().SpillerFactory = std::make_shared<TMockSpillerFactory>();
1259
+ }
1260
+ std::unordered_set<TString> expected {
1261
+ " key one / value 2 / value 1 / value 5 / value 4" ,
1262
+ " key two / value 4 / value 3 / value 3 / value 2"
1263
+ };
1264
+
1210
1265
const auto iterator = graph->GetValue ().GetListIterator ();
1211
1266
NUdf::TUnboxedValue item;
1212
- UNIT_ASSERT (iterator.Next (item));
1213
- UNBOXED_VALUE_STR_EQUAL (item, " key one / value 2 / value 1 / value 5 / value 4" );
1214
- UNIT_ASSERT (iterator.Next (item));
1215
- UNBOXED_VALUE_STR_EQUAL (item, " key two / value 4 / value 3 / value 3 / value 2" );
1267
+ while (!expected.empty ()) {
1268
+ UNIT_ASSERT (iterator.Next (item));
1269
+ const auto actual = TString (item.AsStringRef ());
1270
+
1271
+ auto it = expected.find (actual);
1272
+ UNIT_ASSERT (it != expected.end ());
1273
+ expected.erase (it);
1274
+ }
1216
1275
UNIT_ASSERT (!iterator.Next (item));
1217
1276
UNIT_ASSERT (!iterator.Next (item));
1218
1277
}
1219
1278
1220
- Y_UNIT_TEST_LLVM (TestDoNotCalculateUnusedOutput) {
1221
- TSetup<LLVM> setup;
1279
+ Y_UNIT_TEST_LLVM_SPILLING (TestDoNotCalculateUnusedOutput) {
1280
+ // Currently LLVM version doesn't support spilling.
1281
+ if (LLVM && SPILLING) return ;
1282
+ // callable WideLastCombinerWithSpilling was introduced in 49 version of runtime
1283
+ if (MKQL_RUNTIME_VERSION < 49U && SPILLING) return ;
1284
+ TSetup<LLVM, SPILLING> setup;
1222
1285
TProgramBuilder& pb = *setup.PgmBuilder ;
1223
1286
1224
1287
const auto dataType = pb.NewDataType (NUdf::TDataType<const char *>::Id);
@@ -1252,7 +1315,7 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1252
1315
1253
1316
const auto landmine = pb.NewDataLiteral <NUdf::EDataSlot::String>(" ACHTUNG MINEN!" );
1254
1317
1255
- const auto pgmReturn = pb.Collect (pb.NarrowMap (pb. WideLastCombiner ( pb.ExpandMap (pb.ToFlow (list),
1318
+ const auto pgmReturn = pb.Collect (pb.NarrowMap (WideLastCombiner<SPILLING>(pb, pb.ExpandMap (pb.ToFlow (list),
1256
1319
[&](TRuntimeNode item) -> TRuntimeNode::TList { return {pb.Nth (item, 0U ), pb.Nth (item, 1U ), pb.Nth (item, 2U )}; }),
1257
1320
[&](TRuntimeNode::TList items) -> TRuntimeNode::TList { return {items.front ()}; },
1258
1321
[&](TRuntimeNode::TList, TRuntimeNode::TList items) -> TRuntimeNode::TList {
@@ -1268,26 +1331,42 @@ Y_UNIT_TEST_SUITE(TMiniKQLWideLastCombinerTest) {
1268
1331
));
1269
1332
1270
1333
const auto graph = setup.BuildGraph (pgmReturn);
1334
+ if (SPILLING) {
1335
+ graph->GetContext ().SpillerFactory = std::make_shared<TMockSpillerFactory>();
1336
+ }
1337
+ std::unordered_set<TString> expected {
1338
+ " key one: value 1, value 4, value 5, value 1, value 2" ,
1339
+ " key two: value 2, value 3, value 3, value 4"
1340
+ };
1341
+
1271
1342
const auto iterator = graph->GetValue ().GetListIterator ();
1272
1343
NUdf::TUnboxedValue item;
1273
- UNIT_ASSERT (iterator.Next (item));
1274
- UNBOXED_VALUE_STR_EQUAL (item, " key one: value 1, value 4, value 5, value 1, value 2" );
1275
- UNIT_ASSERT (iterator.Next (item));
1276
- UNBOXED_VALUE_STR_EQUAL (item, " key two: value 2, value 3, value 3, value 4" );
1344
+ while (!expected.empty ()) {
1345
+ UNIT_ASSERT (iterator.Next (item));
1346
+ const auto actual = TString (item.AsStringRef ());
1347
+
1348
+ auto it = expected.find (actual);
1349
+ UNIT_ASSERT (it != expected.end ());
1350
+ expected.erase (it);
1351
+ }
1277
1352
UNIT_ASSERT (!iterator.Next (item));
1278
1353
UNIT_ASSERT (!iterator.Next (item));
1279
1354
}
1280
1355
1281
- Y_UNIT_TEST_LLVM (TestThinAllLambdas) {
1282
- TSetup<LLVM> setup;
1356
+ Y_UNIT_TEST_LLVM_SPILLING (TestThinAllLambdas) {
1357
+ // Currently LLVM version doesn't support spilling.
1358
+ if (LLVM && SPILLING) return ;
1359
+ // callable WideLastCombinerWithSpilling was introduced in 49 version of runtime
1360
+ if (MKQL_RUNTIME_VERSION < 49U && SPILLING) return ;
1361
+ TSetup<LLVM, SPILLING> setup;
1283
1362
TProgramBuilder& pb = *setup.PgmBuilder ;
1284
1363
1285
1364
const auto tupleType = pb.NewTupleType ({});
1286
1365
const auto data = pb.NewTuple ({});
1287
1366
1288
1367
const auto list = pb.NewList (tupleType, {data, data, data, data});
1289
1368
1290
- const auto pgmReturn = pb.Collect (pb.NarrowMap (pb. WideLastCombiner ( pb.ExpandMap (pb.ToFlow (list),
1369
+ const auto pgmReturn = pb.Collect (pb.NarrowMap (WideLastCombiner<SPILLING>(pb, pb.ExpandMap (pb.ToFlow (list),
1291
1370
[](TRuntimeNode) -> TRuntimeNode::TList { return {}; }),
1292
1371
[](TRuntimeNode::TList items) { return items; },
1293
1372
[](TRuntimeNode::TList, TRuntimeNode::TList items) { return items; },
0 commit comments