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