1 /*********************************************************************
2   Blosc - Blocked Shuffling and Compression Library
3 
4   Unit tests for the blosc_getitem() function.
5 
6   Copyright (C) 2021  The Blosc Developers <blosc@blosc.org>
7   https://blosc.org
8   License: BSD 3-Clause (see LICENSE.txt)
9 
10   See LICENSE.txt for details about copyright and rights to use.
11 **********************************************************************/
12 
13 #include "test_common.h"
14 
15 
16 /** Test the blosc_getitem function. */
test_getitem(size_t type_size,size_t num_elements,size_t buffer_alignment,int compression_level,int do_shuffle)17 static int test_getitem(size_t type_size, size_t num_elements,
18                         size_t buffer_alignment, int compression_level,
19                         int do_shuffle) {
20   size_t buffer_size = type_size * num_elements;
21   int csize, dsize;
22 
23   /* Allocate memory for the test. */
24   void* original = blosc_test_malloc(buffer_alignment, buffer_size);
25   void* intermediate = blosc_test_malloc(buffer_alignment,
26                                          buffer_size + BLOSC_MAX_OVERHEAD);
27   void* result = blosc_test_malloc(buffer_alignment, buffer_size);
28 
29   /* Fill the input data buffer with random values. */
30   blosc_test_fill_seq(original, buffer_size);
31 
32   /* Compress the input data, then use blosc_getitem to extract (decompress)
33      a range of elements into a new buffer. */
34   csize = blosc_compress(compression_level, do_shuffle, type_size,
35                           buffer_size, original, intermediate,
36                           buffer_size + BLOSC_MAX_OVERHEAD);
37   if (csize < 0) {
38     printf("Compression error.  Error code: %d\n", csize);
39     return csize;
40   }
41   dsize = blosc_getitem(intermediate, 0, (int)num_elements, result);
42   if (dsize < 0) {
43     printf("getitem error.  Error code: %d\n", dsize);
44     return dsize;
45   }
46 
47   /* The round-tripped data matches the original data when the
48      result of memcmp is 0. */
49   int exit_code = memcmp(original, result, buffer_size) ?
50                   EXIT_FAILURE : EXIT_SUCCESS;
51   if (exit_code != 0) printf("getitem test fail!\n");
52 
53   /* Free allocated memory. */
54   blosc_test_free(original);
55   blosc_test_free(intermediate);
56   blosc_test_free(result);
57 
58   return exit_code;
59 }
60 
61 /** Required number of arguments to this test, including the executable name. */
62 #define TEST_ARG_COUNT  7
63 
main(int argc,char ** argv)64 int main(int argc, char** argv) {
65   /*  argv[1]: sizeof(element type)
66       argv[2]: number of elements
67       argv[3]: buffer alignment
68       argv[4]: compression level
69       argv[5]: shuffle enabled
70       argv[6]: thread count
71   */
72 
73   /*  Verify the correct number of command-line args have been specified. */
74   if (TEST_ARG_COUNT != argc) {
75     blosc_test_print_bad_argcount_msg(TEST_ARG_COUNT, argc);
76     return EXIT_FAILURE;
77   }
78 
79   /* Parse arguments */
80   uint32_t type_size;
81   if (!blosc_test_parse_uint32_t(argv[1], &type_size) || (type_size < 1)) {
82     blosc_test_print_bad_arg_msg(1);
83     return EXIT_FAILURE;
84   }
85 
86   uint32_t num_elements;
87   if (!blosc_test_parse_uint32_t(argv[2], &num_elements) || (num_elements < 1)) {
88     blosc_test_print_bad_arg_msg(2);
89     return EXIT_FAILURE;
90   }
91 
92   uint32_t buffer_align_size;
93   if (!blosc_test_parse_uint32_t(argv[3], &buffer_align_size)
94       || (buffer_align_size & (buffer_align_size - 1))
95       || (buffer_align_size < sizeof(void*))) {
96     blosc_test_print_bad_arg_msg(3);
97     return EXIT_FAILURE;
98   }
99 
100   uint32_t compression_level;
101   if (!blosc_test_parse_uint32_t(
102           argv[4], &compression_level) || (compression_level > 9)) {
103     blosc_test_print_bad_arg_msg(4);
104     return EXIT_FAILURE;
105   }
106 
107   uint32_t shuffle_enabled;
108   {
109     if (!blosc_test_parse_uint32_t(
110             argv[5], &shuffle_enabled) || (shuffle_enabled > 2)) {
111       blosc_test_print_bad_arg_msg(5);
112       return EXIT_FAILURE;
113     }
114   }
115 
116   uint32_t blosc_thread_count;
117   if (!blosc_test_parse_uint32_t(
118           argv[6], &blosc_thread_count) || (blosc_thread_count < 1)) {
119     blosc_test_print_bad_arg_msg(6);
120     return EXIT_FAILURE;
121   }
122 
123   /* Initialize blosc before running tests. */
124   blosc_init();
125   blosc_set_nthreads(blosc_thread_count);
126 
127   /* Run the test. */
128   int result = test_getitem(type_size, num_elements, buffer_align_size,
129                             compression_level, shuffle_enabled);
130 
131   /* Cleanup blosc resources. */
132   blosc_destroy();
133 
134   return result;
135 }
136