#include <stdio.h>
#include <blosc2.h>
#define KB 1024.
#define MB (1024*KB)
#define GB (1024*MB)
#define CHUNKSIZE (200 * 1000)
#define NCHUNKS 100
#define NTHREADS 4
int main(void) {
blosc2_init();
static int32_t data[CHUNKSIZE];
static int32_t data_dest[CHUNKSIZE];
static int32_t data_dest2[CHUNKSIZE];
int32_t isize = CHUNKSIZE * sizeof(int32_t);
int64_t nbytes, cbytes;
int i, nchunk;
int64_t nchunks;
blosc_timestamp_t last, current;
double ttotal;
printf("Blosc version info: %s (%s)\n",
BLOSC2_VERSION_STRING, BLOSC2_VERSION_DATE);
blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
cparams.typesize = sizeof(int32_t);
cparams.compcode = BLOSC_LZ4;
cparams.clevel = 9;
cparams.nthreads = NTHREADS;
blosc2_dparams dparams = BLOSC2_DPARAMS_DEFAULTS;
dparams.nthreads = NTHREADS;
blosc2_storage storage = {.cparams=&cparams, .dparams=&dparams};
blosc2_schunk* schunk = blosc2_schunk_new(&storage);
blosc_set_timestamp(&last);
for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
for (i = 0; i < CHUNKSIZE; i++) {
data[i] = i * nchunk;
}
nchunks = blosc2_schunk_append_buffer(schunk, data, isize);
if (nchunks != nchunk + 1) {
printf("blosc2_schunk_append_buffer is not working correctly");
return BLOSC2_ERROR_FAILURE;
}
}
int32_t content_len = 10;
uint8_t *content = malloc(content_len);
for (int32_t j = 0; j < content_len; ++j) {
content[j] = (uint8_t) j;
}
int umlen = blosc2_vlmeta_add(schunk, "vlmetalayer", content, content_len, NULL);
free(content);
if (umlen < 0) {
printf("Cannot write vlmetalayers chunk");
return umlen;
}
nbytes = schunk->nbytes;
cbytes = schunk->cbytes;
blosc_set_timestamp(¤t);
ttotal = blosc_elapsed_secs(last, current);
printf("Compression ratio: %.1f MB -> %.1f MB (%.1fx)\n",
(double)nbytes / MB, (double)cbytes / MB, (1. * (double)nbytes) / (double)cbytes);
printf("Compression time: %.3g s, %.1f MB/s\n",
ttotal, (double)nbytes / (ttotal * MB));
uint8_t* vlmetalayer;
blosc2_vlmeta_get(schunk, "vlmetalayer", &vlmetalayer, &content_len);
printf("Variable-length metalayer length: %d\n", content_len);
for (int j = 0; j < content_len; ++j) {
printf("%3d", vlmetalayer[j]);
}
printf("\n");
free(vlmetalayer);
blosc_set_timestamp(&last);
uint8_t* cframe;
bool cframe_needs_free;
int64_t frame_len = blosc2_schunk_to_buffer(schunk, &cframe, &cframe_needs_free);
if (frame_len < 0) {
return (int)frame_len;
}
blosc_set_timestamp(¤t);
ttotal = blosc_elapsed_secs(last, current);
printf("Time for schunk -> frame: %.3g s, %.1f MB/s\n",
ttotal, (double)nbytes / (ttotal * MB));
printf("Frame length in memory: %ld bytes\n", (long)frame_len);
remove("frame_simple.b2frame");
blosc_set_timestamp(&last);
frame_len = blosc2_schunk_to_file(schunk, "frame_simple.b2frame");
if (frame_len < 0) {
return (int)frame_len;
}
printf("Frame length on disk: %ld bytes\n", (long)frame_len);
blosc_set_timestamp(¤t);
ttotal = blosc_elapsed_secs(last, current);
printf("Time for frame -> fileframe (frame_simple.b2frame): %.3g s, %.1f GB/s\n",
ttotal, (double)nbytes / (ttotal * GB));
blosc_set_timestamp(&last);
blosc2_schunk* schunk2 = blosc2_schunk_open("file:///frame_simple.b2frame");
blosc_set_timestamp(¤t);
ttotal = blosc_elapsed_secs(last, current);
printf("Time for fileframe (%s) -> frame : %.3g s, %.1f GB/s\n",
schunk2->storage->urlpath, ttotal, (double)nbytes / (ttotal * GB));
blosc_set_timestamp(&last);
blosc2_schunk* schunk1 = blosc2_schunk_from_buffer(cframe, frame_len, false);
if (schunk1 == NULL) {
printf("Bad conversion frame1 -> schunk1!\n");
return -1;
}
blosc_set_timestamp(¤t);
ttotal = blosc_elapsed_secs(last, current);
printf("Time for frame -> schunk: %.3g s, %.1f GB/s\n",
ttotal, (double)nbytes / (ttotal * GB));
for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
int32_t dsize = blosc2_schunk_decompress_chunk(schunk1, nchunk, data_dest, isize);
if (dsize < 0) {
printf("Decompression error in schunk1. Error code: %d\n", dsize);
return dsize;
}
dsize = blosc2_schunk_decompress_chunk(schunk2, nchunk, data_dest2, isize);
if (dsize < 0) {
printf("Decompression error in schunk2. Error code: %d\n", dsize);
return dsize;
}
for (i = 0; i < CHUNKSIZE; i++) {
if ((data_dest[i] != i * nchunk) || (data_dest2[i] != i * nchunk)) {
printf("data mismatch");
return BLOSC2_ERROR_FAILURE;
}
}
}
printf("Successful roundtrip schunk <-> frame <-> fileframe !\n");
blosc2_vlmeta_get(schunk1, "vlmetalayer", &vlmetalayer, &content_len);
for (int j = 0; j < content_len; ++j) {
printf("%3d", vlmetalayer[j]);
}
printf("\n");
free(vlmetalayer);
blosc2_vlmeta_get(schunk2, "vlmetalayer", &vlmetalayer, &content_len);
for (int j = 0; j < content_len; ++j) {
printf("%3d", vlmetalayer[j]);
}
printf("\n");
free(vlmetalayer);
blosc2_schunk_free(schunk);
blosc2_schunk_free(schunk1);
blosc2_schunk_free(schunk2);
if (cframe_needs_free) {
free(cframe);
}
blosc2_destroy();
return 0;
}