Skip to content

Commit 6a28cc4

Browse files
zjw1111Copilot
andcommitted
fix review
Co-authored-by: Copilot <copilot@github.com>
1 parent c9d1f4f commit 6a28cc4

11 files changed

Lines changed: 67 additions & 89 deletions

include/paimon/defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ struct PAIMON_EXPORT Options {
182182
static const char WRITE_BUFFER_SPILLABLE[];
183183

184184
/// "write-buffer-spill.max-disk-size" - The max disk to use for write buffer spill. This only
185-
/// work when the write buffer spill is enabled. Default value is unlimited.
185+
/// works when the write buffer spill is enabled. Default value is unlimited.
186186
static const char WRITE_BUFFER_SPILL_MAX_DISK_SIZE[];
187187

188188
/// "local-sort.max-num-file-handles" - The maximal fan-in for external merge sort. It limits

src/paimon/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ set(PAIMON_CORE_SRCS
234234
core/manifest/manifest_list.cpp
235235
core/manifest/partition_entry.cpp
236236
core/manifest/index_manifest_file_handler.cpp
237+
core/memory/writer_memory_manager.cpp
237238
core/mergetree/compact/universal_compaction.cpp
238239
core/mergetree/compact/early_full_compaction.cpp
239240
core/mergetree/compact/aggregate/aggregate_merge_function.cpp
@@ -253,7 +254,6 @@ set(PAIMON_CORE_SRCS
253254
core/mergetree/in_memory_sort_buffer.cpp
254255
core/mergetree/external_sort_buffer.cpp
255256
core/mergetree/write_buffer.cpp
256-
core/mergetree/writer_memory_manager.cpp
257257
core/mergetree/levels.cpp
258258
core/mergetree/lookup_file.cpp
259259
core/mergetree/lookup_levels.cpp
@@ -596,6 +596,7 @@ if(PAIMON_BUILD_TESTS)
596596
core/manifest/file_entry_test.cpp
597597
core/manifest/index_manifest_entry_serializer_test.cpp
598598
core/manifest/index_manifest_file_handler_test.cpp
599+
core/memory/writer_memory_manager_test.cpp
599600
core/mergetree/levels_test.cpp
600601
core/mergetree/lookup_file_test.cpp
601602
core/mergetree/lookup_levels_test.cpp
@@ -639,7 +640,6 @@ if(PAIMON_BUILD_TESTS)
639640
core/mergetree/sorted_run_test.cpp
640641
core/mergetree/spill_channel_manager_test.cpp
641642
core/mergetree/spill_reader_writer_test.cpp
642-
core/mergetree/writer_memory_manager_test.cpp
643643
core/migrate/file_meta_utils_test.cpp
644644
core/operation/metrics/compaction_metrics_test.cpp
645645
core/operation/data_evolution_file_store_scan_test.cpp

src/paimon/core/mergetree/writer_memory_manager.cpp renamed to src/paimon/core/memory/writer_memory_manager.cpp

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "paimon/core/mergetree/writer_memory_manager.h"
17+
#include "paimon/core/memory/writer_memory_manager.h"
1818

1919
#include <cassert>
2020

@@ -44,7 +44,7 @@ void WriterMemoryManager::RefreshWriterMemory(BatchWriter* writer) {
4444

4545
Status WriterMemoryManager::OnWriteCompleted(BatchWriter* writer) {
4646
UpdateWriterMemory(writer);
47-
if (total_memory_ < max_memory_) {
47+
if (total_memory_ < memory_limit_) {
4848
return Status::OK();
4949
}
5050

@@ -68,13 +68,9 @@ void WriterMemoryManager::UpdateWriterMemory(BatchWriter* writer) {
6868
}
6969
}
7070

71-
WriterMemoryManager::Candidate WriterMemoryManager::PickLargest(
72-
const std::unordered_set<BatchWriter*>& skipped) const {
71+
WriterMemoryManager::Candidate WriterMemoryManager::PickLargest() const {
7372
Candidate candidate;
7473
for (const auto& [writer, memory] : writer_memory_) {
75-
if (skipped.find(writer) != skipped.end()) {
76-
continue;
77-
}
7874
if (memory > candidate.memory) {
7975
candidate = {writer, memory};
8076
}
@@ -83,33 +79,29 @@ WriterMemoryManager::Candidate WriterMemoryManager::PickLargest(
8379
}
8480

8581
Status WriterMemoryManager::ShrinkToLimit() {
86-
std::unordered_set<BatchWriter*> no_progress_writers;
8782
while (true) {
88-
if (total_memory_ < max_memory_) {
83+
if (total_memory_ < memory_limit_) {
8984
return Status::OK();
9085
}
9186

92-
Candidate picked = PickLargest(no_progress_writers);
87+
Candidate picked = PickLargest();
9388
if (picked.memory == 0) {
9489
return Status::Invalid(
9590
fmt::format("Unable to release memory to below the write-buffer-size limit ({} "
9691
"bytes), this might be a bug.",
97-
max_memory_));
92+
memory_limit_));
9893
}
99-
10094
BatchWriter* candidate = picked.writer;
10195
uint64_t before_memory = picked.memory;
102-
10396
PAIMON_RETURN_NOT_OK(candidate->FlushMemory());
10497

10598
UpdateWriterMemory(candidate);
106-
10799
uint64_t after_memory = candidate->GetMemoryUsage();
108-
109100
if (after_memory >= before_memory) {
110-
no_progress_writers.insert(candidate);
111-
} else {
112-
no_progress_writers.erase(candidate);
101+
return Status::Invalid(fmt::format(
102+
"Before flushing memory, writer had {} bytes of memory allocated, After flushing "
103+
"memory, writer still has {} bytes of memory allocated, this might be a bug.",
104+
before_memory, after_memory));
113105
}
114106
}
115107
}

src/paimon/core/mergetree/writer_memory_manager.h renamed to src/paimon/core/memory/writer_memory_manager.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,27 @@
1818

1919
#include <cstdint>
2020
#include <unordered_map>
21-
#include <unordered_set>
2221

2322
#include "paimon/status.h"
2423

2524
namespace paimon {
2625

2726
class BatchWriter;
2827

29-
/// Coordinates global write-buffer memory across managed writers.
30-
/// NOTE: This class is not thread-safe.
28+
/// Coordinates global write-buffer memory across managed writers. Used in `AbstractFileStoreWrite`.
29+
/// @note This class is not thread-safe.
3130
class WriterMemoryManager {
3231
public:
33-
explicit WriterMemoryManager(uint64_t max_memory) : max_memory_(max_memory) {}
32+
explicit WriterMemoryManager(uint64_t memory_limit) : memory_limit_(memory_limit) {}
3433

34+
/// Register a writer when create a new `BatchWriter` in `AbstractFileStoreWrite::GetWriter()`
3535
void RegisterWriter(BatchWriter* writer);
36+
/// Unregister a writer when the `BatchWriter` has been erased in `AbstractFileStoreWrite`
3637
void UnregisterWriter(BatchWriter* writer);
38+
/// Refresh the memory usage of a writer when after `BatchWriter::PrepareCommit()`
3739
void RefreshWriterMemory(BatchWriter* writer);
38-
40+
/// Check if the total memory usage exceeds the limit after `BatchWriter::Write()`, and trigger
41+
/// flush if needed.
3942
Status OnWriteCompleted(BatchWriter* writer);
4043

4144
private:
@@ -45,10 +48,10 @@ class WriterMemoryManager {
4548
};
4649

4750
void UpdateWriterMemory(BatchWriter* writer);
48-
Candidate PickLargest(const std::unordered_set<BatchWriter*>& skipped) const;
51+
Candidate PickLargest() const;
4952
Status ShrinkToLimit();
5053

51-
uint64_t max_memory_;
54+
const uint64_t memory_limit_;
5255
uint64_t total_memory_ = 0;
5356
std::unordered_map<BatchWriter*, uint64_t> writer_memory_;
5457
};

src/paimon/core/mergetree/writer_memory_manager_test.cpp renamed to src/paimon/core/memory/writer_memory_manager_test.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
#include "paimon/core/mergetree/writer_memory_manager.h"
17+
#include "paimon/core/memory/writer_memory_manager.h"
1818

1919
#include <algorithm>
2020
#include <memory>
@@ -35,8 +35,8 @@ namespace {
3535

3636
class FakeBatchWriter : public BatchWriter {
3737
public:
38-
explicit FakeBatchWriter(std::string name, std::vector<std::string>* flush_history = nullptr)
39-
: name_(std::move(name)), flush_history_(flush_history) {}
38+
FakeBatchWriter(const std::string& name, std::vector<std::string>* flush_history)
39+
: name_(name), flush_history_(flush_history) {}
4040

4141
void SetMemoryUsage(uint64_t memory_usage) {
4242
memory_usage_ = memory_usage;
@@ -52,7 +52,7 @@ class FakeBatchWriter : public BatchWriter {
5252

5353
Status FlushMemory() override {
5454
uint64_t reduction = memory_usage_;
55-
if (flush_calls_ < static_cast<int>(flush_reductions_.size())) {
55+
if (flush_calls_ < static_cast<int32_t>(flush_reductions_.size())) {
5656
reduction = flush_reductions_[flush_calls_];
5757
}
5858
reduction = std::min(reduction, memory_usage_);
@@ -103,13 +103,13 @@ class FakeBatchWriter : public BatchWriter {
103103
std::vector<std::string>* flush_history_;
104104
std::vector<uint64_t> flush_reductions_;
105105
uint64_t memory_usage_ = 0;
106-
int flush_calls_ = 0;
106+
int32_t flush_calls_ = 0;
107107
};
108108

109109
} // namespace
110110

111111
TEST(WriterMemoryManagerTest, DoesNotFlushWhenMemoryIsBelowLimit) {
112-
WriterMemoryManager manager(/*max_memory=*/100);
112+
WriterMemoryManager manager(/*memory_limit=*/100);
113113
std::vector<std::string> flush_history;
114114
FakeBatchWriter writer("writer", &flush_history);
115115
manager.RegisterWriter(&writer);
@@ -120,7 +120,7 @@ TEST(WriterMemoryManagerTest, DoesNotFlushWhenMemoryIsBelowLimit) {
120120
}
121121

122122
TEST(WriterMemoryManagerTest, UnregisterWriterRemovesMemoryFromLedger) {
123-
WriterMemoryManager manager(/*max_memory=*/100);
123+
WriterMemoryManager manager(/*memory_limit=*/100);
124124
std::vector<std::string> flush_history;
125125
FakeBatchWriter writer_a("writer_a", &flush_history);
126126
manager.RegisterWriter(&writer_a);
@@ -137,7 +137,7 @@ TEST(WriterMemoryManagerTest, UnregisterWriterRemovesMemoryFromLedger) {
137137
}
138138

139139
TEST(WriterMemoryManagerTest, RefreshWriterMemoryUpdatesLedgerWithoutFlushing) {
140-
WriterMemoryManager manager(/*max_memory=*/80);
140+
WriterMemoryManager manager(/*memory_limit=*/80);
141141
std::vector<std::string> flush_history;
142142
FakeBatchWriter writer_a("writer_a", &flush_history);
143143
manager.RegisterWriter(&writer_a);
@@ -155,7 +155,7 @@ TEST(WriterMemoryManagerTest, RefreshWriterMemoryUpdatesLedgerWithoutFlushing) {
155155
}
156156

157157
TEST(WriterMemoryManagerTest, FlushWriterMemoryWithMultipleWriters) {
158-
WriterMemoryManager manager(/*max_memory=*/100);
158+
WriterMemoryManager manager(/*memory_limit=*/100);
159159
std::vector<std::string> flush_history;
160160
FakeBatchWriter writer_a("writer_a", &flush_history);
161161
manager.RegisterWriter(&writer_a);
@@ -182,7 +182,7 @@ TEST(WriterMemoryManagerTest, FlushWriterMemoryWithMultipleWriters) {
182182
}
183183

184184
TEST(WriterMemoryManagerTest, ReclaimsCallerWhenCallerIsLargestWriter) {
185-
WriterMemoryManager manager(/*max_memory=*/100);
185+
WriterMemoryManager manager(/*memory_limit=*/100);
186186
std::vector<std::string> flush_history;
187187
FakeBatchWriter writer_a("writer_a", &flush_history);
188188
manager.RegisterWriter(&writer_a);
@@ -193,7 +193,6 @@ TEST(WriterMemoryManagerTest, ReclaimsCallerWhenCallerIsLargestWriter) {
193193
manager.RefreshWriterMemory(&writer_a);
194194

195195
writer_b.SetMemoryUsage(90);
196-
writer_b.SetFlushReductions({90});
197196
ASSERT_OK(manager.OnWriteCompleted(&writer_b));
198197

199198
ASSERT_EQ(flush_history, std::vector<std::string>({"writer_b"}));
@@ -202,7 +201,7 @@ TEST(WriterMemoryManagerTest, ReclaimsCallerWhenCallerIsLargestWriter) {
202201
}
203202

204203
TEST(WriterMemoryManagerTest, ContinuesReclaimingUntilBelowGlobalLimit) {
205-
WriterMemoryManager manager(/*max_memory=*/61);
204+
WriterMemoryManager manager(/*memory_limit=*/61);
206205
std::vector<std::string> flush_history;
207206
FakeBatchWriter writer_a("writer_a", &flush_history);
208207
manager.RegisterWriter(&writer_a);
@@ -224,22 +223,23 @@ TEST(WriterMemoryManagerTest, ContinuesReclaimingUntilBelowGlobalLimit) {
224223
}
225224

226225
TEST(WriterMemoryManagerTest, ReturnsConfigurationErrorWhenNoWriterCanReleaseEnoughMemory) {
227-
WriterMemoryManager manager(/*max_memory=*/100);
226+
WriterMemoryManager manager(/*memory_limit=*/100);
228227
std::vector<std::string> flush_history;
229228
FakeBatchWriter writer_a("writer_a", &flush_history);
230229
manager.RegisterWriter(&writer_a);
231230
FakeBatchWriter writer_b("writer_b", &flush_history);
232231
manager.RegisterWriter(&writer_b);
233232

234233
writer_b.SetMemoryUsage(20);
235-
writer_b.SetFlushReductions({20});
236234
manager.RefreshWriterMemory(&writer_b);
237235

238236
writer_a.SetMemoryUsage(120);
239237
writer_a.SetFlushReductions({10, 0});
240-
ASSERT_NOK_WITH_MSG(manager.OnWriteCompleted(&writer_a),
241-
"Unable to release memory to below the write-buffer-size limit");
242-
ASSERT_EQ(flush_history, std::vector<std::string>({"writer_a", "writer_b"}));
238+
ASSERT_NOK_WITH_MSG(
239+
manager.OnWriteCompleted(&writer_a),
240+
"Before flushing memory, writer had 110 bytes of memory allocated, After flushing memory, "
241+
"writer still has 110 bytes of memory allocated, this might be a bug.");
242+
ASSERT_EQ(flush_history, std::vector<std::string>({"writer_a"}));
243243
}
244244

245245
} // namespace paimon::test

src/paimon/core/mergetree/compact/sort_merge_reader_test.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,11 +773,13 @@ TEST_F(SortMergeReaderTest, TestRawSortNoMergeWithMinHeap) {
773773
// key: k0, user defined sequence field: ts, value: v0
774774
// Format: [_SEQUENCE_NUMBER, _VALUE_KIND, k0, ts, v0]
775775
// Reader1 (SEQUENCE_NUMBER 0..5):
776-
// batch1: [key=1,ts=1,v=1], [key=1,ts=2,v=2], [key=1,ts=3,v=3]
777-
// batch2: [key=1,ts=4,v=4], [key=2,ts=4,v=40], [key=2,ts=5,v=50]
776+
// [key=1,ts=1,v=1], [key=1,ts=2,v=2], [key=1,ts=3,v=3]
777+
// [key=1,ts=4,v=4], [key=2,ts=4,v=40], [key=2,ts=5,v=50]
778778
// Reader2 (SEQUENCE_NUMBER 6..11):
779-
// batch1: [key=1,ts=5,v=5], [key=1,ts=6,v=6], [key=2,ts=1,v=10]
780-
// batch2: [key=2,ts=2,v=20], [key=2,ts=3,v=30], [key=2,ts=6,v=60]
779+
// [key=1,ts=5,v=5], [key=1,ts=6,v=6], [key=2,ts=1,v=10]
780+
// [key=2,ts=2,v=20], [key=2,ts=3,v=30], [key=2,ts=6,v=60]
781+
//
782+
// After sort:
781783
// With user_defined_seq_comparator on ts field, sort by key asc, then ts asc within same key
782784
// key=1: ts=1(seq0,v=1), ts=2(seq1,v=2), ts=3(seq2,v=3), ts=4(seq3,v=4),
783785
// ts=5(seq6,v=5), ts=6(seq7,v=6)

src/paimon/core/mergetree/compact/sort_merge_reader_with_loser_tree.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
#include <memory>
2020
#include <optional>
21-
#include <queue>
2221
#include <utility>
2322
#include <vector>
2423

@@ -37,7 +36,7 @@ class KeyValueRecordReader;
3736
class Metrics;
3837

3938
/// `SortMergeReader` implemented with loser tree. Merge the KeyValue parsed by
40-
/// KeyValueRecordReader and return the iterator of KeyValue
39+
/// `KeyValueRecordReader` and return the iterator of KeyValue
4140
class SortMergeReaderWithLoserTree : public SortMergeReader {
4241
public:
4342
SortMergeReaderWithLoserTree(

src/paimon/core/mergetree/compact/sort_merge_reader_with_min_heap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ template <typename T>
3939
class MergeFunctionWrapper;
4040

4141
/// `SortMergeReader` implemented with min-heap. Merge the KeyValue or only sort the KeyValue parsed
42-
/// by KeyValueRecordReader and return the iterator of KeyValue
42+
/// by `KeyValueRecordReader` and return the iterator of KeyValue
4343
class SortMergeReaderWithMinHeap : public SortMergeReader {
4444
public:
4545
SortMergeReaderWithMinHeap(

src/paimon/core/mergetree/external_sort_buffer.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,6 @@ bool ExternalSortBuffer::HasSpilledData() const {
9292
return !spill_channel_manager_->GetChannels().empty();
9393
}
9494

95-
std::vector<FileIOChannel::ID> ExternalSortBuffer::GetSpillChannelIdsSnapshot() const {
96-
const auto& channels = spill_channel_manager_->GetChannels();
97-
std::vector<FileIOChannel::ID> spill_channel_ids;
98-
spill_channel_ids.reserve(channels.size());
99-
for (const auto& spill_channel_id : channels) {
100-
spill_channel_ids.push_back(spill_channel_id);
101-
}
102-
return spill_channel_ids;
103-
}
104-
10595
void ExternalSortBuffer::Clear() {
10696
in_memory_buffer_->Clear();
10797
CleanupSpillFiles();
@@ -171,7 +161,7 @@ Result<int64_t> ExternalSortBuffer::SpillToDisk(
171161
std::vector<std::unique_ptr<KeyValueRecordReader>>&& readers, int32_t write_batch_size) {
172162
const auto& spill_compress_options = options_.GetSpillCompressOptions();
173163
PAIMON_ASSIGN_OR_RAISE(
174-
auto spill_writer,
164+
std::unique_ptr<SpillWriter> spill_writer,
175165
SpillWriter::Create(options_.GetFileSystem(), write_schema_, spill_channel_enumerator_,
176166
spill_channel_manager_, spill_compress_options.compress,
177167
spill_compress_options.zstd_level));
@@ -229,8 +219,7 @@ Status ExternalSortBuffer::MergeSpilledFiles() {
229219
if (spill_channel_manager_->GetChannels().size() < 2) {
230220
return Status::OK();
231221
}
232-
233-
auto spill_channel_ids_before_merge = GetSpillChannelIdsSnapshot();
222+
auto spill_channel_ids_before_merge = spill_channel_manager_->GetChannels();
234223
auto cleanup_guard = ScopeGuard([&]() {
235224
for (const auto& spill_channel_id : spill_channel_ids_before_merge) {
236225
[[maybe_unused]] auto status = spill_channel_manager_->DeleteChannel(spill_channel_id);

src/paimon/core/mergetree/external_sort_buffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ExternalSortBuffer : public SortBuffer {
5353
const std::shared_ptr<FieldsComparator>& user_defined_seq_comparator,
5454
const CoreOptions& options, const std::shared_ptr<IOManager>& io_manager,
5555
const std::shared_ptr<MemoryPool>& pool);
56+
~ExternalSortBuffer();
5657

5758
void Clear() override;
5859
uint64_t GetMemorySize() const override;
@@ -79,7 +80,6 @@ class ExternalSortBuffer : public SortBuffer {
7980
const CoreOptions& options,
8081
const std::shared_ptr<FileIOChannel::Enumerator>& spill_channel_enumerator,
8182
const std::shared_ptr<MemoryPool>& pool);
82-
~ExternalSortBuffer();
8383

8484
std::unique_ptr<InMemorySortBuffer> in_memory_buffer_;
8585

0 commit comments

Comments
 (0)