Rate This Document
Findability
Accuracy
Completeness
Readability

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.

  1. Compress a segment of memory and specify the frame format.
  2. After receiving the callback, decompress the content using open-source frame decompression interfaces.
  3. Compare the decompressed content with the original content.

The detailed code, compilation, and running procedure are as follows.

  1. Create a main.c file.
  2. 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);
    }
  3. Press Esc, type :wq!, and press Enter to save the file and exit.
  4. Compile the main.c file.
    gcc main.c -I/usr/local/kaelz4/include -L/usr/local/kaelz4/lib -llz4 -o kaelz4_frame_async_test
  5. Run the test file.
    export LD_LIBRARY_PATH=/usr/local/kaelz4/lib:$LD_LIBRARY_PATH 
    ./kaelz4_frame_async_test

    "Test Success" is displayed.