Rate This Document
Findability
Accuracy
Completeness
Readability

Using Asynchronous Interfaces

This section describes how to use asynchronous interfaces of the KAELz4 library.

  1. Compile and install the software based on Software Installation (KAE 2.0).
  2. 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
    
  3. 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);
    }
    
  4. 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:

    1
    Test Success.