Skip to content

Commit a4fef57

Browse files
authored
Merge branch 'main' into refactor/write-buffer
2 parents a47d52d + c415846 commit a4fef57

47 files changed

Lines changed: 747 additions & 734 deletions

Some content is hidden

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

src/paimon/common/data/generic_row.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ class GenericRow : public InternalRow {
104104
}
105105

106106
void AddDataHolder(std::unique_ptr<InternalRow>&& holder) {
107-
holders_.push_back(std::move(holder));
107+
row_holder_.push_back(std::move(holder));
108+
}
109+
110+
void AddDataHolder(const std::shared_ptr<Bytes>& bytes) {
111+
bytes_holder_ = bytes;
108112
}
109113

110114
bool GetBoolean(int32_t pos) const override {
@@ -218,8 +222,9 @@ class GenericRow : public InternalRow {
218222
/// The array to store the actual internal format values.
219223
std::vector<VariantType> fields_;
220224
/// As GenericRow only holds string view for string data to avoid deep copy, original data must
221-
/// be held in holders_
222-
std::vector<std::unique_ptr<InternalRow>> holders_;
225+
/// be held in row holders_ or bytes holder
226+
std::vector<std::unique_ptr<InternalRow>> row_holder_;
227+
std::shared_ptr<Bytes> bytes_holder_;
223228
/// The kind of change that a row describes in a changelog.
224229
const RowKind* kind_;
225230
};

src/paimon/common/data/serializer/row_compacted_serializer.cpp

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,24 +42,102 @@ Result<std::unique_ptr<RowCompactedSerializer>> RowCompactedSerializer::Create(
4242
schema, std::move(getters), std::move(writers), std::move(readers), pool));
4343
}
4444

45+
Result<int32_t> RowCompactedSerializer::CompareField(const FieldInfo& field_info,
46+
RowReader* reader1, RowReader* reader2) {
47+
auto type = field_info.type_id;
48+
switch (type) {
49+
case arrow::Type::type::BOOL: {
50+
auto val1 = reader1->ReadValue<bool>();
51+
auto val2 = reader2->ReadValue<bool>();
52+
return val1 == val2 ? 0 : (val1 < val2 ? -1 : 1);
53+
}
54+
case arrow::Type::type::INT8: {
55+
auto val1 = reader1->ReadValue<char>();
56+
auto val2 = reader2->ReadValue<char>();
57+
return val1 == val2 ? 0 : (val1 < val2 ? -1 : 1);
58+
}
59+
case arrow::Type::type::INT16: {
60+
auto val1 = reader1->ReadValue<int16_t>();
61+
auto val2 = reader2->ReadValue<int16_t>();
62+
return val1 == val2 ? 0 : (val1 < val2 ? -1 : 1);
63+
}
64+
case arrow::Type::type::INT32:
65+
case arrow::Type::type::DATE32: {
66+
auto val1 = reader1->ReadValue<int32_t>();
67+
auto val2 = reader2->ReadValue<int32_t>();
68+
return val1 == val2 ? 0 : (val1 < val2 ? -1 : 1);
69+
}
70+
case arrow::Type::type::INT64: {
71+
auto val1 = reader1->ReadValue<int64_t>();
72+
auto val2 = reader2->ReadValue<int64_t>();
73+
return val1 == val2 ? 0 : (val1 < val2 ? -1 : 1);
74+
}
75+
case arrow::Type::type::FLOAT: {
76+
auto val1 = reader1->ReadValue<float>();
77+
auto val2 = reader2->ReadValue<float>();
78+
return FieldsComparator::CompareFloatingPoint(val1, val2);
79+
}
80+
case arrow::Type::type::DOUBLE: {
81+
auto val1 = reader1->ReadValue<double>();
82+
auto val2 = reader2->ReadValue<double>();
83+
return FieldsComparator::CompareFloatingPoint(val1, val2);
84+
}
85+
case arrow::Type::type::STRING:
86+
case arrow::Type::type::BINARY: {
87+
PAIMON_ASSIGN_OR_RAISE(std::string_view val1, reader1->ReadStringView());
88+
PAIMON_ASSIGN_OR_RAISE(std::string_view val2, reader2->ReadStringView());
89+
int32_t cmp = val1.compare(val2);
90+
return cmp == 0 ? 0 : (cmp > 0 ? 1 : -1);
91+
}
92+
case arrow::Type::type::TIMESTAMP: {
93+
PAIMON_ASSIGN_OR_RAISE(Timestamp val1, reader1->ReadTimestamp(field_info.precision));
94+
PAIMON_ASSIGN_OR_RAISE(Timestamp val2, reader2->ReadTimestamp(field_info.precision));
95+
return val1 == val2 ? 0 : (val1 < val2 ? -1 : 1);
96+
}
97+
case arrow::Type::type::DECIMAL: {
98+
PAIMON_ASSIGN_OR_RAISE(Decimal val1,
99+
reader1->ReadDecimal(field_info.precision, field_info.scale));
100+
PAIMON_ASSIGN_OR_RAISE(Decimal val2,
101+
reader2->ReadDecimal(field_info.precision, field_info.scale));
102+
int32_t cmp = val1.CompareTo(val2);
103+
return cmp == 0 ? 0 : (cmp > 0 ? 1 : -1);
104+
}
105+
default:
106+
return Status::NotImplemented(
107+
fmt::format("Do not support comparing type {} in CompareField",
108+
static_cast<int32_t>(field_info.type_id)));
109+
}
110+
}
111+
45112
Result<MemorySlice::SliceComparator> RowCompactedSerializer::CreateSliceComparator(
46113
const std::shared_ptr<arrow::Schema>& schema, const std::shared_ptr<MemoryPool>& pool) {
47114
int32_t bit_set_in_bytes = RowCompactedSerializer::CalculateBitSetInBytes(schema->num_fields());
48115
auto row_reader1 = std::make_shared<RowReader>(bit_set_in_bytes, pool);
49116
auto row_reader2 = std::make_shared<RowReader>(bit_set_in_bytes, pool);
50-
std::vector<RowCompactedSerializer::FieldReader> readers(schema->num_fields());
51-
std::vector<FieldsComparator::VariantComparatorFunc> comparators(schema->num_fields());
117+
118+
std::vector<FieldInfo> field_infos(schema->num_fields());
52119
for (int32_t i = 0; i < schema->num_fields(); i++) {
53120
auto field_type = schema->field(i)->type();
54-
PAIMON_ASSIGN_OR_RAISE(readers[i], CreateFieldReader(field_type, pool));
55-
PAIMON_ASSIGN_OR_RAISE(comparators[i], FieldsComparator::CompareVariant(i, field_type));
121+
field_infos[i].type_id = field_type->id();
122+
if (field_type->id() == arrow::Type::type::TIMESTAMP) {
123+
auto timestamp_type =
124+
arrow::internal::checked_pointer_cast<arrow::TimestampType>(field_type);
125+
assert(timestamp_type);
126+
field_infos[i].precision = DateTimeUtils::GetPrecisionFromType(timestamp_type);
127+
} else if (field_type->id() == arrow::Type::type::DECIMAL) {
128+
auto decimal_type =
129+
arrow::internal::checked_pointer_cast<arrow::Decimal128Type>(field_type);
130+
assert(decimal_type);
131+
field_infos[i].precision = decimal_type->precision();
132+
field_infos[i].scale = decimal_type->scale();
133+
}
56134
}
57-
auto comparator = [row_reader1, row_reader2, readers, comparators](
58-
const std::shared_ptr<MemorySlice>& slice1,
59-
const std::shared_ptr<MemorySlice>& slice2) -> Result<int32_t> {
60-
row_reader1->PointTo(slice1->GetSegment(), slice1->Offset());
61-
row_reader2->PointTo(slice2->GetSegment(), slice2->Offset());
62-
for (int32_t i = 0; i < static_cast<int32_t>(readers.size()); i++) {
135+
136+
auto comparator = [row_reader1, row_reader2, field_infos](
137+
const MemorySlice& slice1, const MemorySlice& slice2) -> Result<int32_t> {
138+
row_reader1->PointTo(slice1.GetSegment(), slice1.Offset());
139+
row_reader2->PointTo(slice2.GetSegment(), slice2.Offset());
140+
for (int32_t i = 0; i < static_cast<int32_t>(field_infos.size()); i++) {
63141
bool is_null1 = row_reader1->IsNullAt(i);
64142
bool is_null2 = row_reader2->IsNullAt(i);
65143
if (!is_null1 || !is_null2) {
@@ -68,9 +146,9 @@ Result<MemorySlice::SliceComparator> RowCompactedSerializer::CreateSliceComparat
68146
} else if (is_null2) {
69147
return 1;
70148
} else {
71-
PAIMON_ASSIGN_OR_RAISE(VariantType field1, readers[i](i, row_reader1.get()));
72-
PAIMON_ASSIGN_OR_RAISE(VariantType field2, readers[i](i, row_reader2.get()));
73-
int32_t comp = comparators[i](field1, field2);
149+
PAIMON_ASSIGN_OR_RAISE(
150+
int32_t comp,
151+
CompareField(field_infos[i], row_reader1.get(), row_reader2.get()));
74152
if (comp != 0) {
75153
return comp;
76154
}
@@ -79,8 +157,7 @@ Result<MemorySlice::SliceComparator> RowCompactedSerializer::CreateSliceComparat
79157
}
80158
return 0;
81159
};
82-
return std::function<Result<int32_t>(const std::shared_ptr<MemorySlice>&,
83-
const std::shared_ptr<MemorySlice>&)>(comparator);
160+
return std::function<Result<int32_t>(const MemorySlice&, const MemorySlice&)>(comparator);
84161
}
85162

86163
Result<std::shared_ptr<Bytes>> RowCompactedSerializer::SerializeToBytes(const InternalRow& row) {
@@ -110,6 +187,7 @@ Result<std::unique_ptr<InternalRow>> RowCompactedSerializer::Deserialize(
110187
PAIMON_ASSIGN_OR_RAISE(VariantType field, readers_[i](i, row_reader_.get()));
111188
row->SetField(i, field);
112189
}
190+
row->AddDataHolder(bytes);
113191
return row;
114192
}
115193

@@ -175,7 +253,7 @@ Result<RowCompactedSerializer::FieldReader> RowCompactedSerializer::CreateFieldR
175253
}
176254
case arrow::Type::type::STRING: {
177255
field_reader = [](int32_t pos, RowReader* reader) -> Result<VariantType> {
178-
PAIMON_ASSIGN_OR_RAISE(VariantType value, reader->ReadString());
256+
PAIMON_ASSIGN_OR_RAISE(VariantType value, reader->ReadStringView());
179257
return value;
180258
};
181259
break;
@@ -497,9 +575,9 @@ Result<const RowKind*> RowCompactedSerializer::RowReader::ReadRowKind() const {
497575
return RowKind::FromByteValue(static_cast<int8_t>(b));
498576
}
499577

500-
Result<BinaryString> RowCompactedSerializer::RowReader::ReadString() {
578+
Result<std::string_view> RowCompactedSerializer::RowReader::ReadStringView() {
501579
PAIMON_ASSIGN_OR_RAISE(int32_t length, ReadUnsignedInt());
502-
BinaryString str = BinaryString::FromAddress(segment_, position_, length);
580+
std::string_view str(segment_.GetArray()->data() + position_, length);
503581
position_ += length;
504582
return str;
505583
}

src/paimon/common/data/serializer/row_compacted_serializer.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
#pragma once
1818
#include <functional>
1919

20+
#include "arrow/api.h"
2021
#include "paimon/common/data/binary_row.h"
2122
#include "paimon/common/data/binary_writer.h"
2223
#include "paimon/common/memory/memory_segment.h"
2324
#include "paimon/common/memory/memory_segment_utils.h"
2425
#include "paimon/common/memory/memory_slice.h"
2526
#include "paimon/common/utils/var_length_int_utils.h"
2627
namespace paimon {
28+
2729
class RowCompactedSerializer {
2830
public:
2931
static Result<std::unique_ptr<RowCompactedSerializer>> Create(
@@ -41,6 +43,12 @@ class RowCompactedSerializer {
4143
const std::shared_ptr<arrow::Schema>& schema, const std::shared_ptr<MemoryPool>& pool);
4244

4345
private:
46+
struct FieldInfo {
47+
arrow::Type::type type_id;
48+
int32_t precision = -1;
49+
int32_t scale = -1;
50+
};
51+
4452
class RowWriter {
4553
public:
4654
RowWriter(int32_t header_size_in_bytes, const std::shared_ptr<MemoryPool>& pool);
@@ -134,7 +142,7 @@ class RowCompactedSerializer {
134142
return value;
135143
}
136144

137-
Result<BinaryString> ReadString();
145+
Result<std::string_view> ReadStringView();
138146

139147
Result<std::shared_ptr<Bytes>> ReadBinary();
140148

@@ -161,6 +169,10 @@ class RowCompactedSerializer {
161169
int32_t position_ = 0;
162170
};
163171

172+
/// Read and compare a single field from two RowReaders.
173+
static Result<int32_t> CompareField(const FieldInfo& field_info, RowReader* reader1,
174+
RowReader* reader2);
175+
164176
using FieldWriter = std::function<Status(int32_t, const VariantType&, RowWriter*)>;
165177
using FieldReader = std::function<Result<VariantType>(int32_t, RowReader*)>;
166178

@@ -184,4 +196,5 @@ class RowCompactedSerializer {
184196
std::unique_ptr<RowWriter> row_writer_;
185197
std::unique_ptr<RowReader> row_reader_;
186198
};
199+
187200
} // namespace paimon

src/paimon/common/data/serializer/row_compacted_serializer_test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ TEST(RowCompactedSerializerTest, TestSimple) {
7575
ASSERT_EQ(de_row->GetLong(4), 4294967295l);
7676
ASSERT_EQ(de_row->GetFloat(5), 0.5);
7777
ASSERT_EQ(de_row->GetDouble(6), 1.141);
78-
ASSERT_EQ(de_row->GetString(7), BinaryString::FromString("20250327", pool.get()));
78+
ASSERT_EQ(de_row->GetStringView(7), "20250327");
7979
auto f9_bytes = std::make_shared<Bytes>("banana", pool.get());
8080
ASSERT_EQ(*de_row->GetBinary(8), *f9_bytes);
8181
ASSERT_EQ(de_row->GetDate(9), 2026);
@@ -450,7 +450,7 @@ TEST(RowCompactedSerializerTest, TestNestedNullWithTimestampAndDecimal2) {
450450
ASSERT_EQ(row->GetFieldCount(), 2);
451451
auto inner_row = row->GetRow(0, 3);
452452
ASSERT_EQ(inner_row->GetFieldCount(), 3);
453-
ASSERT_EQ(row->GetString(1).ToString(), "Alice");
453+
ASSERT_EQ(row->GetStringView(1), "Alice");
454454

455455
// test compatibility
456456
std::vector<uint8_t> java_bytes = {
@@ -485,7 +485,7 @@ TEST(RowCompactedSerializerTest, TestNestedNullWithTimestampAndDecimal2) {
485485
ASSERT_EQ(row->GetFieldCount(), 2);
486486
auto inner_row = row->GetRow(0, 3);
487487
ASSERT_EQ(inner_row->GetFieldCount(), 3);
488-
ASSERT_EQ(row->GetString(1).ToString(), "Bob");
488+
ASSERT_EQ(row->GetStringView(1), "Bob");
489489

490490
// test compatibility
491491
std::vector<uint8_t> java_bytes = {

src/paimon/common/io/cache/cache.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void NoCache::InvalidateAll() {
3535
// do nothing
3636
}
3737

38-
std::unordered_map<std::shared_ptr<CacheKey>, std::shared_ptr<CacheValue>> NoCache::AsMap() {
38+
CacheKeyMap NoCache::AsMap() {
3939
return {};
4040
}
4141

src/paimon/common/io/cache/cache.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Cache {
4242

4343
virtual void InvalidateAll() = 0;
4444

45-
virtual std::unordered_map<std::shared_ptr<CacheKey>, std::shared_ptr<CacheValue>> AsMap() = 0;
45+
virtual CacheKeyMap AsMap() = 0;
4646
};
4747

4848
class NoCache : public Cache {
@@ -55,7 +55,7 @@ class NoCache : public Cache {
5555
const std::shared_ptr<CacheValue>& value) override;
5656
void Invalidate(const std::shared_ptr<CacheKey>& key) override;
5757
void InvalidateAll() override;
58-
std::unordered_map<std::shared_ptr<CacheKey>, std::shared_ptr<CacheValue>> AsMap() override;
58+
CacheKeyMap AsMap() override;
5959
};
6060

6161
class CacheValue {

src/paimon/common/io/cache/cache_key.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,13 @@ int32_t PositionCacheKey::Length() const {
3535
return length_;
3636
}
3737

38-
bool PositionCacheKey::operator==(const PositionCacheKey& other) const {
39-
return file_path_ == other.file_path_ && position_ == other.position_ &&
40-
41-
length_ == other.length_ && is_index_ == other.is_index_;
38+
bool PositionCacheKey::Equals(const CacheKey& other) const {
39+
const auto* rhs = dynamic_cast<const PositionCacheKey*>(&other);
40+
if (!rhs) {
41+
return false;
42+
}
43+
return file_path_ == rhs->file_path_ && position_ == rhs->position_ &&
44+
length_ == rhs->length_ && is_index_ == rhs->is_index_;
4245
}
4346

4447
size_t PositionCacheKey::HashCode() const {

src/paimon/common/io/cache/cache_key.h

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616

1717
#pragma once
1818
#include <cstdint>
19-
#include <functional>
2019
#include <memory>
2120
#include <string>
22-
23-
#include "paimon/status.h"
21+
#include <unordered_map>
2422

2523
namespace paimon {
2624

25+
class CacheValue;
26+
2727
class CacheKey {
2828
public:
2929
static std::shared_ptr<CacheKey> ForPosition(const std::string& file_path, int64_t position,
@@ -33,6 +33,8 @@ class CacheKey {
3333
virtual ~CacheKey() = default;
3434

3535
virtual bool IsIndex() const = 0;
36+
virtual size_t HashCode() const = 0;
37+
virtual bool Equals(const CacheKey& other) const = 0;
3638
};
3739

3840
class PositionCacheKey : public CacheKey {
@@ -41,13 +43,11 @@ class PositionCacheKey : public CacheKey {
4143
: file_path_(file_path), position_(position), length_(length), is_index_(is_index) {}
4244

4345
bool IsIndex() const override;
44-
46+
size_t HashCode() const override;
47+
bool Equals(const CacheKey& other) const override;
4548
int64_t Position() const;
4649
int32_t Length() const;
4750

48-
bool operator==(const PositionCacheKey& other) const;
49-
size_t HashCode() const;
50-
5151
private:
5252
static constexpr uint64_t HASH_CONSTANT = 0x9e3779b97f4a7c15ULL;
5353

@@ -56,13 +56,27 @@ class PositionCacheKey : public CacheKey {
5656
const int32_t length_;
5757
const bool is_index_;
5858
};
59-
} // namespace paimon
6059

61-
namespace std {
62-
template <>
63-
struct hash<paimon::PositionCacheKey> {
64-
size_t operator()(const paimon::PositionCacheKey& key) const {
65-
return key.HashCode();
60+
struct CacheKeyHash {
61+
size_t operator()(const std::shared_ptr<CacheKey>& key) const {
62+
return key ? key->HashCode() : 0;
6663
}
6764
};
68-
} // namespace std
65+
66+
struct CacheKeyEqual {
67+
bool operator()(const std::shared_ptr<CacheKey>& lhs,
68+
const std::shared_ptr<CacheKey>& rhs) const {
69+
if (lhs == rhs) {
70+
return true;
71+
}
72+
if (!lhs || !rhs) {
73+
return false;
74+
}
75+
return lhs->Equals(*rhs);
76+
}
77+
};
78+
79+
using CacheKeyMap = std::unordered_map<std::shared_ptr<CacheKey>, std::shared_ptr<CacheValue>,
80+
CacheKeyHash, CacheKeyEqual>;
81+
82+
} // namespace paimon

0 commit comments

Comments
 (0)