Rate This Document
Findability
Accuracy
Completeness
Readability

Asynchronous Compression Interface Call in Polling Mode

This section describes interfaces required for compressing data into the standard lz4 block or frame format in polling mode and provides an example of using them.

The following code uses interfaces in polling mode, initializes the session context, calls asynchronous compression interfaces in frame format, actively polls the compression result, obtains the compression result in frame format from the callback, and decompresses it to the original data. 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>
    
    static int g_has_done = 0; // Whether the asynchronous callback is complete. The value needs to be initialized to 0.
    
    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() % 256;  // Generate random byte values.
        }
    }
    
    static void compression_callback2(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_frame_polling(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;
        }
    
        void *sess = KAELZ4_create_async_compress_session(NULL);
    
        // 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;
    
        int compression_status = KAELZ4_compress_frame_async_in_session(sess, &src, &dst,
                                                          compression_callback2, &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) {
            KAELZ4_async_polling_in_session(sess, 1);
            usleep(100);
        }
        KAELZ4_destroy_async_compress_session(sess);
    
        return compression_status;
    }
    int main()
    {
        return test_frame_polling(0, 0, 0);
    }
  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 -lkaelz4 -o kaelz4_polling_test
  5. Run the test file.
    export LD_LIBRARY_PATH=/usr/local/kaelz4/lib:$LD_LIBRARY_PATH
    ./kaelz4_polling_test

    "Test Success" is displayed.