3
3
4
4
#include < ydb/library/yql/minikql/mkql_type_builder.h>
5
5
#include < ydb/library/yql/public/udf/arrow/block_reader.h>
6
+ #include < ydb/library/yql/public/udf/arrow/memory_pool.h>
6
7
#include < ydb/library/yql/utils/rope_over_buffer.h>
7
8
#include < ydb/library/yql/utils/yql_panic.h>
8
9
@@ -25,22 +26,35 @@ std::shared_ptr<arrow::Buffer> MakeEmptyBuffer() {
25
26
return std::make_shared<arrow::Buffer>(nullptr , 0 );
26
27
}
27
28
29
+ bool HasArrrowAlignment (const void * buf) {
30
+ return AlignUp (buf, NYql::NUdf::ArrowMemoryAlignment) == buf;
31
+ }
32
+
28
33
std::shared_ptr<arrow::Buffer> MakeZeroBuffer (size_t byteLen) {
34
+ using namespace NYql ::NUdf;
35
+ if (!byteLen) {
36
+ return MakeEmptyBuffer ();
37
+ }
38
+
29
39
constexpr size_t NullWordCount = (MaxBlockSizeInBytes + sizeof (ui64) - 1 ) / sizeof (ui64);
30
- static ui64 nulls[NullWordCount] = { 0 };
31
- if (byteLen <= sizeof (nulls)) {
32
- return std::make_shared<arrow::Buffer>(reinterpret_cast <const ui8*>(nulls), byteLen);
40
+ constexpr size_t ExtraAlignWords = (ArrowMemoryAlignment > sizeof (ui64)) ? (ArrowMemoryAlignment / sizeof (ui64) - 1 ) : 0 ;
41
+ static const ui64 nulls[NullWordCount + ExtraAlignWords] = { 0 };
42
+
43
+ // round all buffer length to 64 bytes
44
+ size_t capacity = AlignUp (byteLen, size_t (64 ));
45
+ if (capacity <= NullWordCount * sizeof (ui64)) {
46
+ return std::make_shared<arrow::Buffer>(AlignUp (reinterpret_cast <const ui8*>(nulls), ArrowMemoryAlignment), byteLen);
33
47
}
34
48
35
- size_t wordCount = (byteLen + sizeof (ui64) - 1 ) / sizeof (ui64 );
36
- std::shared_ptr<ui64[]> buf ( new ui64[wordCount] );
37
- std::fill (buf. get (), buf. get () + wordCount, 0 );
38
- return std::make_shared<TOwnedArrowBuffer>(TContiguousSpan{ reinterpret_cast < const char *>(buf. get ()), byteLen }, buf) ;
49
+ auto result = AllocateResizableBuffer (byteLen, GetYqlMemoryPool () );
50
+ ARROW_OK (result-> Resize (byteLen) );
51
+ std::memset (result-> mutable_data (), 0 , byteLen );
52
+ return result ;
39
53
}
40
54
41
55
std::shared_ptr<arrow::Buffer> MakeZeroBitmap (size_t bitCount) {
42
56
// align up 8 byte boundary
43
- size_t byteCount = (( bitCount + 63u ) & ~ size_t (63u )) >> 3 ;
57
+ size_t byteCount = AlignUp ( bitCount, size_t (64 )) >> 3 ;
44
58
return MakeZeroBuffer (byteCount);
45
59
}
46
60
@@ -57,7 +71,7 @@ void StoreNullsSizes(const arrow::ArrayData& data, const IBlockSerializer::TMeta
57
71
}
58
72
59
73
const ui64 desiredOffset = data.offset % 8 ;
60
- size_t nullBytes = ((( size_t )data.length + desiredOffset + 7 ) & ~ 7ull ) >> 3 ;
74
+ size_t nullBytes = AlignUp (( size_t )data.length + desiredOffset, size_t ( 8 ) ) >> 3 ;
61
75
metaSink (nullBytes);
62
76
}
63
77
@@ -72,7 +86,7 @@ void StoreNulls(const arrow::ArrayData& data, TRope& dst) {
72
86
return ;
73
87
}
74
88
const ui64 desiredOffset = data.offset % 8 ;
75
- size_t nullBytes = ((( size_t )data.length + desiredOffset + 7 ) & ~ 7ull ) >> 3 ;
89
+ size_t nullBytes = AlignUp (( size_t )data.length + desiredOffset, size_t ( 8 ) ) >> 3 ;
76
90
YQL_ENSURE (desiredOffset <= (size_t )data.offset );
77
91
YQL_ENSURE ((data.offset - desiredOffset) % 8 == 0 );
78
92
const char * nulls = data.GetValues <char >(0 , 0 ) + (data.offset - desiredOffset) / 8 ;
@@ -85,17 +99,26 @@ void LoadBufferSize(const IBlockDeserializer::TMetadataSource& metaSource, TMayb
85
99
}
86
100
87
101
std::shared_ptr<arrow::Buffer> LoadBuffer (TRope& source, TMaybe<ui64> size) {
102
+ using namespace NYql ::NUdf;
88
103
YQL_ENSURE (size.Defined (), " Buffer size is not loaded" );
89
104
if (!*size) {
90
- return std::make_shared<arrow::Buffer>( nullptr , 0 );
105
+ return MakeEmptyBuffer ( );
91
106
}
92
107
93
108
YQL_ENSURE (source.size () >= *size, " Premature end of data" );
94
109
auto owner = std::make_shared<TRope>(source.Begin (), source.Begin () + *size);
95
110
source.EraseFront (*size);
96
111
97
112
owner->Compact ();
98
- return std::make_shared<TOwnedArrowBuffer>(owner->GetContiguousSpan (), owner);
113
+ auto span = owner->GetContiguousSpan ();
114
+ if (HasArrrowAlignment (span.Data ())) {
115
+ return std::make_shared<TOwnedArrowBuffer>(span, owner);
116
+ }
117
+
118
+ auto result = AllocateResizableBuffer (span.Size (), NYql::NUdf::GetYqlMemoryPool ());
119
+ ARROW_OK (result->Resize ((int64_t )span.Size ()));
120
+ std::memcpy (result->mutable_data (), span.Data (), span.Size ());
121
+ return result;
99
122
}
100
123
101
124
std::shared_ptr<arrow::Buffer> LoadNullsBitmap (TRope& source, TMaybe<ui64> nullCount, TMaybe<ui64> bitmapSize) {
0 commit comments