1 /*
2   Copyright (C) 2021  The Blosc Developers <blosc@blosc.org>
3   https://blosc.org
4   License: BSD 3-Clause (see LICENSE.txt)
5 
6   Example program demonstrating use of the Blosc filter from C code.
7 
8   To compile this program:
9 
10   $ gcc -O frame_backed_schunk.c -o frame_backed_schunk -lblosc2
11 
12   To run:
13 
14   $ ./frame_backed_schunk
15   Blosc version info: 2.0.0a6.dev ($Date:: 2018-05-18 #$)
16   Compression ratio: 381.5 MB -> 12.2 MB (31.2x)
17   Time for append data to a schunk backed by an in-memory frame: 0.0892 s, 4278.1 MB/s
18   Compression ratio: 381.5 MB -> 12.2 MB (31.2x)
19   Time for append data to a schunk backed by a fileframe: 0.107 s, 3556.3 MB/s
20   Successful roundtrip data <-> schunk (frame-backed) !
21 
22  */
23 
24 #include <stdio.h>
25 #include <assert.h>
26 #include <blosc2.h>
27 
28 #define KB  1024.
29 #define MB  (1024*KB)
30 #define GB  (1024*MB)
31 
32 #define CHUNKSIZE (1000 * 1000)
33 #define NCHUNKS 100
34 #define NTHREADS 4
35 
36 
main(void)37 int main(void) {
38   static int32_t data[CHUNKSIZE];
39   static int32_t data_dest1[CHUNKSIZE];
40   static int32_t data_dest2[CHUNKSIZE];
41   size_t isize = CHUNKSIZE * sizeof(int32_t);
42   int64_t nbytes, cbytes;
43   int i, nchunk;
44   int nchunks;
45   blosc_timestamp_t last, current;
46   double ttotal;
47 
48   printf("Blosc version info: %s (%s)\n",
49          BLOSC_VERSION_STRING, BLOSC_VERSION_DATE);
50 
51   // Compression and decompression parameters
52   blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
53   cparams.typesize = sizeof(int32_t);
54   cparams.clevel = 9;
55   cparams.nthreads = NTHREADS;
56   blosc2_dparams dparams = BLOSC2_DPARAMS_DEFAULTS;
57   dparams.nthreads = NTHREADS;
58 
59   /* Create a new super-chunk backed by an in-memory frame */
60   blosc2_storage storage = {.contiguous=true, .cparams=&cparams, .dparams=&dparams};
61   blosc2_schunk* schunk1 = blosc2_schunk_new(&storage);
62 
63   blosc_set_timestamp(&last);
64   for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
65     for (i = 0; i < CHUNKSIZE; i++) {
66       data[i] = i * nchunk;
67     }
68     nchunks = blosc2_schunk_append_buffer(schunk1, data, isize);
69     assert(nchunks == nchunk + 1);
70   }
71   /* Gather some info */
72   nbytes = schunk1->nbytes;
73   cbytes = schunk1->cbytes;
74   blosc_set_timestamp(&current);
75   ttotal = blosc_elapsed_secs(last, current);
76   printf("Compression ratio: %.1f MB -> %.1f MB (%.1fx)\n",
77          nbytes / MB, cbytes / MB, (1. * nbytes) / cbytes);
78   printf("Time for append data to a schunk backed by an in-memory frame: %.3g s, %.1f MB/s\n",
79          ttotal, nbytes / (ttotal * MB));
80 
81   /* Create a new super-chunk backed by an in-memory frame */
82   storage = (blosc2_storage){.contiguous=true, .cparams=&cparams, .dparams=&dparams};
83   blosc2_schunk* schunk2 = blosc2_schunk_new(&storage);
84 
85   blosc_set_timestamp(&last);
86   for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
87     for (i = 0; i < CHUNKSIZE; i++) {
88       data[i] = i * nchunk;
89     }
90     nchunks = blosc2_schunk_append_buffer(schunk2, data, isize);
91     assert(nchunks == nchunk + 1);
92   }
93   /* Gather some info */
94   nbytes = schunk2->nbytes;
95   cbytes = schunk2->cbytes;
96   blosc_set_timestamp(&current);
97   ttotal = blosc_elapsed_secs(last, current);
98   printf("Compression ratio: %.1f MB -> %.1f MB (%.1fx)\n",
99          nbytes / MB, cbytes / MB, (1. * nbytes) / cbytes);
100   printf("Time for append data to a schunk backed by a fileframe: %.3g s, %.1f MB/s\n",
101          ttotal, nbytes / (ttotal * MB));
102 
103   /* Retrieve and decompress the chunks from the super-chunks and compare values */
104   for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
105     int32_t dsize1 = blosc2_schunk_decompress_chunk(schunk1, nchunk, data_dest1, isize);
106     if (dsize1 < 0) {
107       printf("Decompression error in schunk1.  Error code: %d\n", dsize1);
108       return dsize1;
109     }
110     int32_t dsize2 = blosc2_schunk_decompress_chunk(schunk2, nchunk, data_dest2, isize);
111     if (dsize2 < 0) {
112       printf("Decompression error in schunk2.  Error code: %d\n", dsize2);
113       return dsize2;
114     }
115     assert(dsize1 == dsize2);
116     /* Check integrity of the last chunk */
117     for (i = 0; i < CHUNKSIZE; i++) {
118       assert (data_dest1[i] == i * nchunk);
119       assert (data_dest2[i] == i * nchunk);
120     }
121   }
122 
123   printf("Successful roundtrip data <-> schunk (frame-backed) !\n");
124 
125   /* Free resources */
126   blosc2_schunk_free(schunk1);
127   blosc2_schunk_free(schunk2);
128 
129   return 0;
130 }
131