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 See LICENSE.txt for details about copyright and rights to use.
7 */
8
9 #include <stdio.h>
10 #include "test_common.h"
11
12 #define CHUNKSIZE (200 * 1000)
13 #define BLOCKSIZE (20 * 1000)
14 #define NBLOCKS (CHUNKSIZE / BLOCKSIZE)
15
16 /* Global vars */
17 int tests_run = 0;
18 int nchunks;
19 int clevel;
20 int16_t nthreads;
21 uint8_t filter;
22
23
test_lazy_chunk(void)24 static char* test_lazy_chunk(void) {
25 int32_t *data = malloc(CHUNKSIZE * sizeof(int32_t));
26 int32_t *data_dest = malloc(CHUNKSIZE * sizeof(int32_t));
27 int32_t isize = CHUNKSIZE * sizeof(int32_t);
28 int dsize;
29 int cbytes;
30 blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
31 cparams.filters[5] = filter;
32 blosc2_dparams dparams = BLOSC2_DPARAMS_DEFAULTS;
33 blosc2_schunk* schunk;
34
35 /* Initialize the Blosc compressor */
36 blosc_init();
37
38 /* Create a super-chunk container, backed by a frame */
39 cparams.typesize = sizeof(int32_t);
40 cparams.clevel = clevel;
41 cparams.nthreads = nthreads;
42 cparams.blocksize = BLOCKSIZE * cparams.typesize;
43 dparams.nthreads = nthreads;
44 char* urlpath = "test_lazy_chunk.b2frame";
45 remove(urlpath);
46 blosc2_storage storage = {.contiguous=true, .urlpath=urlpath, .cparams=&cparams, .dparams=&dparams};
47
48 schunk = blosc2_schunk_new(&storage);
49
50 // Feed it with data
51 for (int nchunk = 0; nchunk < nchunks; nchunk++) {
52 for (int i = 0; i < NBLOCKS; i++) {
53 for (int j = 0; j < BLOCKSIZE; j++) {
54 data[j + i * BLOCKSIZE] = j + i * BLOCKSIZE + nchunk * CHUNKSIZE;
55 }
56 }
57 int nchunks_ = blosc2_schunk_append_buffer(schunk, data, isize);
58 mu_assert("ERROR: bad append in frame", nchunks_ > 0);
59 }
60
61 /* Gather some info */
62 if (nchunks > 0 && clevel > 0) {
63 mu_assert("ERROR: bad compression ratio in frame", schunk->nbytes > 10 * schunk->cbytes);
64 }
65
66 // Check that blosc2_getitem_ctx works correctly with lazy chunks
67 bool needs_free;
68 uint8_t* lazy_chunk;
69 for (int nchunk = 0; nchunk < nchunks; nchunk++) {
70 cbytes = blosc2_schunk_get_lazychunk(schunk, nchunk, &lazy_chunk, &needs_free);
71 for (int i = 0; i < NBLOCKS - 1; i++) {
72 memset(data_dest, 0, isize);
73 dsize = blosc2_getitem_ctx(schunk->dctx, lazy_chunk, cbytes, i * BLOCKSIZE, BLOCKSIZE * 2, data_dest, isize);
74 mu_assert("ERROR: blosc2_getitem_ctx does not work correctly.", dsize >= 0);
75 for (int j = 0; j < BLOCKSIZE * 2; j++) {
76 mu_assert("ERROR: bad roundtrip (blosc2_getitem_ctx)",
77 data_dest[j] == j + i * BLOCKSIZE + nchunk * CHUNKSIZE);
78 }
79 }
80 if (needs_free) {
81 free(lazy_chunk);
82 }
83 }
84
85 // Check that lazy chunks can be decompressed correctly
86 for (int nchunk = 0; nchunk < nchunks; nchunk++) {
87 memset(data_dest, 0, isize);
88 cbytes = blosc2_schunk_get_lazychunk(schunk, nchunk, &lazy_chunk, &needs_free);
89 mu_assert("ERROR: cannot get lazy chunk.", cbytes > 0);
90 dsize = blosc2_decompress_ctx(schunk->dctx, lazy_chunk, cbytes, data_dest, isize);
91 if (needs_free) {
92 free(lazy_chunk);
93 }
94 mu_assert("ERROR: chunk cannot be decompressed correctly.", dsize >= 0);
95 for (int i = 0; i < NBLOCKS; i++) {
96 for (int j = 0; j < BLOCKSIZE; j++) {
97 mu_assert("ERROR: bad roundtrip (blosc2_decompress_ctx)",
98 data_dest[j + i * BLOCKSIZE] == j + i * BLOCKSIZE + nchunk * CHUNKSIZE);
99 }
100 }
101 }
102
103 /* Free resources */
104 blosc2_schunk_free(schunk);
105 /* Destroy the Blosc environment */
106 blosc_destroy();
107
108 free(data);
109 free(data_dest);
110
111 return EXIT_SUCCESS;
112 }
113
all_tests(void)114 static char *all_tests(void) {
115 nchunks = 0;
116 clevel = 5;
117 nthreads = 1;
118 filter = BLOSC_SHUFFLE;
119 mu_run_test(test_lazy_chunk);
120
121 nchunks = 1;
122 clevel = 5;
123 nthreads = 2;
124 filter = BLOSC_SHUFFLE;
125 mu_run_test(test_lazy_chunk);
126
127 nchunks = 1;
128 clevel = 0;
129 nthreads = 2;
130 filter = BLOSC_BITSHUFFLE;
131 mu_run_test(test_lazy_chunk);
132
133 nchunks = 10;
134 clevel = 5;
135 nthreads = 1;
136 filter = BLOSC_SHUFFLE;
137 mu_run_test(test_lazy_chunk);
138
139 nchunks = 10;
140 clevel = 5;
141 nthreads = 2;
142 filter = BLOSC_BITSHUFFLE;
143 mu_run_test(test_lazy_chunk);
144
145 nchunks = 10;
146 clevel = 0;
147 nthreads = 1;
148 filter = BLOSC_SHUFFLE;
149 mu_run_test(test_lazy_chunk);
150
151 nchunks = 10;
152 clevel = 0;
153 nthreads = 2;
154 filter = BLOSC_BITSHUFFLE;
155 mu_run_test(test_lazy_chunk);
156
157 return EXIT_SUCCESS;
158 }
159
160
main(void)161 int main(void) {
162 char *result;
163
164 install_blosc_callback_test(); /* optionally install callback test */
165 blosc_init();
166
167 /* Run all the suite */
168 result = all_tests();
169 if (result != EXIT_SUCCESS) {
170 printf(" (%s)\n", result);
171 }
172 else {
173 printf(" ALL TESTS PASSED");
174 }
175 printf("\tTests run: %d\n", tests_run);
176
177 blosc_destroy();
178
179 return result != EXIT_SUCCESS;
180 }
181