Skip to content

Commit 84e0e8e

Browse files
authored
test: add pk compaction inte test (alibaba#203)
1 parent 94e5ef7 commit 84e0e8e

22 files changed

Lines changed: 1064 additions & 42 deletions

include/paimon/defs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,10 @@ struct PAIMON_EXPORT Options {
398398
/// conf like this: 'file.format.per.level' = '0:avro,3:parquet', if the file format for level
399399
/// is not provided, the default format which set by FILE_FORMAT will be used.
400400
static const char FILE_FORMAT_PER_LEVEL[];
401+
/// "file.compression.per.level" - Define different compression policies for different level,
402+
/// you can add the conf like this: 'file.compression.per.level' = '0:lz4,1:zstd'.
403+
/// If a level is not configured, the default compression set by FILE_COMPRESSION will be used.
404+
static const char FILE_COMPRESSION_PER_LEVEL[];
401405
};
402406

403407
static constexpr int64_t BATCH_WRITE_COMMIT_IDENTIFIER = std::numeric_limits<int64_t>::max();

src/paimon/common/defs.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const char Options::LOOKUP_CACHE_SPILL_COMPRESSION[] = "lookup.cache-spill-compr
102102
const char Options::SPILL_COMPRESSION_ZSTD_LEVEL[] = "spill-compression.zstd-level";
103103
const char Options::CACHE_PAGE_SIZE[] = "cache-page-size";
104104
const char Options::FILE_FORMAT_PER_LEVEL[] = "file.format.per.level";
105+
const char Options::FILE_COMPRESSION_PER_LEVEL[] = "file.compression.per.level";
105106
const char Options::COMPACTION_MAX_SIZE_AMPLIFICATION_PERCENT[] =
106107
"compaction.max-size-amplification-percent";
107108
const char Options::COMPACTION_SIZE_RATIO[] = "compaction.size-ratio";

src/paimon/core/core_options.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,34 @@ class ConfigParser {
296296
return Status::OK();
297297
}
298298

299+
// parse file.compression.per.level
300+
Status ParseFileCompressionPerLevel(
301+
std::map<int32_t, std::string>* file_compression_per_level_ptr) const {
302+
auto& file_compression_per_level = *file_compression_per_level_ptr;
303+
std::string file_compression_per_level_str;
304+
PAIMON_RETURN_NOT_OK(
305+
ParseString(Options::FILE_COMPRESSION_PER_LEVEL, &file_compression_per_level_str));
306+
if (!file_compression_per_level_str.empty()) {
307+
auto level2compression = StringUtils::Split(file_compression_per_level_str,
308+
std::string(","), std::string(":"));
309+
for (const auto& single_level : level2compression) {
310+
if (single_level.size() != 2) {
311+
return Status::Invalid(fmt::format(
312+
"fail to parse key {}, value {} (usage example: 0:lz4,1:zstd)",
313+
Options::FILE_COMPRESSION_PER_LEVEL, file_compression_per_level_str));
314+
}
315+
auto level = StringUtils::StringToValue<int32_t>(single_level[0]);
316+
if (!level || level.value() < 0) {
317+
return Status::Invalid(
318+
fmt::format("fail to parse level {} from string to int in {}",
319+
single_level[0], Options::FILE_COMPRESSION_PER_LEVEL));
320+
}
321+
file_compression_per_level[level.value()] = single_level[1];
322+
}
323+
}
324+
return Status::OK();
325+
}
326+
299327
bool ContainsKey(const std::string& key) const {
300328
return config_map_.find(key) != config_map_.end();
301329
}
@@ -395,6 +423,7 @@ struct CoreOptions::Impl {
395423
CompressOptions lookup_compress_options{"zstd", 1};
396424
int64_t cache_page_size = 64 * 1024; // 64KB
397425
std::map<int32_t, std::shared_ptr<FileFormat>> file_format_per_level;
426+
std::map<int32_t, std::string> file_compression_per_level;
398427
};
399428

400429
// Parse configurations from a map and return a populated CoreOptions object
@@ -663,6 +692,9 @@ Result<CoreOptions> CoreOptions::FromMap(
663692
// parse file.format.per.level
664693
PAIMON_RETURN_NOT_OK(parser.ParseFileFormatPerLevel(&impl->file_format_per_level));
665694

695+
// parse file.compression.per.level
696+
PAIMON_RETURN_NOT_OK(parser.ParseFileCompressionPerLevel(&impl->file_compression_per_level));
697+
666698
PAIMON_RETURN_NOT_OK(parser.Parse<int32_t>(Options::COMPACTION_MAX_SIZE_AMPLIFICATION_PERCENT,
667699
&impl->compaction_max_size_amplification_percent));
668700
PAIMON_RETURN_NOT_OK(
@@ -718,6 +750,14 @@ const std::string& CoreOptions::GetFileCompression() const {
718750
return impl_->file_compression;
719751
}
720752

753+
const std::string& CoreOptions::GetWriteFileCompression(int32_t level) const {
754+
auto iter = impl_->file_compression_per_level.find(level);
755+
if (iter != impl_->file_compression_per_level.end()) {
756+
return iter->second;
757+
}
758+
return impl_->file_compression;
759+
}
760+
721761
int32_t CoreOptions::GetFileCompressionZstdLevel() const {
722762
return impl_->file_compression_zstd_level;
723763
}

src/paimon/core/core_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class PAIMON_EXPORT CoreOptions {
5959
std::shared_ptr<FileFormat> GetWriteFileFormat(int32_t level) const;
6060
std::shared_ptr<FileSystem> GetFileSystem() const;
6161
const std::string& GetFileCompression() const;
62+
const std::string& GetWriteFileCompression(int32_t level) const;
6263
int32_t GetFileCompressionZstdLevel() const;
6364
int64_t GetPageSize() const;
6465
int64_t GetTargetFileSize(bool has_primary_key) const;

src/paimon/core/core_options_test.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ TEST(CoreOptionsTest, TestDefaultValue) {
4848
ASSERT_EQ("__DEFAULT_PARTITION__", core_options.GetPartitionDefaultName());
4949
ASSERT_EQ(std::nullopt, core_options.GetScanSnapshotId());
5050
ASSERT_EQ("zstd", core_options.GetFileCompression());
51+
ASSERT_EQ("zstd", core_options.GetWriteFileCompression(0));
52+
ASSERT_EQ("zstd", core_options.GetWriteFileCompression(3));
5153
ASSERT_EQ("zstd", core_options.GetManifestCompression());
5254
ASSERT_EQ(1, core_options.GetFileCompressionZstdLevel());
5355
ASSERT_EQ(StartupMode::LatestFull(), core_options.GetStartupMode());
@@ -207,7 +209,8 @@ TEST(CoreOptionsTest, TestFromMap) {
207209
{Options::LOOKUP_CACHE_SPILL_COMPRESSION, "lz4"},
208210
{Options::SPILL_COMPRESSION_ZSTD_LEVEL, "2"},
209211
{Options::CACHE_PAGE_SIZE, "6MB"},
210-
{Options::FILE_FORMAT_PER_LEVEL, "0:AVRO,3:parquet"}};
212+
{Options::FILE_FORMAT_PER_LEVEL, "0:AVRO,3:parquet"},
213+
{Options::FILE_COMPRESSION_PER_LEVEL, "0:lz4,3:none"}};
211214

212215
ASSERT_OK_AND_ASSIGN(CoreOptions core_options, CoreOptions::FromMap(options));
213216
auto fs = core_options.GetFileSystem();
@@ -278,6 +281,10 @@ TEST(CoreOptionsTest, TestFromMap) {
278281
std::optional<std::string>("FILE:///tmp/index"));
279282
ASSERT_EQ(core_options.GetExternalPathStrategy(), ExternalPathStrategy::ROUND_ROBIN);
280283
ASSERT_EQ("snappy", core_options.GetFileCompression());
284+
ASSERT_EQ("lz4", core_options.GetWriteFileCompression(0));
285+
ASSERT_EQ("snappy", core_options.GetWriteFileCompression(1));
286+
ASSERT_EQ("none", core_options.GetWriteFileCompression(3));
287+
ASSERT_EQ("snappy", core_options.GetWriteFileCompression(5));
281288
ASSERT_EQ("zlib", core_options.GetManifestCompression());
282289
ASSERT_EQ(2, core_options.GetFileCompressionZstdLevel());
283290
ASSERT_FALSE(core_options.EnableAdaptivePrefetchStrategy());
@@ -426,6 +433,13 @@ TEST(CoreOptionsTest, TestInvalidFileFormatPerLevel) {
426433
"fail to parse level aaa from string to int in file.format.per.level");
427434
}
428435

436+
TEST(CoreOptionsTest, TestInvalidFileCompressionPerLevel) {
437+
ASSERT_NOK_WITH_MSG(CoreOptions::FromMap({{Options::FILE_COMPRESSION_PER_LEVEL, "0:lz4:zstd"}}),
438+
"fail to parse key file.compression.per.level, value 0:lz4:zstd");
439+
ASSERT_NOK_WITH_MSG(CoreOptions::FromMap({{Options::FILE_COMPRESSION_PER_LEVEL, "abc:lz4"}}),
440+
"fail to parse level abc from string to int in file.compression.per.level");
441+
}
442+
429443
TEST(CoreOptionsTest, TestCreateExternalPath) {
430444
std::map<std::string, std::string> options = {
431445
{Options::DATA_FILE_EXTERNAL_PATHS,

src/paimon/core/global_index/global_index_scan_impl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ Result<std::shared_ptr<RowRangeGlobalIndexScanner>> GlobalIndexScanImpl::CreateR
5151
if (!partition) {
5252
partition = entry.partition;
5353
} else if (!(partition.value() == entry.partition)) {
54-
// TODO(xinyu.lxy): add inte case
5554
return Status::Invalid(
5655
"input range contain multiple partitions, fail to create range scan");
5756
}

src/paimon/core/io/data_file_writer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Result<std::shared_ptr<DataFileMeta>> DataFileWriter::GetResult() {
5454
PAIMON_ASSIGN_OR_RAISE(std::vector<std::shared_ptr<ColumnStats>> field_stats, GetFieldStats());
5555
PAIMON_ASSIGN_OR_RAISE(SimpleStats stats,
5656
SimpleStatsConverter::ToBinary(field_stats, pool_.get()));
57-
// TODO(xinyu.lxy): do not support write value stats cols & first_row_id for now
57+
// TODO(xinyu.lxy): do not support write value stats cols for now
5858
std::optional<std::string> final_path;
5959
if (is_external_path_) {
6060
PAIMON_ASSIGN_OR_RAISE(Path external_path, PathUtil::ToPath(path_));

src/paimon/core/io/key_value_data_file_writer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Result<std::shared_ptr<DataFileMeta>> KeyValueDataFileWriter::GetResult() {
9595
} else {
9696
PAIMON_RETURN_NOT_OK(GenerateKeyStatsWithAllNull(&key_stats));
9797
}
98-
// TODO(xinyu.lxy): do not support write value stats cols & first_row_id & write_cols for now
98+
// TODO(xinyu.lxy): do not support write value stats cols for now
9999
std::optional<std::string> final_path;
100100
if (is_external_path_) {
101101
PAIMON_ASSIGN_OR_RAISE(Path external_path, PathUtil::ToPath(path_));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class CompactStrategy {
3333
virtual Result<std::optional<CompactUnit>> Pick(int32_t num_levels,
3434
const std::vector<LevelSortedRun>& runs) = 0;
3535
/// Pick a compaction unit consisting of all existing files.
36-
// TODO(xinyu.lxy): support RecordLevelExpire and BucketedDvMaintainer
36+
// TODO(xinyu.lxy): support RecordLevelExpire
3737
static std::optional<CompactUnit> PickFullCompaction(
3838
int32_t num_levels, const std::vector<LevelSortedRun>& runs,
3939
const std::shared_ptr<BucketedDvMaintainer>& dv_maintainer, bool force_rewrite_all_files) {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ LookupMergeTreeCompactRewriter<T>::Create(
6262

6363
// TODO(xinyu.lxy): set executor
6464
ReadContextBuilder read_context_builder(path_factory_cache->RootPath());
65-
read_context_builder.SetOptions(options.ToMap()).EnablePrefetch(true).WithMemoryPool(pool);
65+
read_context_builder.SetOptions(options.ToMap())
66+
.EnablePrefetch(true)
67+
.SetPrefetchMaxParallelNum(1)
68+
.WithMemoryPool(pool);
6669
PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<ReadContext> read_context,
6770
read_context_builder.Finish());
6871

0 commit comments

Comments
 (0)