Skip to content

Commit c864877

Browse files
PG1204jbonofre
authored andcommitted
GH-1196: Write NO_COMPRESSION_LENGTH sentinel for empty buffers in compress()
1 parent 4b2d53e commit c864877

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

‎compression/src/test/java/org/apache/arrow/compression/TestCompressionCodec.java‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,35 @@ void testEmptyBuffer(int vectorLength, CompressionCodec codec) throws Exception
256256
AutoCloseables.close(decompressedBuffers);
257257
}
258258

259+
static Stream<CompressionCodec> compressingCodecs() {
260+
return Stream.of(new Lz4CompressionCodec(), new ZstdCompressionCodec());
261+
}
262+
263+
@ParameterizedTest
264+
@MethodSource("compressingCodecs")
265+
void testEmptyBufferWritesUncompressedSentinel(CompressionCodec codec) {
266+
// GH-1196: an empty buffer must be encoded with the uncompressed-length
267+
// sentinel (-1), not 0. A 0 prefix is undefined in the Arrow IPC format and
268+
// is rejected by the C++ and Python implementations, even though Java itself
269+
// accepts it on read.
270+
ArrowBuf empty = allocator.buffer(1);
271+
empty.writerIndex(0);
272+
273+
// compress() takes ownership of and closes the input buffer
274+
ArrowBuf compressed = codec.compress(allocator, empty);
275+
276+
assertEquals(
277+
CompressionUtil.NO_COMPRESSION_LENGTH,
278+
compressed.getLong(0),
279+
"empty buffer must use the -1 uncompressed sentinel, not 0");
280+
281+
// and it must still round-trip back to an empty buffer
282+
ArrowBuf decompressed = codec.decompress(allocator, compressed);
283+
assertEquals(0L, decompressed.writerIndex());
284+
285+
decompressed.close();
286+
}
287+
259288
@Test
260289
void testLz4DecompressRejectsWrongLength() {
261290
byte[] data = new byte[512]; // all zeros, highly compressible

‎vector/src/main/java/org/apache/arrow/vector/compression/AbstractCompressionCodec.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public ArrowBuf compress(BufferAllocator allocator, ArrowBuf uncompressedBuffer)
3737
if (uncompressedLength == 0L) {
3838
// shortcut for empty buffer
3939
ArrowBuf compressedBuffer = allocator.buffer(CompressionUtil.SIZE_OF_UNCOMPRESSED_LENGTH);
40-
compressedBuffer.setLong(0, 0);
40+
compressedBuffer.setLong(0, CompressionUtil.NO_COMPRESSION_LENGTH);
4141
compressedBuffer.writerIndex(CompressionUtil.SIZE_OF_UNCOMPRESSED_LENGTH);
4242
return compressedBuffer;
4343
}

0 commit comments

Comments
 (0)