Skip to content

Commit 6ad44ae

Browse files
authored
refactor: unify BinarySection classes to single MemorySegment model and use string_view to avoid copies (alibaba#196)
1 parent b542e57 commit 6ad44ae

85 files changed

Lines changed: 1121 additions & 1152 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

include/paimon/data/blob.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,10 @@ class PAIMON_EXPORT Blob {
9494
/// It automatically injects Paimon-specific metadata to identify the field as a BLOB.
9595
///
9696
/// @param field_name The name of the Arrow field.
97-
/// @param nullable Whether the field can contain null values (defaults to false).
9897
/// @param metadata A map of key-value metadata to be attached to the field.
9998
/// @return A result containing a unique pointer to the generated `ArrowSchema` or an error.
10099
static Result<std::unique_ptr<::ArrowSchema>> ArrowField(
101-
const std::string& field_name, bool nullable = false,
102-
std::unordered_map<std::string, std::string> metadata = {});
100+
const std::string& field_name, std::unordered_map<std::string, std::string> metadata = {});
103101

104102
private:
105103
class Impl;

src/paimon/common/data/abstract_binary_writer.cpp

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
#include "paimon/common/data/abstract_binary_writer.h"
1818

19-
#include <algorithm>
2019
#include <cassert>
2120
#include <memory>
2221
#include <optional>
@@ -48,11 +47,11 @@ void AbstractBinaryWriter::WriteString(int32_t pos, const BinaryString& input) {
4847
int32_t len = input.GetSizeInBytes();
4948
if (len <= BinarySection::MAX_FIX_PART_DATA_SIZE) {
5049
auto bytes = Bytes::AllocateBytes(len, pool_);
51-
MemorySegmentUtils::CopyToBytes(input.GetSegments(), input.GetOffset(), bytes.get(), 0,
50+
MemorySegmentUtils::CopyToBytes({input.GetSegment()}, input.GetOffset(), bytes.get(), 0,
5251
len);
5352
WriteBytesToFixLenPart(&segment_, GetFieldOffset(pos), *bytes, len);
5453
} else {
55-
WriteSegmentsToVarLenPart(pos, input.GetSegments(), input.GetOffset(), len);
54+
WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(), len);
5655
}
5756
}
5857

@@ -75,20 +74,19 @@ void AbstractBinaryWriter::WriteStringView(int32_t pos, const std::string_view&
7574
}
7675

7776
void AbstractBinaryWriter::WriteRow(int32_t pos, const BinaryRow& input) {
78-
return WriteSegmentsToVarLenPart(pos, input.GetSegments(), input.GetOffset(),
79-
input.GetSizeInBytes());
77+
return WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(),
78+
input.GetSizeInBytes());
8079
}
8180

8281
void AbstractBinaryWriter::WriteArray(int32_t pos, const BinaryArray& input) {
83-
return WriteSegmentsToVarLenPart(pos, input.GetSegments(), input.GetOffset(),
84-
input.GetSizeInBytes());
82+
return WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(),
83+
input.GetSizeInBytes());
8584
}
8685

8786
void AbstractBinaryWriter::WriteMap(int32_t pos, const BinaryMap& input) {
88-
return WriteSegmentsToVarLenPart(pos, input.GetSegments(), input.GetOffset(),
89-
input.GetSizeInBytes());
87+
return WriteSegmentToVarLenPart(pos, input.GetSegment(), input.GetOffset(),
88+
input.GetSizeInBytes());
9089
}
91-
9290
void AbstractBinaryWriter::WriteDecimal(int32_t pos, const std::optional<Decimal>& value,
9391
int32_t precision) {
9492
assert(value == std::nullopt || precision == value.value().Precision());
@@ -152,44 +150,19 @@ void AbstractBinaryWriter::EnsureCapacity(int32_t needed_size) {
152150
}
153151
}
154152

155-
void AbstractBinaryWriter::WriteSegmentsToVarLenPart(int32_t pos,
156-
const std::vector<MemorySegment>& segments,
157-
int32_t offset, int32_t size) {
153+
void AbstractBinaryWriter::WriteSegmentToVarLenPart(int32_t pos, const MemorySegment& segment,
154+
int32_t offset, int32_t size) {
158155
const int32_t rounded_size = RoundNumberOfBytesToNearestWord(size);
159156
// grow the global buffer before writing data.
160157
EnsureCapacity(rounded_size);
161158
ZeroOutPaddingBytes(size);
162159

163-
if (segments.size() == 1) {
164-
segments[0].CopyTo(offset, &segment_, cursor_, size);
165-
} else {
166-
WriteMultiSegmentsToVarLenPart(segments, offset, size);
167-
}
160+
segment.CopyTo(offset, &segment_, cursor_, size);
168161
SetOffsetAndSize(pos, cursor_, size);
169162
// move the cursor forward.
170163
cursor_ += rounded_size;
171164
}
172165

173-
void AbstractBinaryWriter::WriteMultiSegmentsToVarLenPart(
174-
const std::vector<MemorySegment>& segments, int32_t offset, int32_t size) {
175-
// Write the bytes to the variable length portion.
176-
int32_t need_copy = size;
177-
int32_t from_offset = offset;
178-
int32_t to_offset = cursor_;
179-
for (const auto& source_segment : segments) {
180-
int32_t remain = source_segment.Size() - from_offset;
181-
if (remain > 0) {
182-
int32_t copy_size = std::min(remain, need_copy);
183-
source_segment.CopyTo(from_offset, &segment_, to_offset, copy_size);
184-
need_copy -= copy_size;
185-
to_offset += copy_size;
186-
from_offset = 0;
187-
} else {
188-
from_offset -= source_segment.Size();
189-
}
190-
}
191-
}
192-
193166
template <typename T>
194167
void AbstractBinaryWriter::WriteBytesToVarLenPart(int32_t pos, const T& bytes, int32_t len) {
195168
const int32_t rounded_size = RoundNumberOfBytesToNearestWord(len);

src/paimon/common/data/abstract_binary_writer.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include <cstdint>
2020
#include <optional>
2121
#include <string_view>
22-
#include <vector>
2322

2423
#include "paimon/common/data/binary_writer.h"
2524
#include "paimon/common/memory/memory_segment.h"
@@ -56,7 +55,7 @@ class AbstractBinaryWriter : public BinaryWriter {
5655

5756
void WriteStringView(int32_t pos, const std::string_view& view) override;
5857

59-
const MemorySegment& GetSegments() const {
58+
const MemorySegment& GetSegment() const {
6059
return segment_;
6160
}
6261

@@ -90,10 +89,8 @@ class AbstractBinaryWriter : public BinaryWriter {
9089
static void WriteBytesToFixLenPart(MemorySegment* segment, int32_t field_offset, const T& bytes,
9190
int32_t len);
9291

93-
void WriteSegmentsToVarLenPart(int32_t pos, const std::vector<MemorySegment>& segments,
94-
int32_t offset, int32_t size);
95-
void WriteMultiSegmentsToVarLenPart(const std::vector<MemorySegment>& segments, int32_t offset,
96-
int32_t size);
92+
void WriteSegmentToVarLenPart(int32_t pos, const MemorySegment& segment, int32_t offset,
93+
int32_t size);
9794

9895
protected:
9996
int32_t cursor_ = 0;

src/paimon/common/data/binary_array.cpp

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,28 @@ int32_t BinaryArray::GetElementOffset(int32_t ordinal, int32_t element_size) con
4040
}
4141

4242
void BinaryArray::PointTo(const MemorySegment& segment, int32_t offset, int32_t size_in_bytes) {
43-
std::vector<MemorySegment> segments = {segment};
44-
PointTo(segments, offset, size_in_bytes);
45-
}
46-
47-
void BinaryArray::PointTo(const std::vector<MemorySegment>& segments, int32_t offset,
48-
int32_t size_in_bytes) {
49-
// Read the number of elements from the first 4 bytes.
50-
auto size = MemorySegmentUtils::GetValue<int32_t>(segments, offset);
43+
auto size = MemorySegmentUtils::GetValue<int32_t>({segment}, offset);
5144
assert(size >= 0);
52-
5345
size_ = size;
54-
segments_ = segments;
46+
segment_ = segment;
5547
offset_ = offset;
5648
size_in_bytes_ = size_in_bytes;
5749
element_offset_ = offset_ + CalculateHeaderInBytes(size_);
5850
}
5951

6052
bool BinaryArray::IsNullAt(int32_t pos) const {
6153
AssertIndexIsValid(pos);
62-
return MemorySegmentUtils::BitGet(segments_, offset_ + 4, pos);
54+
return MemorySegmentUtils::BitGet({segment_}, offset_ + 4, pos);
6355
}
6456

6557
int64_t BinaryArray::GetLong(int32_t pos) const {
6658
AssertIndexIsValid(pos);
67-
return MemorySegmentUtils::GetValue<int64_t>(segments_, GetElementOffset(pos, 8));
59+
return MemorySegmentUtils::GetValue<int64_t>({segment_}, GetElementOffset(pos, 8));
6860
}
6961

7062
int32_t BinaryArray::GetInt(int32_t pos) const {
7163
AssertIndexIsValid(pos);
72-
return MemorySegmentUtils::GetValue<int32_t>(segments_, GetElementOffset(pos, 4));
64+
return MemorySegmentUtils::GetValue<int32_t>({segment_}, GetElementOffset(pos, 4));
7365
}
7466
int32_t BinaryArray::GetDate(int32_t pos) const {
7567
return GetInt(pos);
@@ -78,90 +70,96 @@ int32_t BinaryArray::GetDate(int32_t pos) const {
7870
BinaryString BinaryArray::GetString(int32_t pos) const {
7971
AssertIndexIsValid(pos);
8072
int32_t field_offset = GetElementOffset(pos, 8);
81-
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>(segments_, field_offset);
82-
return BinaryDataReadUtils::ReadBinaryString(segments_, offset_, field_offset, offset_and_size);
73+
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>({segment_}, field_offset);
74+
return BinaryDataReadUtils::ReadBinaryString(segment_, offset_, field_offset, offset_and_size);
75+
}
76+
77+
std::string_view BinaryArray::GetStringView(int32_t pos) const {
78+
BinaryString binary_string = GetString(pos);
79+
return binary_string.GetStringView();
8380
}
8481

8582
Decimal BinaryArray::GetDecimal(int32_t pos, int32_t precision, int32_t scale) const {
8683
AssertIndexIsValid(pos);
8784
if (Decimal::IsCompact(precision)) {
8885
return Decimal::FromUnscaledLong(
89-
MemorySegmentUtils::GetValue<int64_t>(segments_, GetElementOffset(pos, 8)), precision,
86+
MemorySegmentUtils::GetValue<int64_t>({segment_}, GetElementOffset(pos, 8)), precision,
9087
scale);
9188
}
9289

9390
int32_t field_offset = GetElementOffset(pos, 8);
94-
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>(segments_, field_offset);
95-
return BinaryDataReadUtils::ReadDecimal(segments_, offset_, offset_and_size, precision, scale);
91+
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>({segment_}, field_offset);
92+
return BinaryDataReadUtils::ReadDecimal(segment_, offset_, offset_and_size, precision, scale);
9693
}
9794

9895
Timestamp BinaryArray::GetTimestamp(int32_t pos, int32_t precision) const {
9996
AssertIndexIsValid(pos);
10097

10198
if (Timestamp::IsCompact(precision)) {
10299
return Timestamp::FromEpochMillis(
103-
MemorySegmentUtils::GetValue<int64_t>(segments_, GetElementOffset(pos, 8)));
100+
MemorySegmentUtils::GetValue<int64_t>({segment_}, GetElementOffset(pos, 8)));
104101
}
105102

106103
int32_t field_offset = GetElementOffset(pos, 8);
107104
const auto offset_and_nano_of_milli =
108-
MemorySegmentUtils::GetValue<int64_t>(segments_, field_offset);
109-
return BinaryDataReadUtils::ReadTimestampData(segments_, offset_, offset_and_nano_of_milli);
105+
MemorySegmentUtils::GetValue<int64_t>({segment_}, field_offset);
106+
return BinaryDataReadUtils::ReadTimestampData(segment_, offset_, offset_and_nano_of_milli);
110107
}
111108

112109
std::shared_ptr<Bytes> BinaryArray::GetBinary(int32_t pos) const {
113110
AssertIndexIsValid(pos);
114111
int32_t field_offset = GetElementOffset(pos, 8);
115-
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>(segments_, field_offset);
116-
return BinarySection::ReadBinary(segments_, offset_, field_offset, offset_and_size,
112+
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>({segment_}, field_offset);
113+
return BinarySection::ReadBinary(segment_, offset_, field_offset, offset_and_size,
117114
GetDefaultPool().get());
118115
}
119116

120117
std::shared_ptr<InternalArray> BinaryArray::GetArray(int32_t pos) const {
121118
AssertIndexIsValid(pos);
122-
return BinaryDataReadUtils::ReadArrayData(segments_, offset_, GetLong(pos));
119+
return BinaryDataReadUtils::ReadArrayData(segment_, offset_, GetLong(pos));
123120
}
124121

125122
std::shared_ptr<InternalMap> BinaryArray::GetMap(int32_t pos) const {
126123
AssertIndexIsValid(pos);
127-
return BinaryDataReadUtils::ReadMapData(segments_, offset_, GetLong(pos));
124+
return BinaryDataReadUtils::ReadMapData(segment_, offset_, GetLong(pos));
128125
}
129126

130127
std::shared_ptr<InternalRow> BinaryArray::GetRow(int32_t pos, int32_t num_fields) const {
131128
AssertIndexIsValid(pos);
132129
int32_t field_offset = GetElementOffset(pos, 8);
133-
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>(segments_, field_offset);
134-
return BinaryDataReadUtils::ReadRowData(segments_, num_fields, offset_, offset_and_size);
130+
const auto offset_and_size = MemorySegmentUtils::GetValue<int64_t>({segment_}, field_offset);
131+
return BinaryDataReadUtils::ReadRowData(segment_, num_fields, offset_, offset_and_size);
135132
}
136133

137134
bool BinaryArray::GetBoolean(int32_t pos) const {
138135
AssertIndexIsValid(pos);
139-
return MemorySegmentUtils::GetValue<bool>(segments_, GetElementOffset(pos, 1));
136+
return MemorySegmentUtils::GetValue<bool>({segment_}, GetElementOffset(pos, 1));
140137
}
141138

142139
char BinaryArray::GetByte(int32_t pos) const {
143140
AssertIndexIsValid(pos);
144-
return MemorySegmentUtils::GetValue<char>(segments_, GetElementOffset(pos, 1));
141+
return MemorySegmentUtils::GetValue<char>({segment_}, GetElementOffset(pos, 1));
145142
}
146143

147144
int16_t BinaryArray::GetShort(int32_t pos) const {
148145
AssertIndexIsValid(pos);
149-
return MemorySegmentUtils::GetValue<int16_t>(segments_, GetElementOffset(pos, sizeof(int16_t)));
146+
return MemorySegmentUtils::GetValue<int16_t>({segment_},
147+
GetElementOffset(pos, sizeof(int16_t)));
150148
}
151149

152150
float BinaryArray::GetFloat(int32_t pos) const {
153151
AssertIndexIsValid(pos);
154-
return MemorySegmentUtils::GetValue<float>(segments_, GetElementOffset(pos, sizeof(float)));
152+
return MemorySegmentUtils::GetValue<float>({segment_}, GetElementOffset(pos, sizeof(float)));
155153
}
156154

157155
double BinaryArray::GetDouble(int32_t pos) const {
158156
AssertIndexIsValid(pos);
159-
return MemorySegmentUtils::GetValue<double>(segments_, GetElementOffset(pos, sizeof(double)));
157+
return MemorySegmentUtils::GetValue<double>({segment_}, GetElementOffset(pos, sizeof(double)));
160158
}
161159

162160
bool BinaryArray::AnyNull() const {
163161
for (int32_t i = offset_ + 4; i < element_offset_; i += 4) {
164-
if (MemorySegmentUtils::GetValue<int32_t>(segments_, i) != 0) {
162+
if (MemorySegmentUtils::GetValue<int32_t>({segment_}, i) != 0) {
165163
return true;
166164
}
167165
}
@@ -172,7 +170,7 @@ Result<std::vector<char>> BinaryArray::ToBooleanArray() const {
172170
PAIMON_RETURN_NOT_OK(CheckNoNull());
173171
std::vector<char> values;
174172
values.resize(size_);
175-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
173+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
176174
const_cast<void*>(static_cast<const void*>(values.data())),
177175
size_);
178176
return values;
@@ -182,7 +180,7 @@ Result<std::vector<char>> BinaryArray::ToByteArray() const {
182180
PAIMON_RETURN_NOT_OK(CheckNoNull());
183181
std::vector<char> values;
184182
values.resize(size_);
185-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
183+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
186184
const_cast<void*>(static_cast<const void*>(values.data())),
187185
size_);
188186
return values;
@@ -192,7 +190,7 @@ Result<std::vector<int16_t>> BinaryArray::ToShortArray() const {
192190
PAIMON_RETURN_NOT_OK(CheckNoNull());
193191
std::vector<int16_t> values;
194192
values.resize(size_);
195-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
193+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
196194
const_cast<void*>(static_cast<const void*>(values.data())),
197195
size_ * sizeof(int16_t));
198196
return values;
@@ -202,7 +200,7 @@ Result<std::vector<int32_t>> BinaryArray::ToIntArray() const {
202200
PAIMON_RETURN_NOT_OK(CheckNoNull());
203201
std::vector<int32_t> values;
204202
values.resize(size_);
205-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
203+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
206204
const_cast<void*>(static_cast<const void*>(values.data())),
207205
size_ * sizeof(int32_t));
208206
return values;
@@ -212,7 +210,7 @@ Result<std::vector<int64_t>> BinaryArray::ToLongArray() const {
212210
PAIMON_RETURN_NOT_OK(CheckNoNull());
213211
std::vector<int64_t> values;
214212
values.resize(size_);
215-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
213+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
216214
const_cast<void*>(static_cast<const void*>(values.data())),
217215
size_ * sizeof(int64_t));
218216
return values;
@@ -222,7 +220,7 @@ Result<std::vector<float>> BinaryArray::ToFloatArray() const {
222220
PAIMON_RETURN_NOT_OK(CheckNoNull());
223221
std::vector<float> values;
224222
values.resize(size_);
225-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
223+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
226224
const_cast<void*>(static_cast<const void*>(values.data())),
227225
size_ * sizeof(float));
228226
return values;
@@ -232,7 +230,7 @@ Result<std::vector<double>> BinaryArray::ToDoubleArray() const {
232230
PAIMON_RETURN_NOT_OK(CheckNoNull());
233231
std::vector<double> values;
234232
values.resize(size_);
235-
MemorySegmentUtils::CopyToUnsafe(segments_, element_offset_,
233+
MemorySegmentUtils::CopyToUnsafe({segment_}, element_offset_,
236234
const_cast<void*>(static_cast<const void*>(values.data())),
237235
size_ * sizeof(double));
238236
return values;
@@ -246,7 +244,7 @@ BinaryArray BinaryArray::Copy(MemoryPool* pool) const {
246244

247245
void BinaryArray::Copy(BinaryArray* reuse, MemoryPool* pool) const {
248246
std::shared_ptr<Bytes> bytes =
249-
MemorySegmentUtils::CopyToBytes(segments_, offset_, size_in_bytes_, pool);
247+
MemorySegmentUtils::CopyToBytes({segment_}, offset_, size_in_bytes_, pool);
250248
reuse->PointTo(MemorySegment::Wrap(bytes), 0, size_in_bytes_);
251249
}
252250

0 commit comments

Comments
 (0)