Skip to content

Commit a8be438

Browse files
committed
feat(avro): support zstd compression level configuration
1 parent 623db38 commit a8be438

7 files changed

Lines changed: 78 additions & 7 deletions

File tree

src/paimon/format/avro/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ if(PAIMON_ENABLE_AVRO)
6565
"-Wl,--whole-archive"
6666
paimon_local_file_system_static
6767
paimon_avro_file_format_static
68+
paimon_parquet_file_format_static
6869
"-Wl,--no-whole-archive"
6970
${GTEST_LINK_TOOLCHAIN})
7071

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2026-present Alibaba Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
namespace paimon::avro {
20+
21+
// write
22+
static inline const char AVRO_COMPRESSION_CODEC_ZSTD_LEVEL[] = "avro.compression.codec.zstd.level";
23+
static inline const char AVRO_COMPRESSION_CODEC_DEFLATE_LEVEL[] =
24+
"avro.compression.codec.deflate.level";
25+
26+
} // namespace paimon::avro

src/paimon/format/avro/avro_format_writer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,14 @@ AvroFormatWriter::AvroFormatWriter(std::unique_ptr<::avro::DataFileWriterBase>&&
5353

5454
Result<std::unique_ptr<AvroFormatWriter>> AvroFormatWriter::Create(
5555
std::unique_ptr<AvroOutputStreamImpl> out, const std::shared_ptr<arrow::Schema>& schema,
56-
const ::avro::Codec codec) {
56+
const ::avro::Codec codec, std::optional<int> compressionLevel) {
5757
try {
5858
PAIMON_ASSIGN_OR_RAISE(::avro::ValidSchema avro_schema,
5959
AvroSchemaConverter::ArrowSchemaToAvroSchema(schema));
6060
AvroOutputStreamImpl* avro_output_stream = out.get();
61-
auto writer = std::make_unique<::avro::DataFileWriterBase>(std::move(out), avro_schema,
62-
DEFAULT_SYNC_INTERVAL, codec);
61+
::avro::Metadata metadata;
62+
auto writer = std::make_unique<::avro::DataFileWriterBase>(
63+
std::move(out), avro_schema, DEFAULT_SYNC_INTERVAL, codec, metadata, compressionLevel);
6364
auto data_type = arrow::struct_(schema->fields());
6465
return std::unique_ptr<AvroFormatWriter>(
6566
new AvroFormatWriter(std::move(writer), avro_schema, data_type, avro_output_stream));

src/paimon/format/avro/avro_format_writer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <cstddef>
2020
#include <cstdint>
2121
#include <memory>
22+
#include <optional>
2223

2324
#include "arrow/api.h"
2425
#include "avro/DataFile.hh"
@@ -49,7 +50,7 @@ class AvroFormatWriter : public FormatWriter {
4950
public:
5051
static Result<std::unique_ptr<AvroFormatWriter>> Create(
5152
std::unique_ptr<AvroOutputStreamImpl> out, const std::shared_ptr<arrow::Schema>& schema,
52-
const ::avro::Codec codec);
53+
const ::avro::Codec codec, std::optional<int> compressionLevel = std::nullopt);
5354

5455
Status AddBatch(ArrowArray* batch) override;
5556

src/paimon/format/avro/avro_writer_builder.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424

2525
#include "avro/DataFile.hh"
2626
#include "avro/Stream.hh"
27+
#include "paimon/common/utils/options_utils.h"
2728
#include "paimon/common/utils/string_utils.h"
29+
#include "paimon/core/core_options.h"
30+
#include "paimon/format/avro/avro_format_defs.h"
2831
#include "paimon/format/avro/avro_format_writer.h"
2932
#include "paimon/format/avro/avro_output_stream_impl.h"
3033
#include "paimon/format/writer_builder.h"
@@ -58,7 +61,11 @@ class AvroWriterBuilder : public WriterBuilder {
5861
auto output_stream = std::make_unique<AvroOutputStreamImpl>(out, BUFFER_SIZE, pool_);
5962
PAIMON_ASSIGN_OR_RAISE(::avro::Codec codec,
6063
ToAvroCompressionKind(StringUtils::ToLowerCase(compression)));
61-
return AvroFormatWriter::Create(std::move(output_stream), schema_, codec);
64+
PAIMON_ASSIGN_OR_RAISE(std::optional<int> compression_zstd_level,
65+
GetAvroCompressionZstdLevel(codec));
66+
67+
return AvroFormatWriter::Create(std::move(output_stream), schema_, codec,
68+
compression_zstd_level);
6269
}
6370

6471
private:
@@ -77,6 +84,14 @@ class AvroWriterBuilder : public WriterBuilder {
7784
return Status::Invalid("unknown compression " + file_compression);
7885
}
7986
}
87+
Result<std::optional<int>> GetAvroCompressionZstdLevel(const ::avro::Codec& codec) {
88+
PAIMON_ASSIGN_OR_RAISE(CoreOptions core_options, CoreOptions::FromMap(options_));
89+
std::optional<int> compression_zstd_level;
90+
if (codec == ::avro::Codec::ZSTD_CODEC) {
91+
compression_zstd_level = core_options.GetFileCompressionZstdLevel();
92+
}
93+
return compression_zstd_level;
94+
}
8095

8196
std::shared_ptr<MemoryPool> pool_;
8297
std::shared_ptr<arrow::Schema> schema_;

src/paimon/format/avro/avro_writer_builder_test.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,31 @@ TEST(ToAvroCompressionKindTest, HandlesInvalidCompression) {
5151
TEST(ToAvroCompressionKindTest, HandlesEmptyString) {
5252
ASSERT_NOK(AvroWriterBuilder::ToAvroCompressionKind(""));
5353
}
54+
55+
TEST(ToAvroCompressionKindTest, GetAvroCompressionZstdLevel) {
56+
AvroWriterBuilder builder(nullptr, -1, {});
57+
ASSERT_OK_AND_ASSIGN(std::optional<int> zstd_level,
58+
builder.GetAvroCompressionZstdLevel(::avro::Codec::ZSTD_CODEC));
59+
ASSERT_TRUE(zstd_level.has_value());
60+
ASSERT_EQ(zstd_level.value(), 1);
61+
62+
ASSERT_OK_AND_ASSIGN(std::optional<int> compression_level1,
63+
builder.GetAvroCompressionZstdLevel(::avro::Codec::SNAPPY_CODEC));
64+
ASSERT_FALSE(compression_level1.has_value());
65+
66+
ASSERT_OK_AND_ASSIGN(std::optional<int> compression_level2,
67+
builder.GetAvroCompressionZstdLevel(::avro::Codec::DEFLATE_CODEC));
68+
ASSERT_FALSE(compression_level2.has_value());
69+
70+
ASSERT_OK_AND_ASSIGN(std::optional<int> compression_level3,
71+
builder.GetAvroCompressionZstdLevel(::avro::Codec::NULL_CODEC));
72+
ASSERT_FALSE(compression_level3.has_value());
73+
74+
AvroWriterBuilder builder2(nullptr, -1, {{"file.compression.zstd-level", "3"}});
75+
ASSERT_OK_AND_ASSIGN(std::optional<int> zstd_level2,
76+
builder2.GetAvroCompressionZstdLevel(::avro::Codec::ZSTD_CODEC));
77+
ASSERT_TRUE(zstd_level2.has_value());
78+
ASSERT_EQ(zstd_level2.value(), 3);
79+
}
80+
5481
} // namespace paimon::avro::test

third_party/versions.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ PAIMON_GTEST_PKG_NAME=gtest-${PAIMON_GTEST_BUILD_VERSION}.tar.gz
5555
PAIMON_ARROW_BUILD_VERSION=17.0.0
5656
PAIMON_ARROW_BUILD_SHA256_CHECKSUM=9d280d8042e7cf526f8c28d170d93bfab65e50f94569f6a790982a878d8d898d
5757
PAIMON_ARROW_PKG_NAME=apache-arrow-${PAIMON_ARROW_BUILD_VERSION}.tar.gz
58-
PAIMON_AVRO_BUILD_VERSION=54b332161524086dcb6cde8afe097097eed7f3ee
59-
PAIMON_AVRO_BUILD_SHA256_CHECKSUM=00febd590b1e328d3a97b67a6d29a1d0243e0e41bb2b1582ec580d37698d1fe2
58+
PAIMON_AVRO_BUILD_VERSION=c499eefb48aa2db906c7bca14a047223806f36db
59+
PAIMON_AVRO_BUILD_SHA256_CHECKSUM=9771f1dcfe3c01aff7ff670e873e66d3406362f71941821d482de65f3d32d780
6060
PAIMON_AVRO_PKG_NAME=avro-${PAIMON_AVRO_BUILD_VERSION}.tar.gz
6161
PAIMON_FMT_BUILD_VERSION=11.2.0
6262
PAIMON_FMT_BUILD_SHA256_CHECKSUM=bc23066d87ab3168f27cef3e97d545fa63314f5c79df5ea444d41d56f962c6af

0 commit comments

Comments
 (0)