From 2d10bd95a7861bd574985983399a5397b3003908 Mon Sep 17 00:00:00 2001 From: Xiaoguang Sun Date: Sat, 16 Aug 2014 17:58:04 +0800 Subject: [PATCH] Use thread local state for high compressor Use thread local state for high compressor, this can reduce one memory allocation and free for each compress call to one memory allocation per thread. --- .../net/jpountz/lz4/LZ4HCJNICompressor.java | 9 +++++- src/java/net/jpountz/lz4/LZ4JNI.java | 3 +- src/jni/net_jpountz_lz4_LZ4JNI.c | 31 +++++++++++++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/java/net/jpountz/lz4/LZ4HCJNICompressor.java b/src/java/net/jpountz/lz4/LZ4HCJNICompressor.java index ec09353d..c07aabfd 100644 --- a/src/java/net/jpountz/lz4/LZ4HCJNICompressor.java +++ b/src/java/net/jpountz/lz4/LZ4HCJNICompressor.java @@ -24,11 +24,18 @@ final class LZ4HCJNICompressor extends LZ4Compressor { public static final LZ4Compressor INSTANCE = new LZ4HCJNICompressor(); + private static ThreadLocal state = new ThreadLocal() { + @Override + protected byte[] initialValue() { + return new byte[LZ4JNI.LZ4_sizeofStateHC()]; + } + }; + @Override public int compress(byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen) { checkRange(src, srcOff, srcLen); checkRange(dest, destOff, maxDestLen); - final int result = LZ4JNI.LZ4_compressHC(src, srcOff, srcLen, dest, destOff, maxDestLen); + final int result = LZ4JNI.LZ4_compressHC_withStateHC(state.get(), src, srcOff, srcLen, dest, destOff, maxDestLen); if (result <= 0) { throw new LZ4Exception(); } diff --git a/src/java/net/jpountz/lz4/LZ4JNI.java b/src/java/net/jpountz/lz4/LZ4JNI.java index 1c02ff1c..d462c565 100644 --- a/src/java/net/jpountz/lz4/LZ4JNI.java +++ b/src/java/net/jpountz/lz4/LZ4JNI.java @@ -30,7 +30,8 @@ enum LZ4JNI { static native void init(); static native int LZ4_compress_limitedOutput(byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen); - static native int LZ4_compressHC(byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen); + static native int LZ4_sizeofStateHC(); + static native int LZ4_compressHC_withStateHC(byte[] state, byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen); static native int LZ4_decompress_fast(byte[] src, int srcOff, byte[] dest, int destOff, int destLen); static native int LZ4_decompress_fast_withPrefix64k(byte[] src, int srcOff, byte[] dest, int destOff, int destLen); static native int LZ4_decompress_safe(byte[] src, int srcOff, int srcLen, byte[] dest, int destOff, int maxDestLen); diff --git a/src/jni/net_jpountz_lz4_LZ4JNI.c b/src/jni/net_jpountz_lz4_LZ4JNI.c index 8217ed17..82a57ee8 100644 --- a/src/jni/net_jpountz_lz4_LZ4JNI.c +++ b/src/jni/net_jpountz_lz4_LZ4JNI.c @@ -13,6 +13,7 @@ */ #include "lz4.h" +#include "lz4hc.h" #include "net_jpountz_lz4_LZ4JNI.h" static jclass OutOfMemoryError; @@ -64,17 +65,24 @@ JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compress_1limitedOutput } /* - * Class: net_jpountz_lz4_LZ4 - * Method: LZ4_compressHC - * Signature: ([BII[BI)I + * Class: net_jpountz_lz4_LZ4JNI + * Method: LZ4_compressHC_withStateHC + * Signature: ([B[BII[BII)I */ -JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compressHC - (JNIEnv *env, jclass cls, jbyteArray src, jint srcOff, jint srcLen, jbyteArray dest, jint destOff, jint maxDestLen) { +JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compressHC_1withStateHC + (JNIEnv *env, jclass cls, jbyteArray state, jbyteArray src, jint srcOff, jint srcLen, jbyteArray dest, jint destOff, jint maxDestLen) { + char* stateHC; char* in; char* out; jint compressed; + stateHC = (char*) (*env)->GetPrimitiveArrayCritical(env, state, 0); + if (stateHC == NULL) { + throw_OOM(env); + return 0; + } + in = (char*) (*env)->GetPrimitiveArrayCritical(env, src, 0); if (in == NULL) { throw_OOM(env); @@ -86,8 +94,9 @@ JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compressHC return 0; } - compressed = LZ4_compressHC_limitedOutput(in + srcOff, out + destOff, srcLen, maxDestLen); + compressed = LZ4_compressHC_limitedOutput_withStateHC(stateHC, in + srcOff, out + destOff, srcLen, maxDestLen); + (*env)->ReleasePrimitiveArrayCritical(env, state, stateHC, 0); (*env)->ReleasePrimitiveArrayCritical(env, src, in, 0); (*env)->ReleasePrimitiveArrayCritical(env, dest, out, 0); @@ -95,6 +104,16 @@ JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1compressHC } +/* + * Class: net_jpountz_lz4_LZ4JNI + * Method: LZ4_sizeofStateHC + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_net_jpountz_lz4_LZ4JNI_LZ4_1sizeofStateHC + (JNIEnv *env, jclass cls) { + return LZ4_sizeofStateHC(); +} + /* * Class: net_jpountz_lz4_LZ4 * Method: LZ4_decompress