Using Asynchronous Interfaces
This section describes how to use asynchronous interfaces of the KAELz4 library.
- Compile and install the software based on Software Installation (KAE 2.0).
- At the application layer, the locations of libkaelz4.so and the KAELz4 asynchronous header file are specified during compilation. The following compilation options are used for linking:
1-I/usr/local/kaelz4/include -L/usr/local/kaelz4/lib -llz4
Set environment variables.
1 2
export LD_LIBRARY_PATH=/usr/local/kaelz4/lib:$LD_LIBRARY_PATH export C_INCLUDE_PATH=/usr/local/kaelz4/include:$C_INCLUDE_PATH
- Write compression code main.c using asynchronous interfaces. The following is a code sample for compression in frame mode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <lz4.h> #include <lz4frame.h> #include <unistd.h> #include <sys/stat.h> int g_has_done = 0; // Indicates whether the asynchronous callback is complete. The value needs to be initialized to 0. int g_test_file = 0; // Indicates whether to use file-based testing. struct my_custom_data { void *src; void *dst; void *src_decompd; size_t src_len; size_t dst_len; size_t src_decompd_len; }; // Generates 256 KB random data. static void generate_random_data(void *data, size_t size) { unsigned char *bytes = (unsigned char *)data; for (size_t i = 0; i < size; i++) { bytes[i] = rand() % 256; // Generates random byte values. } } static size_t read_inputFile(const char* fileName, void** input) { FILE* sourceFile = fopen(fileName, "r"); if (sourceFile == NULL) { fprintf(stderr, "%s not exist!\n", fileName); return 0; } int fd = fileno(sourceFile); struct stat fs; (void)fstat(fd, &fs); size_t input_size = fs.st_size; *input = malloc(input_size); if (*input == NULL) { return 0; } (void)fread(*input, 1, input_size, sourceFile); fclose(sourceFile); return input_size; } void compression_callback(struct kaelz4_result *result) { if (result->status != 0) { printf("Compression failed with status: %d\n", result->status); return; } // Obtain compressed data from the callback. struct my_custom_data *my_data = (struct my_custom_data *)result->user_data; void *compressed_data = my_data->dst; size_t compressed_size = result->dst_len; my_data->dst_len = compressed_size; // Decompresses data using LZ4. size_t tmp_src_len = result->src_size * 10; // Allocates memory for decompressed data. void *dst_buffer = malloc(tmp_src_len); if (!dst_buffer) { printf("Memory allocation failed for decompressed data.\n"); return; } LZ4F_decompressionContext_t dctx; LZ4F_createDecompressionContext(&dctx, 100); int ret = LZ4F_decompress(dctx, dst_buffer, &tmp_src_len, compressed_data, &compressed_size, NULL); if (ret < 0) { printf("Decompression failed with error code: %d\n", ret); free(dst_buffer); return; } my_data->src_decompd = dst_buffer; my_data->src_decompd_len = tmp_src_len; if (my_data->src_decompd_len != my_data->src_len) { printf("Test Error: The length after decompression is different from the original length. result->src_size=%ld Original length=%ld Length after decompression=%ld \n", result->src_size, my_data->src_len, my_data->src_decompd_len); } // Compares the decompressed data with the original data. if (memcmp(my_data->src_decompd, my_data->src, result->src_size) == 0) { printf("Test Success.\n"); } else { printf("Test Error:Decompressed data does not match the original data.\n"); } // Releases decompressed data. free(dst_buffer); g_has_done = 1; } static int test_async_frame_with_perferences(int contentChecksumFlag, int blockChecksumFlag, int contentSizeFlag) { g_has_done = 0; size_t src_len = 258 * 1024; // 256KB void *inbuf = malloc(src_len); if (!inbuf) { printf("Memory allocation failed for input data.\n"); return -1; } // Generates random data. generate_random_data(inbuf, src_len); if (g_test_file) { src_len = read_inputFile("../../../scripts/compressTestDataset/x-ray", &inbuf); } // Allocates memory for compressed data. size_t compressed_size = LZ4F_compressBound(src_len, NULL); void *compressed_data = malloc(compressed_size); if (!compressed_data) { printf("Memory allocation failed for compressed data.\n"); free(inbuf); return -1; } // Initializes LZ4F compression parameters. LZ4F_preferences_t preferences = {0}; preferences.frameInfo.blockSizeID = LZ4F_max64KB; // Sets the block size. if (contentChecksumFlag) { preferences.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled; } if (blockChecksumFlag) { preferences.frameInfo.blockChecksumFlag = LZ4F_blockChecksumEnabled; } if (contentSizeFlag) { preferences.frameInfo.contentSize = src_len; } // Performs asynchronous compression. struct kaelz4_result result = {0}; struct my_custom_data mydata = {0}; mydata.src = inbuf; mydata.src_len = src_len; mydata.dst = compressed_data; result.user_data = &mydata; result.src_size = src_len; result.dst_len = compressed_size; LZ4_async_compress_init(); int compression_status = LZ4F_compressFrame_async(inbuf, compressed_data, compression_callback, &result, &preferences); if (compression_status != 0) { printf("Compression failed with error code: %d\n", compression_status); free(inbuf); free(compressed_data); return -1; } while (g_has_done != 1) { usleep(100); } LZ4_teardown_async_compress(); return compression_status; } int main() { return test_async_frame_with_perferences(1, 1, 1); }
- Compile and run the code.
1 2
gcc main.c -I/usr/local/kaelz4/include -L/usr/local/kaelz4/lib -llz4 -o kaelz4_frame_async_test ./kaelz4_frame_async_test
Command output:
1Test Success.
Parent topic: Using the KAELz4 Library