Asynchronous Compression Interface Call in Non-Polling Mode
This section describes how to call interfaces to asynchronously compress data in non-polling mode and obtain the compression result from the callback.
Asynchronous compression interfaces in frame format are used as an example.
- Compress a segment of memory and specify the frame format.
- After receiving the callback, decompress the content using open-source frame decompression interfaces.
- Compare the decompressed content with the original content.
The detailed code, compilation, and running procedure are as follows.
- Create a main.c file.
- Press i to enter the insert mode and write the following content to the file.
#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; // Whether the asynchronous callback is complete. The value needs to be initialized to 0. // User-defined data record struct my_custom_data { void *src; void *dst; void *src_decompd; size_t src_len; size_t dst_len; size_t src_decompd_len; }; // Generate 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() % 10; } } 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; // Decompresse data using LZ4. size_t tmp_src_len = result->src_size * 10; // Allocate 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); } // Compare 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"); } // Release 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 = 256 * 1024; // 256KB void *inbuf = malloc(src_len); if (!inbuf) { printf("Memory allocation failed for input data.\n"); return -1; } // Generate random data. generate_random_data(inbuf, src_len); // Allocate 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; } // Initialize LZ4F compression parameters. LZ4F_preferences_t preferences = {0}; preferences.frameInfo.blockSizeID = LZ4F_max64KB; // Set the block size. if (contentChecksumFlag) { preferences.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled; } if (blockChecksumFlag) { preferences.frameInfo.blockChecksumFlag = LZ4F_blockChecksumEnabled; } if (contentSizeFlag) { preferences.frameInfo.contentSize = src_len; } // Perform asynchronous compression. struct kaelz4_result result = {0}; struct my_custom_data mydata = {0}; struct kaelz4_buffer_list src = {0}; struct kaelz4_buffer src_buf[128]; src.usr_data = &mydata; src.buf_num = 1; src.buf = src_buf; src.buf[0].data = inbuf; src.buf[0].buf_len = src_len; struct kaelz4_buffer dst_buf[128]; struct kaelz4_buffer_list dst = {0}; dst.buf_num = 1; dst.buf = dst_buf; dst.buf[0].data = compressed_data; dst.buf[0].buf_len = compressed_size; 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(NULL); int compression_status = LZ4F_compressFrame_async(&src, &dst, 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); } - Press Esc, type :wq!, and press Enter to save the file and exit.
- Compile the main.c file.
gcc main.c -I/usr/local/kaelz4/include -L/usr/local/kaelz4/lib -llz4 -o kaelz4_frame_async_test
- Run the test file.
export LD_LIBRARY_PATH=/usr/local/kaelz4/lib:$LD_LIBRARY_PATH ./kaelz4_frame_async_test
"Test Success" is displayed.