Skip to content

Commit 2aa540e

Browse files
committed
Add support for string/binary view to content defined chunking writer
1 parent bffbbe7 commit 2aa540e

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

‎cpp/src/parquet/chunker_internal.cc‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <cstdint>
2222
#include <iterator>
2323
#include <string>
24+
#include <string_view>
2425
#include <vector>
2526

2627
#include "arrow/array.h"
@@ -349,6 +350,17 @@ class ContentDefinedChunker::Impl {
349350
});
350351
}
351352

353+
std::vector<Chunk> CalculateBinaryView(const int16_t* def_levels,
354+
const int16_t* rep_levels, int64_t num_levels,
355+
const ::arrow::Array& values) {
356+
const auto& array = checked_cast<const ::arrow::BinaryViewArray&>(values);
357+
return Calculate(def_levels, rep_levels, num_levels, [&](int64_t i) {
358+
const std::string_view value = array.GetView(i);
359+
Roll(reinterpret_cast<const uint8_t*>(value.data()),
360+
static_cast<int64_t>(value.size()));
361+
});
362+
}
363+
352364
std::vector<Chunk> GetChunks(const int16_t* def_levels, const int16_t* rep_levels,
353365
int64_t num_levels, const ::arrow::Array& values) {
354366
auto handle_type = [&](auto&& type) -> std::vector<Chunk> {
@@ -380,6 +392,8 @@ class ContentDefinedChunker::Impl {
380392
} else if constexpr (::arrow::is_large_binary_like(ArrowType::type_id)) {
381393
return CalculateBinaryLike<::arrow::LargeBinaryArray>(def_levels, rep_levels,
382394
num_levels, values);
395+
} else if constexpr (::arrow::is_binary_view_like(ArrowType::type_id)) {
396+
return CalculateBinaryView(def_levels, rep_levels, num_levels, values);
383397
} else if constexpr (::arrow::is_dictionary(ArrowType::type_id)) {
384398
return GetChunks(def_levels, rep_levels, num_levels,
385399
*static_cast<const ::arrow::DictionaryArray&>(values).indices());

‎cpp/src/parquet/chunker_internal_test.cc‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ Result<std::shared_ptr<Array>> GenerateArray(const std::shared_ptr<Field>& field
170170
std::string("bin_") + std::to_string(val))
171171
GENERATE_CASE(LARGE_BINARY, ::arrow::LargeBinaryBuilder,
172172
std::string("bin_") + std::to_string(val))
173+
GENERATE_CASE(STRING_VIEW, ::arrow::StringViewBuilder,
174+
std::string("str_") + std::to_string(val))
175+
GENERATE_CASE(BINARY_VIEW, ::arrow::BinaryViewBuilder,
176+
std::string("bin_") + std::to_string(val))
173177
case ::arrow::Type::FIXED_SIZE_BINARY: {
174178
auto size =
175179
checked_cast<const ::arrow::FixedSizeBinaryType*>(type.get())->byte_width();
@@ -742,6 +746,13 @@ Result<int64_t> CalculateCdcSize(const std::shared_ptr<Array>& array, bool nulla
742746
} else if (::arrow::is_large_binary_like(type_id)) {
743747
auto binary_array = checked_cast<const ::arrow::LargeBinaryArray*>(array.get());
744748
result += binary_array->total_values_length();
749+
} else if (::arrow::is_binary_view_like(type_id)) {
750+
auto view_array = checked_cast<const ::arrow::BinaryViewArray*>(array.get());
751+
for (int64_t i = 0; i < view_array->length(); i++) {
752+
if (view_array->IsValid(i)) {
753+
result += static_cast<int64_t>(view_array->GetView(i).size());
754+
}
755+
}
745756
} else {
746757
return Status::NotImplemented("CDC size calculation for type ",
747758
array->type()->ToString(), " is not implemented");
@@ -784,7 +795,8 @@ void AssertContentDefinedChunkSizes(const std::shared_ptr<::arrow::ChunkedArray>
784795
ASSERT_EQ(column_info.has_dictionary_page, expect_dictionary_page);
785796
}
786797

787-
if (::arrow::is_fixed_width(type_id) || ::arrow::is_base_binary_like(type_id)) {
798+
if (::arrow::is_fixed_width(type_id) || ::arrow::is_base_binary_like(type_id) ||
799+
::arrow::is_binary_view_like(type_id)) {
788800
int64_t offset = 0;
789801

790802
auto page_lengths = column_info.page_lengths;
@@ -1451,7 +1463,7 @@ INSTANTIATE_TEST_SUITE_P(
14511463
testing::Values(
14521464
CaseConfig{::arrow::boolean(), false}, CaseConfig{::arrow::int64(), true},
14531465
// Binary-like
1454-
CaseConfig{::arrow::utf8(), false},
1466+
CaseConfig{::arrow::utf8(), false}, CaseConfig{::arrow::utf8_view(), true},
14551467
CaseConfig{::arrow::fixed_size_binary(16), true},
14561468
// Nested types
14571469
CaseConfig{::arrow::list(::arrow::int32()), false},
@@ -1475,6 +1487,7 @@ INSTANTIATE_TEST_SUITE_P(
14751487
// Binary-like
14761488
CaseConfig{::arrow::utf8(), false}, CaseConfig{::arrow::binary(), true},
14771489
CaseConfig{::arrow::fixed_size_binary(16), true},
1490+
CaseConfig{::arrow::utf8_view(), false}, CaseConfig{::arrow::binary_view(), true},
14781491
// Temporal
14791492
CaseConfig{::arrow::date32(), false},
14801493
CaseConfig{::arrow::time32(::arrow::TimeUnit::MILLI), true},

0 commit comments

Comments
 (0)