鲲鹏社区首页
中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

非polling模式异步压缩接口调用示例

提供非polling模式下,数据通过接口直接被异步压缩处理,最终由callback函数回调压缩结果的相关接口调用示例。

以普通frame格式异步压缩接口为示例:

  1. 对某一段内存进行压缩,同时设置特定的frame格式。
  2. 在收到回调后,使用开源frame解压接口对压缩内容进行解压。
  3. 最后比较解压后的内容是否是原始内容。

详细代码和编译运行步骤如下。

  1. 创建main.c文件。
  2. “i”进入编辑模式,将以下内容写入文件。
    #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; // 异步回调是否完成。需要初始化为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;
    };
    
    // 随机生成256KB的数据
    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;
        }
    
        // 在回调中获取压缩后的数据
        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;
    
        // 使用LZ4解压缩数据
        size_t tmp_src_len = result->src_size * 10;
        // 为解压数据分配内存
        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: 解压后与原始长度不一样. result->src_size=%ld   原始长度=%ld   压缩后解压长度=%ld \n",
                result->src_size,
                my_data->src_len,
                my_data->src_decompd_len);
        }
    
        // 比较解压后的数据和原始数据
        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");
        }
    
        // 释放解压后的数据
        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(inbuf, src_len);
    
        // 为压缩数据分配内存
        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;
        }
    
        // 初始化LZ4F压缩的参数
        LZ4F_preferences_t preferences = {0};
        preferences.frameInfo.blockSizeID = LZ4F_max64KB;  // 设定块大小
        if (contentChecksumFlag) {
            preferences.frameInfo.contentChecksumFlag = LZ4F_contentChecksumEnabled;
        }
        if (blockChecksumFlag) {
            preferences.frameInfo.blockChecksumFlag = LZ4F_blockChecksumEnabled;
        }
        if (contentSizeFlag) {
            preferences.frameInfo.contentSize = src_len;
        }
    
        // 异步压缩
        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. “Esc”键,输入:wq!,按“Enter”保存并退出编辑。
  4. 编译main.c文件。
    gcc main.c -I/usr/local/kaelz4/include -L/usr/local/kaelz4/lib -llz4 -o kaelz4_frame_async_test
  5. 运行测试文件。
    export LD_LIBRARY_PATH=/usr/local/kaelz4/lib:$LD_LIBRARY_PATH 
    ./kaelz4_frame_async_test

    输出Test Success。