2026년 1월 13일 화요일

압축 해제 thread local 사용

 import net.jpountz.lz4.*;

import com.github.luben.zstd.Zstd;

import java.nio.charset.StandardCharsets;


public class CompressedRedisClient {

    // 1. LZ4 공용 팩토리 (Thread-safe)

    private static final LZ4Factory lz4Factory = LZ4Factory.fastestInstance();

    private static final LZ4Compressor lz4Compressor = lz4Factory.fastCompressor();

    private static final LZ4SafeDecompressor lz4Decompressor = lz4Factory.safeDecompressor();


    // 2. ThreadLocal을 이용한 재사용 버퍼 (64KB 기준, 필요시 자동 확장 가능)

    private static final ThreadLocal<byte[]> BUFFER_CACHE = ThreadLocal.withInitial(() -> new byte[64 * 1024]);


    private static byte[] getBuffer(int size) {

        byte[] buf = BUFFER_CACHE.get();

        if (buf.length < size) {

            buf = new byte[size];

            BUFFER_CACHE.set(buf);

        }

        return buf;

    }


    /**

     * LZ4 압축 (Thread-local 버퍼 활용)

     */

    public byte[] compressLZ4(String input) {

        byte[] data = input.getBytes(StandardCharsets.UTF_8);

        int maxLen = lz4Compressor.maxCompressedLength(data.length);

        

        // 버퍼 재사용

        byte[] outputBuffer = getBuffer(maxLen);

        int compressedLen = lz4Compressor.compress(data, 0, data.length, outputBuffer, 0, maxLen);


        // 실제 압축된 크기만큼만 복사해서 반환 (레디스 저장용)

        byte[] result = new byte[compressedLen];

        System.arraycopy(outputBuffer, 0, result, 0, compressedLen);

        return result;

    }


    /**

     * Zstd 압축 해제 (Thread-local 버퍼 활용)

     */

    public String decompressZstd(byte[] compressed, int originalLen) {

        // 원본 크기에 맞는 버퍼 확보

        byte[] decompressedBuffer = getBuffer(originalLen);

        

        // Zstd 해제 (버퍼에 직접 씀)

        Zstd.decompress(decompressedBuffer, compressed);


        return new String(decompressedBuffer, 0, originalLen, StandardCharsets.UTF_8);

    }

}


댓글 없음: