Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Improve `RunLengthBitPackingHybridDecoder.readNext` to avoid per-call buffer allocation and `DataInputStream` wrapping

Open Beginner friendly
#3,466 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
74/100
Issue type
Refactor
Clarity
Clearly specified
Activity status
Quiet
Tech stack
java
Domain
data

Research direction

Start in parquet-column/src/main/java/org/apache/parquet/column/values/rle/RunLengthBitPackingHybridDecoder.java, focusing on the PACKED-mode path in readNext() around lines 94–98 and the existing TODO. Trace how buffers and input reads are used, then run the relevant decoder tests. Done means repeated PACKED-mode calls reuse sufficiently sized buffers without per-call DataInputStream wrappers while preserving decoding behavior.

Written by the indexing model from the issue text.

Description

Type: enhancement
Describe the enhancement requested

RunLengthBitPackingHybridDecoder.readNext() allocates a new int[] and byte[] on every PACKED-mode call. In workloads that decode many bit-packed runs (definition levels, repetition levels, RLE-encoded integers), these allocations dominate the read-side allocation profile. The upstream code even acknowledges this with a // TODO: reuse a buffer comment.

Problem 1: per-call buffer allocation

Lines 94–95 allocate fresh arrays on every PACKED-mode readNext():

currentBuffer = new int[currentCount]; // TODO: reuse a buffer
byte[] bytes = new byte[numGroups * bitWidth];

currentCount is always numGroups * 8, and numGroups is typically small (1–16 groups = 8–128 values per run). These allocations are individually modest but occur thousands of times per column chunk — once per bit-packed run. In a 180M-row merge with multiple integer/boolean columns, the cumulative allocation is substantial.

Since currentCount varies between runs (different numGroups values), the fix retains the field-level int[] and a new field-level byte[], growing them only when the next run requires a larger buffer.

Problem 2: per-call DataInputStream wrapping

Line 98 creates a new DataInputStream(in) on every PACKED-mode call:

new DataInputStream(in).readFully(bytes, 0, bytesToRead);

This allocates a DataInputStream wrapper object per call just to access readFully(). A private readFully() method on the decoder itself eliminates this allocation and the virtual dispatch through the wrapper.

Component(s)

Core

Dominant language
Java
Stars
3.1k
Forks
1.6k
Avg merge
4d 12h
Merged PRs (30d)
28

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/parquet-java

All issues in apache/parquet-java

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.