1818 */
1919package org .apache .parquet .hadoop .codec ;
2020
21- import io .airlift .compress .lz4 .Lz4Decompressor ;
21+ import io .airlift .compress .v3 . lz4 .Lz4Decompressor ;
2222import java .io .IOException ;
2323import java .nio .ByteBuffer ;
2424import org .apache .hadoop .io .compress .DirectDecompressor ;
2525
2626public class Lz4RawDecompressor extends NonBlockedDecompressor implements DirectDecompressor {
2727
28- private Lz4Decompressor decompressor = new Lz4Decompressor ();
28+ private final Lz4Decompressor decompressor = Lz4Decompressor .create ();
29+
30+ /** Reused for direct buffers; lazily allocated and grown when needed. */
31+ private byte [] inputBuf ;
32+ /** Reused for direct buffers; lazily allocated and grown when needed. */
33+ private byte [] outputBuf ;
2934
3035 @ Override
3136 protected int maxUncompressedLength (ByteBuffer compressed , int maxUncompressedLength ) throws IOException {
@@ -36,10 +41,34 @@ protected int maxUncompressedLength(ByteBuffer compressed, int maxUncompressedLe
3641
3742 @ Override
3843 protected int uncompress (ByteBuffer compressed , ByteBuffer uncompressed ) throws IOException {
39- decompressor .decompress (compressed , uncompressed );
40- int uncompressedSize = uncompressed .position ();
41- uncompressed .limit (uncompressedSize );
42- uncompressed .rewind ();
44+ int startPos = uncompressed .position ();
45+ int compressedLen = compressed .remaining ();
46+ int maxOut = uncompressed .remaining ();
47+
48+ final int uncompressedSize ;
49+ if (compressed .hasArray () && uncompressed .hasArray ()) {
50+ int inputOffset = compressed .arrayOffset () + compressed .position ();
51+ int outputOffset = uncompressed .arrayOffset () + uncompressed .position ();
52+ uncompressedSize = decompressor .decompress (
53+ compressed .array (), inputOffset , compressedLen ,
54+ uncompressed .array (), outputOffset , maxOut );
55+ // Advance positions to match the direct-buffer path (where get/put do this)
56+ compressed .position (compressed .position () + compressedLen );
57+ } else {
58+ if (inputBuf == null || inputBuf .length < compressedLen ) {
59+ inputBuf = new byte [compressedLen ];
60+ }
61+ if (outputBuf == null || outputBuf .length < maxOut ) {
62+ outputBuf = new byte [maxOut ];
63+ }
64+ compressed .get (inputBuf , 0 , compressedLen );
65+ uncompressedSize = decompressor .decompress (
66+ inputBuf , 0 , compressedLen , outputBuf , 0 , maxOut );
67+ uncompressed .put (outputBuf , 0 , uncompressedSize );
68+ }
69+
70+ uncompressed .limit (startPos + uncompressedSize );
71+ uncompressed .position (startPos );
4372 return uncompressedSize ;
4473 }
4574
0 commit comments