异步接口的使用
本节提供KAELz4加速压缩库异步接口的使用方法。
- 请参见软件安装(KAE2.0)章节编译并安装好软件。
- 应用层在编译阶段指定libkaelz4.so的位置,指定KAELz4异步头文件的位置,通过以下编译选项进行链接。
1
-I/usr/local/kaelz4/include -L/usr/local/kaelz4/lib -llz4
设置环境变量。
1 2
export LD_LIBRARY_PATH=/usr/local/kaelz4/lib:$LD_LIBRARY_PATH export C_INCLUDE_PATH=/usr/local/kaelz4/include:$C_INCLUDE_PATH
- 使用异步接口编写压缩代码main.c。frame格式压缩代码示例如下。
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; // 异步回调是否完成。需要初始化为0。 int g_test_file = 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() % 256; // 随机生成字节 } } 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; } // 在回调中获取压缩后的数据 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 = 258 * 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); if (g_test_file) { src_len = read_inputFile("../../../scripts/compressTestDataset/x-ray", &inbuf); } // 为压缩数据分配内存 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}; 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); }
- 编译并运行代码。
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
显示结果如下。
1
Test Success.
父主题: KAELz4加速库的使用