Skip to content

GH-50216: [C++][Parquet] Add RleBitPackedToBitmapDecoder - #50217

Merged
pitrou merged 23 commits into
apache:mainfrom
AntoinePrv:rle-bitmap
Jun 25, 2026
Merged

GH-50216: [C++][Parquet] Add RleBitPackedToBitmapDecoder#50217
pitrou merged 23 commits into
apache:mainfrom
AntoinePrv:rle-bitmap

Conversation

@AntoinePrv

@AntoinePrvAntoinePrv commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Rationale for this change

Add a RleBitPackedToBitmapDecoder capable of decoding a Parquet mixed Rle / BitPacked byte stream directly into a bitmap. This is an optimization to be used when target and source bit_width = 1 that will improve decoding nullable columns in a follow-up PR.

What changes are included in this PR?

New classes, that reuse previous Runs and parser.
Their API is slighly different from the existing one as it fits a partilcular case.

  • RleRunToBitmapDecoder
  • BitPackedRunToBitmapDecoder
  • RleRunToBitmapDecoder

Are these changes tested?

Yes.

Are there any user-facing changes?

No.

@AntoinePrv
AntoinePrv requested a review from pitrou as a code ownerJune 18, 2026 09:25
CopilotAI review requested due to automatic review settings June 18, 2026 09:25
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #50216has been automatically assigned in GitHub to PR creator.

@github-actionsgithub-actionsBot added the awaiting review Awaiting review label Jun 18, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a specialized path for decoding Parquet mixed RLE / BitPacked streams with bit_width=1 directly into Arrow bitmaps, aiming to speed up validity/definition-level decoding.

Changes:

  • Added bitmap-oriented decoders for RleRun and BitPackedRun, plus RleBitPackedToBitmapDecoder for mixed streams.
  • Refactored RleBitPackedParser to provide ParseWithCallable() and adjusted RleBitPackedDecoder to use it.
  • Added new bit utilities (Get32Bits, CopyBits) and comprehensive unit tests for the new bitmap decoders.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
cpp/src/arrow/util/rle_encoding_internal.hAdds RleRun::value(), moves callable-based parsing into the parser, and updates RleBitPackedDecoder accordingly.
cpp/src/arrow/util/rle_bitmap_internal.hIntroduces bitmap span + run-to-bitmap decoders and the new RleBitPackedToBitmapDecoder.
cpp/src/arrow/util/rle_bitmap_test.ccAdds tests covering alignment, chunking, reset, and truncated input scenarios for bitmap decoding.
cpp/src/arrow/util/CMakeLists.txtRegisters the new test file in the util test target.
cpp/src/arrow/util/bit_util.hAdds Get32Bits and CopyBits helpers used by the new bitmap decoder implementation.
cpp/src/arrow/util/bit_util_test.ccAdds unit tests for Get32Bits and CopyBits.

Comment threadcpp/src/arrow/util/rle_encoding_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h
Comment threadcpp/src/arrow/util/bit_util.h Outdated
Comment threadcpp/src/arrow/util/rle_encoding_internal.h
@github-actionsgithub-actionsBot added awaiting committer review Awaiting committer review Component: C++ and removed awaiting review Awaiting review labels Jun 18, 2026
CopilotAI review requested due to automatic review settings June 18, 2026 12:03

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment on lines +169 to +176
void Reset(const RunType& run) noexcept {
values_left_ = run.values_count();
if (run.value_little_endian() == 0) {
value_pattern_ = uint8_t{0};
} else {
value_pattern_ = uint8_t{0xFF};
}
}
@AntoinePrv

Copy link
Copy Markdown
CollaboratorAuthor

@pitrou this is ready

rle_size_t batch_size) -> rle_size_t {
using ControlFlow = RleBitPackedParser::ControlFlow;

if (ARROW_PREDICT_FALSE(batch_size == 0 || exhausted())) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason this became necessary?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Came from the Copilot review, which I found to be relevant. I may not be a possible path in practice in all of Arrow, but better safe than sorry.

Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
CopilotAI review requested due to automatic review settings June 22, 2026 09:22

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment threadcpp/src/arrow/util/rle_bitmap_internal.h
Comment threadcpp/src/arrow/util/bit_util.h Outdated

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update @AntoinePrv !

Comment threadcpp/src/arrow/util/bit_util.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h Outdated
/// Make a vector of `size` pseudo-random bytes, deterministic for a given `seed`.
std::vector<uint8_t> MakeRandomBytes(size_t size, uint32_t seed = 56) {
std::vector<uint8_t> bytes(size);
std::minstd_rand gen(seed);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, the default_random_engine might give better randomness, though not sure it's useful here.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I picked this one because it is small and cheap and I assume sufficient here.

Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
Comment threadcpp/src/arrow/util/rle_bitmap_test.cc Outdated
CopilotAI review requested due to automatic review settings June 23, 2026 11:57

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment on lines +83 to +90
void Reset(const RunType& run) noexcept {
values_left_ = run.values_count();
if (run.value_little_endian() == 0) {
value_pattern_ = uint8_t{0};
} else {
value_pattern_ = uint8_t{0xFF};
}
}
@AntoinePrv

Copy link
Copy Markdown
CollaboratorAuthor

@pitrou this is ready

@pitrou

Copy link
Copy Markdown
Member

@AntoinePrv Note there is a compilation error on MSVC.

@pitrou

Copy link
Copy Markdown
Member

@github-actions crossbow submit -g cpp

@pitroupitrou left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, but need to fix the MSVC-based CI build.

@github-actions

Copy link
Copy Markdown

Revision: 6fc9785

Submitted crossbow builds: ursacomputing/crossbow @ actions-fb93408670

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-debian-13-cpp-amd64GitHub Actions
test-debian-13-cpp-i386GitHub Actions
test-debian-experimental-cpp-gcc-15GitHub Actions
test-fedora-42-cppGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

CopilotAI review requested due to automatic review settings June 23, 2026 14:34
@pitrou

Copy link
Copy Markdown
Member

Other related failures:

  • this compilation error on Ubuntu 22.04
  • these Valgrind errors: I think you just have to implement a PrintTo for the new test parameter type(s) such that GTest doesn't read uninitialized memory

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment threadcpp/src/arrow/util/rle_bitmap_internal.h
Comment threadcpp/src/arrow/util/rle_bitmap_internal.h
Comment threadcpp/src/arrow/util/CMakeLists.txt
@AntoinePrv

Copy link
Copy Markdown
CollaboratorAuthor

@github-actions crossbow submit -g cpp

@github-actions

Copy link
Copy Markdown

Revision: 441408d

Submitted crossbow builds: ursacomputing/crossbow @ actions-632a7d9657

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-debian-13-cpp-amd64GitHub Actions
test-debian-13-cpp-i386GitHub Actions
test-debian-experimental-cpp-gcc-15GitHub Actions
test-fedora-42-cppGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

CopilotAI review requested due to automatic review settings June 25, 2026 09:21

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment threadcpp/src/arrow/util/rle_bitmap_internal.h
@AntoinePrv

Copy link
Copy Markdown
CollaboratorAuthor

@github-actions crossbow submit -g cpp

@github-actions

Copy link
Copy Markdown

Revision: e64924b

Submitted crossbow builds: ursacomputing/crossbow @ actions-3b12a273d8

TaskStatus
example-cpp-minimal-build-staticGitHub Actions
example-cpp-minimal-build-static-system-dependencyGitHub Actions
example-cpp-tutorialGitHub Actions
test-build-cpp-fuzzGitHub Actions
test-conda-cppGitHub Actions
test-conda-cpp-valgrindGitHub Actions
test-debian-13-cpp-amd64GitHub Actions
test-debian-13-cpp-i386GitHub Actions
test-debian-experimental-cpp-gcc-15GitHub Actions
test-fedora-42-cppGitHub Actions
test-ubuntu-22.04-cppGitHub Actions
test-ubuntu-22.04-cpp-bundledGitHub Actions
test-ubuntu-22.04-cpp-emscriptenGitHub Actions
test-ubuntu-22.04-cpp-no-threadingGitHub Actions
test-ubuntu-24.04-cppGitHub Actions
test-ubuntu-24.04-cpp-bundled-offlineGitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundledGitHub Actions
test-ubuntu-24.04-cpp-gcc-14GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formatsGitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizerGitHub Actions

@pitrou

Copy link
Copy Markdown
Member

Thanks for fixing CI @AntoinePrv , I'll merge now!

@pitrou
pitrou merged commit e74bb67 into apache:mainJun 25, 2026
53 of 55 checks passed
@pitroupitrou removed the awaiting committer review Awaiting committer review label Jun 25, 2026
@AntoinePrv
AntoinePrv deleted the rle-bitmap branch June 25, 2026 10:51
@raulcd

raulcd commented Jun 25, 2026

Copy link
Copy Markdown
Member

This PR seems to have broken the documentation CI jobs:

+ doxygen
/arrow/cpp/apidoc /
/arrow/cpp/src/arrow/util/bit_util.h:249: error: Unsupported xml/html tag <typename> found (warning treated as error, aborting now)
Error: `docker compose --file=/home/runner/work/arrow/arrow/compose.yaml run --rm conda-python-docs` exited with a non-zero exit code 1, see the process log above.

I'll open an issue, I am trying to understand what is the problem

edit: opened: #50257

@conbench-apache-arrow

Copy link
Copy Markdown

After merging your PR, Conbench analyzed the 4 benchmarking runs that have been run so far on merge-commit e74bb67.

There were no benchmark performance regressions. 🎉

The full Conbench report has more details. It also includes information about 1 possible false positive for unstable benchmarks that are known to sometimes produce them.

tadeja pushed a commit to tadeja/arrow that referenced this pull request Jun 27, 2026
…e#50217)
### Rationale for this change
Add a `RleBitPackedToBitmapDecoder` capable of decoding a Parquet mixed Rle / BitPacked byte stream directly into a bitmap. This is an optimization to be used when target and source bit_width = 1 that will improve decoding nullable columns in a follow-up PR.
### What changes are included in this PR?
New classes, that reuse previous Runs and parser.
Their API is slighly different from the existing one as it fits a partilcular case.
- `RleRunToBitmapDecoder`
- `BitPackedRunToBitmapDecoder`
- `RleRunToBitmapDecoder`
### Are these changes tested?
Yes.
### Are there any user-facing changes?
No.
* GitHub Issue: apache#50216
Authored-by: AntoinePrv <AntoinePrv@users.noreply.github.com>
Signed-off-by: Antoine Pitrou <antoine@python.org>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@AntoinePrv@pitrou@raulcd