This is an automated email from the ASF dual-hosted git repository.

SteNicholas pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new dbdce8fd perf(parquet): reuse leaf column index set across fields in 
page-filtered reads (#207)
dbdce8fd is described below

commit dbdce8fd646394833586a324599811a135116f6e
Author: Zhou Hongfeng <[email protected]>
AuthorDate: Thu Aug 20 16:28:44 2026 +0800

    perf(parquet): reuse leaf column index set across fields in page-filtered 
reads (#207)
---
 cmake_modules/arrow.diff                                     |  8 ++++----
 src/paimon/format/parquet/page_filtered_row_group_reader.cpp | 10 ++++++----
 src/paimon/format/parquet/page_filtered_row_group_reader.h   |  9 ++++++---
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/cmake_modules/arrow.diff b/cmake_modules/arrow.diff
index ce63af35..75e3bb51 100644
--- a/cmake_modules/arrow.diff
+++ b/cmake_modules/arrow.diff
@@ -57,7 +57,7 @@ index 285e2a5973..db919d7ef8 100644
    }
 
 +  ::arrow::Status GetColumn(
-+      int i, const std::vector<int>& column_indices,
++      int i, const std::shared_ptr<std::unordered_set<int>>& column_indices,
 +      FileColumnIteratorFactory iterator_factory,
 +      std::unique_ptr<ColumnReader>* out) override;
 +
@@ -235,7 +235,7 @@ index 285e2a5973..db919d7ef8 100644
  }
 
 +::arrow::Status FileReaderImpl::GetColumn(
-+    int i, const std::vector<int>& column_indices,
++    int i, const std::shared_ptr<std::unordered_set<int>>& column_indices,
 +    FileColumnIteratorFactory iterator_factory,
 +    std::unique_ptr<ColumnReader>* out) {
 +  RETURN_NOT_OK(BoundsCheckColumn(i));
@@ -244,7 +244,7 @@ index 285e2a5973..db919d7ef8 100644
 +  ctx->pool = pool_;
 +  ctx->iterator_factory = iterator_factory;
 +  ctx->filter_leaves = true;
-+  ctx->included_leaves = VectorToSharedSet(column_indices);
++  ctx->included_leaves = column_indices;
 +  std::unique_ptr<ColumnReaderImpl> result;
 +  RETURN_NOT_OK(GetReader(manifest_.schema_fields[i], ctx, &result));
 +  *out = std::move(result);
@@ -298,7 +298,7 @@ index 6e46ca43f7..e86ff0ef52 100644
 +  /// \param iterator_factory factory to create FileColumnIterator per leaf
 +  /// \param[out] out the ColumnReader (may be nullptr if all leaves are 
pruned)
 +  virtual ::arrow::Status GetColumn(
-+      int i, const std::vector<int>& column_indices,
++      int i, const std::shared_ptr<std::unordered_set<int>>& column_indices,
 +      FileColumnIteratorFactory iterator_factory,
 +      std::unique_ptr<ColumnReader>* out) {
 +    return ::arrow::Status::NotImplemented(
diff --git a/src/paimon/format/parquet/page_filtered_row_group_reader.cpp 
b/src/paimon/format/parquet/page_filtered_row_group_reader.cpp
index 1b4bdd30..f20f224f 100644
--- a/src/paimon/format/parquet/page_filtered_row_group_reader.cpp
+++ b/src/paimon/format/parquet/page_filtered_row_group_reader.cpp
@@ -284,9 +284,9 @@ Status PageFilteredRowGroupReader::WaitForPreBuffer(
 
 Result<std::shared_ptr<arrow::ChunkedArray>> 
PageFilteredRowGroupReader::ReadFilteredField(
     const std::shared_ptr<::parquet::RowGroupPageIndexReader>& 
rg_page_index_reader,
-    int32_t row_group_index, int32_t field_index, const std::vector<int32_t>& 
column_indices,
-    const RowRanges& row_ranges, int64_t row_group_row_count,
-    ::parquet::arrow::FileReader* arrow_file_reader) {
+    int32_t row_group_index, int32_t field_index,
+    std::shared_ptr<std::unordered_set<int>> column_indices, const RowRanges& 
row_ranges,
+    int64_t row_group_row_count, ::parquet::arrow::FileReader* 
arrow_file_reader) {
     // Factory: set a direct data page read plan on every leaf (per-leaf 
OffsetIndex).
     // The plan lets Arrow jump over unselected page headers as well as page 
bodies.
     auto factory =
@@ -397,12 +397,14 @@ Result<std::unique_ptr<arrow::RecordBatchReader>> 
PageFilteredRowGroupReader::Re
     std::vector<std::shared_ptr<arrow::ChunkedArray>> result_arrays;
     result_arrays.reserve(field_indices.size());
 
+    std::shared_ptr<std::unordered_set<int>> col_indices_set =
+        std::make_shared<std::unordered_set<int>>(column_indices.begin(), 
column_indices.end());
     // TODO(zhouhongfeng.zhf): This loop could be parallelized.
     for (int field_idx : field_indices) {
         PAIMON_ASSIGN_OR_RAISE(
             std::shared_ptr<arrow::ChunkedArray> chunked_array,
             ReadFilteredField(row_group_page_index_reader, row_group_index, 
field_idx,
-                              column_indices, row_ranges, row_group_row_count, 
arrow_file_reader));
+                              col_indices_set, row_ranges, 
row_group_row_count, arrow_file_reader));
 
         if (chunked_array->length() != expected_rows) {
             return Status::Invalid(
diff --git a/src/paimon/format/parquet/page_filtered_row_group_reader.h 
b/src/paimon/format/parquet/page_filtered_row_group_reader.h
index 683bde71..a143ae5a 100644
--- a/src/paimon/format/parquet/page_filtered_row_group_reader.h
+++ b/src/paimon/format/parquet/page_filtered_row_group_reader.h
@@ -23,6 +23,7 @@
 #include <limits>
 #include <memory>
 #include <optional>
+#include <unordered_set>
 #include <utility>
 #include <vector>
 
@@ -117,11 +118,13 @@ class PageFilteredRowGroupReader {
     /// Sets a direct page read plan on all leaves via factory, then drives 
each leaf
     /// independently via ResetLeaf/SkipRecords/ReadRecords using its own
     /// compressed_ranges.
+    /// `column_indices` holds `int` rather than `int32_t` because the set is
+    /// handed straight to Arrow's `FileReader::GetColumn` (to avoid 
reconstruction and deep copy)
     static Result<std::shared_ptr<arrow::ChunkedArray>> ReadFilteredField(
         const std::shared_ptr<::parquet::RowGroupPageIndexReader>& 
rg_page_index_reader,
-        int32_t row_group_index, int32_t field_index, const 
std::vector<int32_t>& column_indices,
-        const RowRanges& row_ranges, int64_t row_group_row_count,
-        ::parquet::arrow::FileReader* arrow_file_reader);
+        int32_t row_group_index, int32_t field_index,
+        std::shared_ptr<std::unordered_set<int>> column_indices, const 
RowRanges& row_ranges,
+        int64_t row_group_row_count, ::parquet::arrow::FileReader* 
arrow_file_reader);
 };
 
 }  // namespace paimon::parquet

Reply via email to