|
@@ -0,0 +1,253 @@
|
|
|
+#if defined HAVE_CONFIG_H
|
|
|
+ #include <config.h>
|
|
|
+#endif
|
|
|
+
|
|
|
+#if defined HAVE_STDIO_H
|
|
|
+ #include <stdio.h>
|
|
|
+#else
|
|
|
+ #error 'stdio.h not found'
|
|
|
+#endif
|
|
|
+
|
|
|
+#if defined HAVE_STDLIB_H
|
|
|
+ #include <stdlib.h>
|
|
|
+#else
|
|
|
+ #error 'stdlib.h not found'
|
|
|
+#endif
|
|
|
+
|
|
|
+#include "org_apache_hadoop_io_compress_lzo.h"
|
|
|
+
|
|
|
+// The lzo2 library-handle
|
|
|
+static void *liblzo2 = NULL;
|
|
|
+
|
|
|
+// The lzo 'compressors'
|
|
|
+typedef struct {
|
|
|
+ const char *function; // The compression function
|
|
|
+ int wrkmem; // The 'working memory' needed
|
|
|
+ int compression_level; // Compression level if required;
|
|
|
+ // else UNDEFINED_COMPRESSION_LEVEL
|
|
|
+} lzo_compressor;
|
|
|
+
|
|
|
+#define UNDEFINED_COMPRESSION_LEVEL -999
|
|
|
+
|
|
|
+static lzo_compressor lzo_compressors[] = {
|
|
|
+ /** lzo1 compressors */
|
|
|
+ /* 0 */ {"lzo1_compress", LZO1_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 1 */ {"lzo1_99_compress", LZO1_99_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1a compressors */
|
|
|
+ /* 2 */ {"lzo1a_compress", LZO1A_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 3 */ {"lzo1a_99_compress", LZO1A_99_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1b compressors */
|
|
|
+ /* 4 */ {"lzo1b_compress", LZO1B_MEM_COMPRESS, LZO1B_DEFAULT_COMPRESSION},
|
|
|
+ /* 5 */ {"lzo1b_compress", LZO1B_MEM_COMPRESS, LZO1B_BEST_SPEED},
|
|
|
+ /* 6 */ {"lzo1b_compress", LZO1B_MEM_COMPRESS, LZO1B_BEST_COMPRESSION},
|
|
|
+ /* 7 */ {"lzo1b_1_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 8 */ {"lzo1b_2_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 9 */ {"lzo1b_3_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 10 */ {"lzo1b_4_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 11 */ {"lzo1b_5_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 12 */ {"lzo1b_6_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 13 */ {"lzo1b_7_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 14 */ {"lzo1b_8_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 15 */ {"lzo1b_9_compress", LZO1B_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 16 */ {"lzo1b_99_compress", LZO1B_99_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 17 */ {"lzo1b_999_compress", LZO1B_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1c compressors */
|
|
|
+ /* 18 */ {"lzo1c_compress", LZO1C_MEM_COMPRESS, LZO1C_DEFAULT_COMPRESSION},
|
|
|
+ /* 19 */ {"lzo1c_compress", LZO1C_MEM_COMPRESS, LZO1C_BEST_SPEED},
|
|
|
+ /* 20 */ {"lzo1c_compress", LZO1C_MEM_COMPRESS, LZO1C_BEST_COMPRESSION},
|
|
|
+ /* 21 */ {"lzo1c_1_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 22 */ {"lzo1c_2_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 23 */ {"lzo1c_3_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 24 */ {"lzo1c_4_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 25 */ {"lzo1c_5_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 26 */ {"lzo1c_6_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 27 */ {"lzo1c_7_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 28 */ {"lzo1c_8_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 29 */ {"lzo1c_9_compress", LZO1C_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 30 */ {"lzo1c_99_compress", LZO1C_99_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 31 */ {"lzo1c_999_compress", LZO1C_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1f compressors */
|
|
|
+ /* 32 */ {"lzo1f_1_compress", LZO1F_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 33 */ {"lzo1f_999_compress", LZO1F_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1x compressors */
|
|
|
+ /* 34 */ {"lzo1x_1_compress", LZO1X_1_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 35 */ {"lzo1x_11_compress", LZO1X_1_11_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 36 */ {"lzo1x_12_compress", LZO1X_1_12_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 37 */ {"lzo1x_15_compress", LZO1X_1_15_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 38 */ {"lzo1x_999_compress", LZO1X_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1y compressors */
|
|
|
+ /* 39 */ {"lzo1y_1_compress", LZO1Y_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+ /* 40 */ {"lzo1y_999_compress", LZO1Y_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo1z compressors */
|
|
|
+ /* 41 */ {"lzo1z_999_compress", LZO1Z_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+
|
|
|
+ /** lzo2a compressors */
|
|
|
+ /* 42 */ {"lzo2a_999_compress", LZO2A_999_MEM_COMPRESS, UNDEFINED_COMPRESSION_LEVEL},
|
|
|
+};
|
|
|
+
|
|
|
+// The second lzo* compressor prototype - this really should be in lzoconf.h!
|
|
|
+typedef int
|
|
|
+(__LZO_CDECL *lzo_compress2_t) ( const lzo_bytep src, lzo_uint src_len,
|
|
|
+ lzo_bytep dst, lzo_uintp dst_len,
|
|
|
+ lzo_voidp wrkmem, int compression_level );
|
|
|
+
|
|
|
+static jfieldID LzoCompressor_finish;
|
|
|
+static jfieldID LzoCompressor_finished;
|
|
|
+static jfieldID LzoCompressor_uncompressedDirectBuf;
|
|
|
+static jfieldID LzoCompressor_uncompressedDirectBufLen;
|
|
|
+static jfieldID LzoCompressor_compressedDirectBuf;
|
|
|
+static jfieldID LzoCompressor_directBufferSize;
|
|
|
+static jfieldID LzoCompressor_lzoCompressor;
|
|
|
+static jfieldID LzoCompressor_workingMemoryBufLen;
|
|
|
+static jfieldID LzoCompressor_workingMemoryBuf;
|
|
|
+
|
|
|
+JNIEXPORT void JNICALL
|
|
|
+Java_org_apache_hadoop_io_compress_lzo_LzoCompressor_initIDs(
|
|
|
+ JNIEnv *env, jclass class
|
|
|
+ ) {
|
|
|
+ // Load liblzo2.so
|
|
|
+ liblzo2 = dlopen(HADOOP_LZO_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
|
|
|
+ if (!liblzo2) {
|
|
|
+ THROW(env, "java/lang/UnsatisfiedLinkError", "Cannot load liblzo2.so!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ LzoCompressor_finish = (*env)->GetFieldID(env, class, "finish", "Z");
|
|
|
+ LzoCompressor_finished = (*env)->GetFieldID(env, class, "finished", "Z");
|
|
|
+ LzoCompressor_uncompressedDirectBuf = (*env)->GetFieldID(env, class,
|
|
|
+ "uncompressedDirectBuf",
|
|
|
+ "Ljava/nio/Buffer;");
|
|
|
+ LzoCompressor_uncompressedDirectBufLen = (*env)->GetFieldID(env, class,
|
|
|
+ "uncompressedDirectBufLen", "I");
|
|
|
+ LzoCompressor_compressedDirectBuf = (*env)->GetFieldID(env, class,
|
|
|
+ "compressedDirectBuf",
|
|
|
+ "Ljava/nio/Buffer;");
|
|
|
+ LzoCompressor_directBufferSize = (*env)->GetFieldID(env, class,
|
|
|
+ "directBufferSize", "I");
|
|
|
+ LzoCompressor_lzoCompressor = (*env)->GetFieldID(env, class,
|
|
|
+ "lzoCompressor", "J");
|
|
|
+ LzoCompressor_workingMemoryBufLen = (*env)->GetFieldID(env, class,
|
|
|
+ "workingMemoryBufLen", "I");
|
|
|
+ LzoCompressor_workingMemoryBuf = (*env)->GetFieldID(env, class,
|
|
|
+ "workingMemoryBuf",
|
|
|
+ "Ljava/nio/Buffer;");
|
|
|
+}
|
|
|
+
|
|
|
+JNIEXPORT void JNICALL
|
|
|
+Java_org_apache_hadoop_io_compress_lzo_LzoCompressor_init(
|
|
|
+ JNIEnv *env, jobject this, jint compressor
|
|
|
+ ) {
|
|
|
+ const char *lzo_compressor_function = lzo_compressors[compressor].function;
|
|
|
+
|
|
|
+ // Locate the requisite symbols from liblzo2.so
|
|
|
+ dlerror(); // Clear any existing error
|
|
|
+
|
|
|
+ // Initialize the lzo library
|
|
|
+ void *lzo_init_func_ptr = NULL;
|
|
|
+ typedef int (__LZO_CDECL *lzo_init_t) (unsigned,int,int,int,int,int,int,int,int,int);
|
|
|
+ LOAD_DYNAMIC_SYMBOL(lzo_init_func_ptr, env, liblzo2, "__lzo_init_v2");
|
|
|
+ lzo_init_t lzo_init_function = (lzo_init_t)(lzo_init_func_ptr);
|
|
|
+ int rv = lzo_init_function(LZO_VERSION, (int)sizeof(short), (int)sizeof(int),
|
|
|
+ (int)sizeof(long), (int)sizeof(lzo_uint32), (int)sizeof(lzo_uint),
|
|
|
+ (int)lzo_sizeof_dict_t, (int)sizeof(char*), (int)sizeof(lzo_voidp),
|
|
|
+ (int)sizeof(lzo_callback_t));
|
|
|
+ if (rv != LZO_E_OK) {
|
|
|
+ THROW(env, "Ljava/lang/InternalError", "Could not initialize lzo library!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Save the compressor-function into LzoCompressor_lzoCompressor
|
|
|
+ void *compressor_func_ptr = NULL;
|
|
|
+ LOAD_DYNAMIC_SYMBOL(compressor_func_ptr, env, liblzo2, lzo_compressor_function);
|
|
|
+ (*env)->SetLongField(env, this, LzoCompressor_lzoCompressor,
|
|
|
+ JLONG(compressor_func_ptr));
|
|
|
+
|
|
|
+ // Save the compressor-function into LzoCompressor_lzoCompressor
|
|
|
+ (*env)->SetIntField(env, this, LzoCompressor_workingMemoryBufLen,
|
|
|
+ lzo_compressors[compressor].wrkmem);
|
|
|
+
|
|
|
+ return;
|
|
|
+}
|
|
|
+
|
|
|
+JNIEXPORT jint JNICALL
|
|
|
+Java_org_apache_hadoop_io_compress_lzo_LzoCompressor_compressBytesDirect(
|
|
|
+ JNIEnv *env, jobject this, jint compressor
|
|
|
+ ) {
|
|
|
+ const char *lzo_compressor_function = lzo_compressors[compressor].function;
|
|
|
+
|
|
|
+ // Get members of LzoCompressor
|
|
|
+ jobject uncompressed_direct_buf = (*env)->GetObjectField(env, this,
|
|
|
+ LzoCompressor_uncompressedDirectBuf);
|
|
|
+ lzo_uint uncompressed_direct_buf_len = (*env)->GetIntField(env, this,
|
|
|
+ LzoCompressor_uncompressedDirectBufLen);
|
|
|
+
|
|
|
+ jobject compressed_direct_buf = (*env)->GetObjectField(env, this,
|
|
|
+ LzoCompressor_compressedDirectBuf);
|
|
|
+ lzo_uint compressed_direct_buf_len = (*env)->GetIntField(env, this,
|
|
|
+ LzoCompressor_directBufferSize);
|
|
|
+
|
|
|
+ jobject working_memory_buf = (*env)->GetObjectField(env, this,
|
|
|
+ LzoCompressor_workingMemoryBuf);
|
|
|
+
|
|
|
+ jlong lzo_compressor_funcptr = (*env)->GetLongField(env, this,
|
|
|
+ LzoCompressor_lzoCompressor);
|
|
|
+
|
|
|
+ // Get direct buffers
|
|
|
+ lzo_bytep uncompressed_bytes = (*env)->GetDirectBufferAddress(env,
|
|
|
+ uncompressed_direct_buf);
|
|
|
+ if (uncompressed_bytes == 0) {
|
|
|
+ return (jint)0;
|
|
|
+ }
|
|
|
+
|
|
|
+ lzo_bytep compressed_bytes = (*env)->GetDirectBufferAddress(env,
|
|
|
+ compressed_direct_buf);
|
|
|
+ if (compressed_bytes == 0) {
|
|
|
+ return (jint)0;
|
|
|
+ }
|
|
|
+
|
|
|
+ lzo_voidp workmem = (*env)->GetDirectBufferAddress(env, working_memory_buf);
|
|
|
+ if (workmem == 0) {
|
|
|
+ return (jint)0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Compress
|
|
|
+ lzo_uint no_compressed_bytes = compressed_direct_buf_len;
|
|
|
+ int rv = 0;
|
|
|
+ int compression_level = lzo_compressors[compressor].compression_level;
|
|
|
+ if (compression_level == UNDEFINED_COMPRESSION_LEVEL) {
|
|
|
+ lzo_compress_t fptr = (lzo_compress_t) FUNC_PTR(lzo_compressor_funcptr);
|
|
|
+ rv = fptr(uncompressed_bytes, uncompressed_direct_buf_len,
|
|
|
+ compressed_bytes, &no_compressed_bytes,
|
|
|
+ workmem);
|
|
|
+ } else {
|
|
|
+ lzo_compress2_t fptr = (lzo_compress2_t) FUNC_PTR(lzo_compressor_funcptr);
|
|
|
+ rv = fptr(uncompressed_bytes, uncompressed_direct_buf_len,
|
|
|
+ compressed_bytes, &no_compressed_bytes,
|
|
|
+ workmem, compression_level);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rv == LZO_E_OK) {
|
|
|
+ // lzo compresses all input data
|
|
|
+ (*env)->SetIntField(env, this,
|
|
|
+ LzoCompressor_uncompressedDirectBufLen, 0);
|
|
|
+ } else {
|
|
|
+ const int msg_len = 32;
|
|
|
+ char exception_msg[msg_len];
|
|
|
+ snprintf(exception_msg, msg_len, "%s returned: %d", lzo_compressor_function, rv);
|
|
|
+ THROW(env, "java/lang/InternalError", exception_msg);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (jint)no_compressed_bytes;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * vim: sw=2: ts=2: et:
|
|
|
+ */
|
|
|
+
|