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

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-java.git


The following commit(s) were added to refs/heads/main by this push:
     new b0e51af85 GH-1116: [Java] Fix compressed buffer prefix write and ZSTD 
dstCapacity (#1119)
b0e51af85 is described below

commit b0e51af855ef5befac903b1a6de3f535258ccd1b
Author: YangJie <[email protected]>
AuthorDate: Tue Jun 30 12:40:01 2026 +0800

    GH-1116: [Java] Fix compressed buffer prefix write and ZSTD dstCapacity 
(#1119)
    
    ## What
    
    Two fixes in the compression codec:
    
    1. **`AbstractCompressionCodec.compress()`: capture `writerIndex()`
    once**
    
    The previous code read `uncompressedBuffer.writerIndex()` at multiple
    sites — for the size comparison and again after `doCompress()` to
    populate the 8-byte uncompressed-length prefix. Capture the value once
    at the top of `compress()` and reuse it for the empty-buffer check, the
    size comparison, and the prefix, so all three consumers see the same
    value.
    
    2. **`ZstdCompressionCodec.doCompress()`: `dstCapacity` overstated by 8
    bytes**
    
    `Zstd.compressUnsafe(dst, dstSize, ...)` expects `dstSize` to be the
    available space from `dst`. The code offsets `dst` by 8 bytes past the
    prefix but passed `8 + maxSize` instead of `maxSize`. The
    `compressBound()` headroom hides this in practice, but the parameter was
    semantically wrong. Pass `maxSize`.
    
    ## Tests
    
    Covered by the existing round-trip tests (`testEmptyBuffer`,
    `testReadWriteStream`, `testReadWriteFile`, etc.). I was not able to
    construct a minimal reproducer for the original `declaredUncompressed=0`
    symptom on the unfixed code, so both fixes are conservative correctness
    improvements derived from code inspection rather than failing-then-green
    regression tests.
---
 .../java/org/apache/arrow/compression/ZstdCompressionCodec.java    | 2 +-
 .../apache/arrow/vector/compression/AbstractCompressionCodec.java  | 7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git 
a/compression/src/main/java/org/apache/arrow/compression/ZstdCompressionCodec.java
 
b/compression/src/main/java/org/apache/arrow/compression/ZstdCompressionCodec.java
index 290723608..ed46fe81b 100644
--- 
a/compression/src/main/java/org/apache/arrow/compression/ZstdCompressionCodec.java
+++ 
b/compression/src/main/java/org/apache/arrow/compression/ZstdCompressionCodec.java
@@ -44,7 +44,7 @@ public class ZstdCompressionCodec extends 
AbstractCompressionCodec {
     long bytesWritten =
         Zstd.compressUnsafe(
             compressedBuffer.memoryAddress() + 
CompressionUtil.SIZE_OF_UNCOMPRESSED_LENGTH,
-            dstSize,
+            maxSize,
             /*src*/ uncompressedBuffer.memoryAddress(),
             /* srcSize= */ uncompressedBuffer.writerIndex(),
             /* level= */ this.compressionLevel);
diff --git 
a/vector/src/main/java/org/apache/arrow/vector/compression/AbstractCompressionCodec.java
 
b/vector/src/main/java/org/apache/arrow/vector/compression/AbstractCompressionCodec.java
index 58d9e4db9..b108173c8 100644
--- 
a/vector/src/main/java/org/apache/arrow/vector/compression/AbstractCompressionCodec.java
+++ 
b/vector/src/main/java/org/apache/arrow/vector/compression/AbstractCompressionCodec.java
@@ -29,7 +29,11 @@ public abstract class AbstractCompressionCodec implements 
CompressionCodec {
 
   @Override
   public ArrowBuf compress(BufferAllocator allocator, ArrowBuf 
uncompressedBuffer) {
-    if (uncompressedBuffer.writerIndex() == 0L) {
+    // GH-1116: capture writerIndex() once so the empty-buffer check, size
+    // comparison, and uncompressed-length prefix all see the same value.
+    long uncompressedLength = uncompressedBuffer.writerIndex();
+
+    if (uncompressedLength == 0L) {
       // shortcut for empty buffer
       ArrowBuf compressedBuffer = 
allocator.buffer(CompressionUtil.SIZE_OF_UNCOMPRESSED_LENGTH);
       compressedBuffer.setLong(0, 0);
@@ -41,7 +45,6 @@ public abstract class AbstractCompressionCodec implements 
CompressionCodec {
     ArrowBuf compressedBuffer = doCompress(allocator, uncompressedBuffer);
     long compressedLength =
         compressedBuffer.writerIndex() - 
CompressionUtil.SIZE_OF_UNCOMPRESSED_LENGTH;
-    long uncompressedLength = uncompressedBuffer.writerIndex();
 
     if (compressedLength > uncompressedLength) {
       // compressed buffer is larger, send the raw buffer

Reply via email to