Skip to content

Commit d78c86c

Browse files
authored
avoid allocating data on TTypeEnv when making cell vectors (#12552)
1 parent 52ecaf3 commit d78c86c

File tree

3 files changed

+65
-4
lines changed

3 files changed

+65
-4
lines changed

ydb/core/engine/mkql_keys.cpp

+19-2
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,10 @@ THolder<TKeyDesc> ExtractEraseRow(TCallable& callable, const TTypeEnvironment& e
251251
#define MAKE_PRIMITIVE_TYPE_CELL(type, layout) \
252252
case NUdf::TDataType<type>::Id: return MakeCell<layout>(value);
253253

254-
TCell MakeCell(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
255-
const TTypeEnvironment& env, bool copy,
254+
255+
template<typename TStringBackend>
256+
TCell MakeCellImpl(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
257+
const TStringBackend& env, bool copy,
256258
i32 typmod, TMaybe<TString>* error)
257259
{
258260
if (!value)
@@ -300,6 +302,21 @@ TCell MakeCell(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
300302
return TCell(val.Data(), val.Size());
301303
}
302304

305+
TCell MakeCell(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
306+
const TTypeEnvironment& env, bool copy,
307+
i32 typmod, TMaybe<TString>* error)
308+
{
309+
return MakeCellImpl(type, value, env, copy, typmod, error);
310+
}
311+
312+
TCell MakeCell(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
313+
const TStringProviderBackend& env, bool copy,
314+
i32 typmod, TMaybe<TString>* error)
315+
{
316+
return MakeCellImpl(type, value, env, copy, typmod, error);
317+
}
318+
319+
303320
#undef MAKE_PRIMITIVE_TYPE_CELL
304321

305322
TReadTarget ExtractFlatReadTarget(TRuntimeNode modeInput) {

ydb/core/engine/mkql_keys.h

+38
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,48 @@ TCell MakeCell(const NUdf::TUnboxedValuePod& value) {
5252
return TCell(reinterpret_cast<const char*>(&v), sizeof(v));
5353
}
5454

55+
struct TStringProviderBackend {
56+
mutable TMemoryPool MemoryPool;
57+
58+
TStringProviderBackend()
59+
: MemoryPool(256)
60+
{}
61+
62+
class TMutableStringData {
63+
friend struct TStringProviderBackend;
64+
65+
private:
66+
char* Data_;
67+
size_t Size_ = 0;
68+
69+
explicit TMutableStringData(char* data, size_t size)
70+
: Data_(data)
71+
, Size_(size)
72+
{}
73+
74+
public:
75+
char *Data() const noexcept {
76+
return Data_;
77+
}
78+
79+
size_t Size() const noexcept {
80+
return Size_;
81+
}
82+
};
83+
84+
TMutableStringData NewString(ui32 size) const {
85+
return TMutableStringData(reinterpret_cast<char*>(MemoryPool.Allocate(size)), size);
86+
}
87+
};
88+
5589
TCell MakeCell(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
5690
const TTypeEnvironment& env, bool copy = true,
5791
i32 typmod = -1, TMaybe<TString>* error = {});
5892

93+
TCell MakeCell(NScheme::TTypeInfo type, const NUdf::TUnboxedValuePod& value,
94+
const TStringProviderBackend& env, bool copy = true,
95+
i32 typmod = -1, TMaybe<TString>* error = {});
96+
5997
void FillKeyTupleValue(const NUdf::TUnboxedValue& row, const TVector<ui32>& rowIndices,
6098
const TVector<NScheme::TTypeInfo>& rowTypes, TVector<TCell>& cells, const TTypeEnvironment& env);
6199

ydb/core/kqp/runtime/kqp_stream_lookup_worker.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,15 @@ class TKqpLookupRows : public TKqpStreamLookupWorker {
143143
virtual ~TKqpLookupRows() {}
144144

145145
void AddInputRow(NUdf::TUnboxedValue inputRow) final {
146+
NMiniKQL::TStringProviderBackend backend;
146147
std::vector<TCell> keyCells(LookupKeyColumns.size());
147148
for (size_t colId = 0; colId < LookupKeyColumns.size(); ++colId) {
148149
const auto* lookupKeyColumn = LookupKeyColumns[colId];
149150
YQL_ENSURE(lookupKeyColumn->KeyOrder < static_cast<i64>(keyCells.size()));
151+
// when making a cell we don't really need to make a copy of data, because
152+
// TOwnedCellVec will make its' own copy.
150153
keyCells[lookupKeyColumn->KeyOrder] = MakeCell(lookupKeyColumn->PType,
151-
inputRow.GetElement(colId), TypeEnv, /* copy */ true);
154+
inputRow.GetElement(colId), backend, /* copy */ false);
152155
}
153156

154157
if (keyCells.size() < KeyColumns.size()) {
@@ -425,13 +428,16 @@ class TKqpJoinRows : public TKqpStreamLookupWorker {
425428
void AddInputRow(NUdf::TUnboxedValue inputRow) final {
426429
auto joinKey = inputRow.GetElement(0);
427430
std::vector<TCell> joinKeyCells(LookupKeyColumns.size());
431+
NMiniKQL::TStringProviderBackend backend;
428432

429433
if (joinKey.HasValue()) {
430434
for (size_t colId = 0; colId < LookupKeyColumns.size(); ++colId) {
431435
const auto* joinKeyColumn = LookupKeyColumns[colId];
432436
YQL_ENSURE(joinKeyColumn->KeyOrder < static_cast<i64>(joinKeyCells.size()));
437+
// when making a cell we don't really need to make a copy of data, because
438+
// TOwnedCellVec will make its' own copy.
433439
joinKeyCells[joinKeyColumn->KeyOrder] = MakeCell(joinKeyColumn->PType,
434-
joinKey.GetElement(colId), TypeEnv, true);
440+
joinKey.GetElement(colId), backend, /* copy */ false);
435441
}
436442
}
437443

0 commit comments

Comments
 (0)