1 | #include <Compression/CompressionFactory.h> |
2 | |
3 | #include <Common/PODArray.h> |
4 | #include <Core/Types.h> |
5 | #include <DataTypes/DataTypesNumber.h> |
6 | #include <DataTypes/IDataType.h> |
7 | #include <IO/ReadBufferFromMemory.h> |
8 | #include <IO/WriteHelpers.h> |
9 | #include <Parsers/ExpressionElementParsers.h> |
10 | #include <Parsers/IParser.h> |
11 | #include <Parsers/TokenIterator.h> |
12 | |
13 | #include <boost/format.hpp> |
14 | |
15 | #include <bitset> |
16 | #include <cmath> |
17 | #include <initializer_list> |
18 | #include <iomanip> |
19 | #include <iostream> |
20 | #include <iterator> |
21 | #include <memory> |
22 | #include <typeinfo> |
23 | #include <vector> |
24 | |
25 | #include <string.h> |
26 | |
27 | /// For the expansion of gtest macros. |
28 | #if defined(__clang__) |
29 | #pragma clang diagnostic ignored "-Wdeprecated" |
30 | #elif defined (__GNUC__) && __GNUC__ >= 9 |
31 | #pragma GCC diagnostic ignored "-Wdeprecated-copy" |
32 | #endif |
33 | |
34 | #include <gtest/gtest.h> |
35 | |
36 | using namespace DB; |
37 | |
38 | namespace std |
39 | { |
40 | template <typename T> |
41 | std::ostream & operator<<(std::ostream & ostr, const std::optional<T> & opt) |
42 | { |
43 | if (!opt) |
44 | { |
45 | return ostr << "<empty optional>" ; |
46 | } |
47 | |
48 | return ostr << *opt; |
49 | } |
50 | |
51 | template <typename T> |
52 | std::vector<T> operator+(std::vector<T> && left, std::vector<T> && right) |
53 | { |
54 | std::vector<T> result(std::move(left)); |
55 | std::move(std::begin(right), std::end(right), std::back_inserter(result)); |
56 | |
57 | return result; |
58 | } |
59 | |
60 | } |
61 | |
62 | namespace |
63 | { |
64 | |
65 | template <typename T> |
66 | std::string bin(const T & value, size_t bits = sizeof(T)*8) |
67 | { |
68 | static const UInt8 MAX_BITS = sizeof(T)*8; |
69 | assert(bits <= MAX_BITS); |
70 | |
71 | return std::bitset<sizeof(T) * 8>(static_cast<unsigned long long>(value)) |
72 | .to_string().substr(MAX_BITS - bits, bits); |
73 | } |
74 | |
75 | template <typename T> |
76 | const char* type_name() |
77 | { |
78 | #define MAKE_TYPE_NAME(TYPE) \ |
79 | if constexpr (std::is_same_v<TYPE, T>) return #TYPE |
80 | |
81 | MAKE_TYPE_NAME(UInt8); |
82 | MAKE_TYPE_NAME(UInt16); |
83 | MAKE_TYPE_NAME(UInt32); |
84 | MAKE_TYPE_NAME(UInt64); |
85 | MAKE_TYPE_NAME(Int8); |
86 | MAKE_TYPE_NAME(Int16); |
87 | MAKE_TYPE_NAME(Int32); |
88 | MAKE_TYPE_NAME(Int64); |
89 | MAKE_TYPE_NAME(Float32); |
90 | MAKE_TYPE_NAME(Float64); |
91 | |
92 | #undef MAKE_TYPE_NAME |
93 | |
94 | return typeid(T).name(); |
95 | } |
96 | |
97 | template <typename T> |
98 | DataTypePtr makeDataType() |
99 | { |
100 | #define MAKE_DATA_TYPE(TYPE) \ |
101 | if constexpr (std::is_same_v<T, TYPE>) return std::make_shared<DataType ## TYPE>() |
102 | |
103 | MAKE_DATA_TYPE(UInt8); |
104 | MAKE_DATA_TYPE(UInt16); |
105 | MAKE_DATA_TYPE(UInt32); |
106 | MAKE_DATA_TYPE(UInt64); |
107 | MAKE_DATA_TYPE(Int8); |
108 | MAKE_DATA_TYPE(Int16); |
109 | MAKE_DATA_TYPE(Int32); |
110 | MAKE_DATA_TYPE(Int64); |
111 | MAKE_DATA_TYPE(Float32); |
112 | MAKE_DATA_TYPE(Float64); |
113 | |
114 | #undef MAKE_DATA_TYPE |
115 | |
116 | assert(false && "unsupported size" ); |
117 | return nullptr; |
118 | } |
119 | |
120 | |
121 | template <typename T, typename ContainerLeft, typename ContainerRight> |
122 | ::testing::AssertionResult EqualByteContainersAs(const ContainerLeft & left, const ContainerRight & right) |
123 | { |
124 | static_assert(sizeof(typename ContainerLeft::value_type) == 1, "Expected byte-container" ); |
125 | static_assert(sizeof(typename ContainerRight::value_type) == 1, "Expected byte-container" ); |
126 | |
127 | ::testing::AssertionResult result = ::testing::AssertionSuccess(); |
128 | |
129 | ReadBufferFromMemory left_read_buffer(left.data(), left.size()); |
130 | ReadBufferFromMemory right_read_buffer(right.data(), right.size()); |
131 | |
132 | const auto l_size = left.size() / sizeof(T); |
133 | const auto r_size = right.size() / sizeof(T); |
134 | const auto size = std::min(l_size, r_size); |
135 | |
136 | if (l_size != r_size) |
137 | { |
138 | result = ::testing::AssertionFailure() << "size mismatch" << " expected: " << l_size << " got:" << r_size; |
139 | } |
140 | |
141 | const auto MAX_MISMATCHING_ITEMS = 5; |
142 | int mismatching_items = 0; |
143 | for (int i = 0; i < size; ++i) |
144 | { |
145 | T left_value{}; |
146 | left_read_buffer.readStrict(reinterpret_cast<char*>(&left_value), sizeof(left_value)); |
147 | |
148 | T right_value{}; |
149 | right_read_buffer.readStrict(reinterpret_cast<char*>(&right_value), sizeof(right_value)); |
150 | |
151 | if (left_value != right_value) |
152 | { |
153 | if (result) |
154 | { |
155 | result = ::testing::AssertionFailure(); |
156 | } |
157 | |
158 | if (++mismatching_items <= MAX_MISMATCHING_ITEMS) |
159 | { |
160 | result << "mismatching " << sizeof(T) << "-byte item #" << i |
161 | << "\nexpected: " << bin(left_value) << " (0x" << std::hex << left_value << ")" |
162 | << "\ngot : " << bin(right_value) << " (0x" << std::hex << right_value << ")" |
163 | << std::endl; |
164 | if (mismatching_items == MAX_MISMATCHING_ITEMS) |
165 | { |
166 | result << "..." << std::endl; |
167 | } |
168 | } |
169 | } |
170 | } |
171 | if (mismatching_items > 0) |
172 | { |
173 | result << "\ntotal mismatching items:" << mismatching_items << " of " << size; |
174 | } |
175 | |
176 | return result; |
177 | } |
178 | |
179 | struct Codec |
180 | { |
181 | std::string codec_statement; |
182 | std::optional<double> expected_compression_ratio; |
183 | |
184 | explicit Codec(std::string codec_statement_, std::optional<double> expected_compression_ratio_ = std::nullopt) |
185 | : codec_statement(std::move(codec_statement_)), |
186 | expected_compression_ratio(expected_compression_ratio_) |
187 | {} |
188 | |
189 | Codec() |
190 | : Codec(std::string()) |
191 | {} |
192 | }; |
193 | |
194 | |
195 | struct CodecTestSequence |
196 | { |
197 | std::string name; |
198 | std::vector<char> serialized_data; |
199 | DataTypePtr data_type; |
200 | |
201 | CodecTestSequence() |
202 | : name(), |
203 | serialized_data(), |
204 | data_type() |
205 | {} |
206 | |
207 | CodecTestSequence(std::string name_, std::vector<char> serialized_data_, DataTypePtr data_type_) |
208 | : name(name_), |
209 | serialized_data(serialized_data_), |
210 | data_type(data_type_) |
211 | {} |
212 | |
213 | CodecTestSequence(const CodecTestSequence &) = default; |
214 | CodecTestSequence & operator=(const CodecTestSequence &) = default; |
215 | CodecTestSequence(CodecTestSequence &&) = default; |
216 | CodecTestSequence & operator=(CodecTestSequence &&) = default; |
217 | }; |
218 | |
219 | CodecTestSequence operator+(CodecTestSequence && left, CodecTestSequence && right) |
220 | { |
221 | assert(left.data_type->equals(*right.data_type)); |
222 | |
223 | std::vector<char> data(std::move(left.serialized_data)); |
224 | data.insert(data.end(), right.serialized_data.begin(), right.serialized_data.end()); |
225 | |
226 | return CodecTestSequence{ |
227 | left.name + " + " + right.name, |
228 | std::move(data), |
229 | std::move(left.data_type) |
230 | }; |
231 | } |
232 | |
233 | template <typename T> |
234 | CodecTestSequence operator*(CodecTestSequence && left, T times) |
235 | { |
236 | std::vector<char> data(std::move(left.serialized_data)); |
237 | const size_t initial_size = data.size(); |
238 | const size_t final_size = initial_size * times; |
239 | |
240 | data.reserve(final_size); |
241 | |
242 | for (T i = 0; i < times; ++i) |
243 | { |
244 | data.insert(data.end(), data.begin(), data.begin() + initial_size); |
245 | } |
246 | |
247 | return CodecTestSequence{ |
248 | left.name + " x " + std::to_string(times), |
249 | std::move(data), |
250 | std::move(left.data_type) |
251 | }; |
252 | } |
253 | |
254 | std::ostream & operator<<(std::ostream & ostr, const Codec & codec) |
255 | { |
256 | return ostr << "Codec{" |
257 | << "name: " << codec.codec_statement |
258 | << ", expected_compression_ratio: " << codec.expected_compression_ratio |
259 | << "}" ; |
260 | } |
261 | |
262 | std::ostream & operator<<(std::ostream & ostr, const CodecTestSequence & seq) |
263 | { |
264 | return ostr << "CodecTestSequence{" |
265 | << "name: " << seq.name |
266 | << ", type name: " << seq.data_type->getName() |
267 | << ", data size: " << seq.serialized_data.size() << " bytes" |
268 | << "}" ; |
269 | } |
270 | |
271 | template <typename T, typename... Args> |
272 | CodecTestSequence makeSeq(Args && ... args) |
273 | { |
274 | std::initializer_list<T> vals{static_cast<T>(args)...}; |
275 | std::vector<char> data(sizeof(T) * std::size(vals)); |
276 | |
277 | char * write_pos = data.data(); |
278 | for (const auto & v : vals) |
279 | { |
280 | unalignedStore<T>(write_pos, v); |
281 | write_pos += sizeof(v); |
282 | } |
283 | |
284 | return CodecTestSequence{ |
285 | (boost::format("%1% values of %2%" ) % std::size(vals) % type_name<T>()).str(), |
286 | std::move(data), |
287 | makeDataType<T>() |
288 | }; |
289 | } |
290 | |
291 | template <typename T, typename Generator> |
292 | CodecTestSequence generateSeq(Generator gen, const char* gen_name, size_t Begin = 0, size_t End = 10000) |
293 | { |
294 | assert (End >= Begin); |
295 | |
296 | std::vector<char> data(sizeof(T) * (End - Begin)); |
297 | char * write_pos = data.data(); |
298 | |
299 | for (size_t i = Begin; i < End; ++i) |
300 | { |
301 | const T v = gen(static_cast<T>(i)); |
302 | unalignedStore<T>(write_pos, v); |
303 | write_pos += sizeof(v); |
304 | } |
305 | |
306 | return CodecTestSequence{ |
307 | (boost::format("%1% values of %2% from %3%" ) % (End - Begin) % type_name<T>() % gen_name).str(), |
308 | std::move(data), |
309 | makeDataType<T>() |
310 | }; |
311 | } |
312 | |
313 | |
314 | class CodecTest : public ::testing::TestWithParam<std::tuple<Codec, CodecTestSequence>> |
315 | { |
316 | public: |
317 | enum MakeCodecParam |
318 | { |
319 | CODEC_WITH_DATA_TYPE, |
320 | CODEC_WITHOUT_DATA_TYPE, |
321 | }; |
322 | |
323 | CompressionCodecPtr makeCodec(MakeCodecParam with_data_type) const |
324 | { |
325 | const auto & codec_string = std::get<0>(GetParam()).codec_statement; |
326 | const auto & data_type = with_data_type == CODEC_WITH_DATA_TYPE ? std::get<1>(GetParam()).data_type : nullptr; |
327 | |
328 | const std::string codec_statement = "(" + codec_string + ")" ; |
329 | Tokens tokens(codec_statement.begin().base(), codec_statement.end().base()); |
330 | IParser::Pos token_iterator(tokens); |
331 | |
332 | Expected expected; |
333 | ASTPtr codec_ast; |
334 | ParserCodec parser; |
335 | |
336 | parser.parse(token_iterator, codec_ast, expected); |
337 | |
338 | return CompressionCodecFactory::instance().get(codec_ast, data_type); |
339 | } |
340 | |
341 | void testTranscoding(ICompressionCodec & codec) |
342 | { |
343 | const auto & test_sequence = std::get<1>(GetParam()); |
344 | const auto & source_data = test_sequence.serialized_data; |
345 | |
346 | const UInt32 encoded_max_size = codec.getCompressedReserveSize(source_data.size()); |
347 | PODArray<char> encoded(encoded_max_size); |
348 | |
349 | const UInt32 encoded_size = codec.compress(source_data.data(), source_data.size(), encoded.data()); |
350 | encoded.resize(encoded_size); |
351 | |
352 | PODArray<char> decoded(source_data.size()); |
353 | const UInt32 decoded_size = codec.decompress(encoded.data(), encoded.size(), decoded.data()); |
354 | decoded.resize(decoded_size); |
355 | |
356 | switch (test_sequence.data_type->getSizeOfValueInMemory()) |
357 | { |
358 | case 1: |
359 | ASSERT_TRUE(EqualByteContainersAs<UInt8>(source_data, decoded)); |
360 | break; |
361 | case 2: |
362 | ASSERT_TRUE(EqualByteContainersAs<UInt16>(source_data, decoded)); |
363 | break; |
364 | case 4: |
365 | ASSERT_TRUE(EqualByteContainersAs<UInt32>(source_data, decoded)); |
366 | break; |
367 | case 8: |
368 | ASSERT_TRUE(EqualByteContainersAs<UInt64>(source_data, decoded)); |
369 | break; |
370 | default: |
371 | FAIL() << "Invalid test sequence data type: " << test_sequence.data_type->getName(); |
372 | } |
373 | const auto = codec.getHeaderSize(); |
374 | const auto compression_ratio = (encoded_size - header_size) / (source_data.size() * 1.0); |
375 | |
376 | const auto & codec_spec = std::get<0>(GetParam()); |
377 | if (codec_spec.expected_compression_ratio) |
378 | { |
379 | ASSERT_LE(compression_ratio, *codec_spec.expected_compression_ratio) |
380 | << "\n\tdecoded size: " << source_data.size() |
381 | << "\n\tencoded size: " << encoded_size |
382 | << "(no header: " << encoded_size - header_size << ")" ; |
383 | } |
384 | } |
385 | }; |
386 | |
387 | TEST_P(CodecTest, TranscodingWithDataType) |
388 | { |
389 | const auto codec = makeCodec(CODEC_WITH_DATA_TYPE); |
390 | testTranscoding(*codec); |
391 | } |
392 | |
393 | TEST_P(CodecTest, TranscodingWithoutDataType) |
394 | { |
395 | const auto codec = makeCodec(CODEC_WITHOUT_DATA_TYPE); |
396 | testTranscoding(*codec); |
397 | } |
398 | |
399 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
400 | // Here we use generators to produce test payload for codecs. |
401 | // Generator is a callable that can produce infinite number of values, |
402 | // output value MUST be of the same type input value. |
403 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
404 | |
405 | auto SameValueGenerator = [](auto value) |
406 | { |
407 | return [=](auto i) |
408 | { |
409 | return static_cast<decltype(i)>(value); |
410 | }; |
411 | }; |
412 | |
413 | auto SequentialGenerator = [](auto stride = 1) |
414 | { |
415 | return [=](auto i) |
416 | { |
417 | using ValueType = decltype(i); |
418 | return static_cast<ValueType>(stride * i); |
419 | }; |
420 | }; |
421 | |
422 | // Generator that helps debugging output of other generators |
423 | // by logging every output value alongside iteration index and input. |
424 | //auto LoggingProxyGenerator = [](auto other_generator, const char * name, std::ostream & ostr, const int limit = std::numeric_limits<int>::max()) |
425 | //{ |
426 | // ostr << "\n\nValues from " << name << ":\n"; |
427 | // auto count = std::make_shared<int>(0); |
428 | // return [&, count](auto i) |
429 | // { |
430 | // using ValueType = decltype(i); |
431 | // const auto ret = static_cast<ValueType>(other_generator(i)); |
432 | // if (++(*count) < limit) |
433 | // { |
434 | // ostr << "\t" << *count << " : " << i << " => " << ret << "\n"; |
435 | // } |
436 | |
437 | // return ret; |
438 | // }; |
439 | //}; |
440 | |
441 | template <typename T> |
442 | using uniform_distribution = |
443 | typename std::conditional_t<std::is_floating_point_v<T>, std::uniform_real_distribution<T>, |
444 | typename std::conditional_t<is_integral_v<T>, std::uniform_int_distribution<T>, void>>; |
445 | |
446 | |
447 | template <typename T = Int32> |
448 | struct MonotonicGenerator |
449 | { |
450 | MonotonicGenerator(T stride_ = 1, T max_step = 10) |
451 | : prev_value(0), |
452 | stride(stride_), |
453 | random_engine(0), |
454 | distribution(0, max_step) |
455 | {} |
456 | |
457 | template <typename U> |
458 | U operator()(U) |
459 | { |
460 | prev_value = prev_value + stride * distribution(random_engine); |
461 | return static_cast<U>(prev_value); |
462 | } |
463 | |
464 | private: |
465 | T prev_value; |
466 | const T stride; |
467 | std::default_random_engine random_engine; |
468 | uniform_distribution<T> distribution; |
469 | }; |
470 | |
471 | template <typename T> |
472 | struct RandomGenerator |
473 | { |
474 | RandomGenerator(T seed = 0, T value_min = std::numeric_limits<T>::min(), T value_max = std::numeric_limits<T>::max()) |
475 | : random_engine(seed), |
476 | distribution(value_min, value_max) |
477 | { |
478 | } |
479 | |
480 | template <typename U> |
481 | U operator()(U) |
482 | { |
483 | return static_cast<U>(distribution(random_engine)); |
484 | } |
485 | |
486 | private: |
487 | std::default_random_engine random_engine; |
488 | uniform_distribution<T> distribution; |
489 | }; |
490 | |
491 | auto RandomishGenerator = [](auto i) |
492 | { |
493 | return static_cast<decltype(i)>(sin(static_cast<double>(i * i)) * i); |
494 | }; |
495 | |
496 | auto MinMaxGenerator = []() |
497 | { |
498 | return [step = 0](auto i) mutable |
499 | { |
500 | if (step++ % 2 == 0) |
501 | { |
502 | return std::numeric_limits<decltype(i)>::min(); |
503 | } |
504 | else |
505 | { |
506 | return std::numeric_limits<decltype(i)>::max(); |
507 | } |
508 | }; |
509 | }; |
510 | |
511 | // Fill dest value with 0x00 or 0xFF |
512 | auto FFand0Generator = []() |
513 | { |
514 | return [step = 0](auto i) mutable |
515 | { |
516 | decltype(i) result; |
517 | if (step++ % 2 == 0) |
518 | { |
519 | memset(&result, 0, sizeof(result)); |
520 | } |
521 | else |
522 | { |
523 | memset(&result, 0xFF, sizeof(result)); |
524 | } |
525 | |
526 | return result; |
527 | }; |
528 | }; |
529 | |
530 | |
531 | // Makes many sequences with generator, first sequence length is 1, second is 2... up to `sequences_count`. |
532 | template <typename T, typename Generator> |
533 | std::vector<CodecTestSequence> generatePyramidOfSequences(const size_t sequences_count, Generator && generator, const char* generator_name) |
534 | { |
535 | std::vector<CodecTestSequence> sequences; |
536 | sequences.reserve(sequences_count); |
537 | for (size_t i = 1; i < sequences_count; ++i) |
538 | { |
539 | std::string name = generator_name + std::string(" from 0 to " ) + std::to_string(i); |
540 | sequences.push_back(generateSeq<T>(std::forward<decltype(generator)>(generator), name.c_str(), 0, i)); |
541 | } |
542 | |
543 | return sequences; |
544 | }; |
545 | |
546 | |
547 | // helper macro to produce human-friendly sequence name from generator |
548 | #define G(generator) generator, #generator |
549 | |
550 | const auto DefaultCodecsToTest = ::testing::Values( |
551 | Codec("DoubleDelta" ), |
552 | Codec("DoubleDelta, LZ4" ), |
553 | Codec("DoubleDelta, ZSTD" ), |
554 | Codec("Gorilla" ), |
555 | Codec("Gorilla, LZ4" ), |
556 | Codec("Gorilla, ZSTD" ) |
557 | ); |
558 | |
559 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
560 | // test cases |
561 | /////////////////////////////////////////////////////////////////////////////////////////////////// |
562 | |
563 | INSTANTIATE_TEST_CASE_P(Simple, |
564 | CodecTest, |
565 | ::testing::Combine( |
566 | DefaultCodecsToTest, |
567 | ::testing::Values( |
568 | makeSeq<Float64>(1, 2, 3, 5, 7, 11, 13, 17, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97) |
569 | ) |
570 | ), |
571 | ); |
572 | |
573 | INSTANTIATE_TEST_CASE_P(SmallSequences, |
574 | CodecTest, |
575 | ::testing::Combine( |
576 | DefaultCodecsToTest, |
577 | ::testing::ValuesIn( |
578 | generatePyramidOfSequences<Int8 >(42, G(SequentialGenerator(1))) |
579 | + generatePyramidOfSequences<Int16 >(42, G(SequentialGenerator(1))) |
580 | + generatePyramidOfSequences<Int32 >(42, G(SequentialGenerator(1))) |
581 | + generatePyramidOfSequences<Int64 >(42, G(SequentialGenerator(1))) |
582 | + generatePyramidOfSequences<UInt8 >(42, G(SequentialGenerator(1))) |
583 | + generatePyramidOfSequences<UInt16>(42, G(SequentialGenerator(1))) |
584 | + generatePyramidOfSequences<UInt32>(42, G(SequentialGenerator(1))) |
585 | + generatePyramidOfSequences<UInt64>(42, G(SequentialGenerator(1))) |
586 | ) |
587 | ), |
588 | ); |
589 | |
590 | INSTANTIATE_TEST_CASE_P(Mixed, |
591 | CodecTest, |
592 | ::testing::Combine( |
593 | DefaultCodecsToTest, |
594 | ::testing::Values( |
595 | generateSeq<Int8>(G(MinMaxGenerator()), 1, 5) + generateSeq<Int8>(G(SequentialGenerator(1)), 1, 1001), |
596 | generateSeq<Int16>(G(MinMaxGenerator()), 1, 5) + generateSeq<Int16>(G(SequentialGenerator(1)), 1, 1001), |
597 | generateSeq<Int32>(G(MinMaxGenerator()), 1, 5) + generateSeq<Int32>(G(SequentialGenerator(1)), 1, 1001), |
598 | generateSeq<Int64>(G(MinMaxGenerator()), 1, 5) + generateSeq<Int64>(G(SequentialGenerator(1)), 1, 1001), |
599 | generateSeq<UInt8>(G(MinMaxGenerator()), 1, 5) + generateSeq<UInt8>(G(SequentialGenerator(1)), 1, 1001), |
600 | generateSeq<UInt16>(G(MinMaxGenerator()), 1, 5) + generateSeq<UInt16>(G(SequentialGenerator(1)), 1, 1001), |
601 | generateSeq<UInt32>(G(MinMaxGenerator()), 1, 5) + generateSeq<UInt32>(G(SequentialGenerator(1)), 1, 1001), |
602 | generateSeq<UInt64>(G(MinMaxGenerator()), 1, 5) + generateSeq<UInt64>(G(SequentialGenerator(1)), 1, 1001) |
603 | ) |
604 | ), |
605 | ); |
606 | |
607 | INSTANTIATE_TEST_CASE_P(SameValueInt, |
608 | CodecTest, |
609 | ::testing::Combine( |
610 | DefaultCodecsToTest, |
611 | ::testing::Values( |
612 | generateSeq<Int8 >(G(SameValueGenerator(1000))), |
613 | generateSeq<Int16 >(G(SameValueGenerator(1000))), |
614 | generateSeq<Int32 >(G(SameValueGenerator(1000))), |
615 | generateSeq<Int64 >(G(SameValueGenerator(1000))), |
616 | generateSeq<UInt8 >(G(SameValueGenerator(1000))), |
617 | generateSeq<UInt16>(G(SameValueGenerator(1000))), |
618 | generateSeq<UInt32>(G(SameValueGenerator(1000))), |
619 | generateSeq<UInt64>(G(SameValueGenerator(1000))) |
620 | ) |
621 | ), |
622 | ); |
623 | |
624 | INSTANTIATE_TEST_CASE_P(SameNegativeValueInt, |
625 | CodecTest, |
626 | ::testing::Combine( |
627 | DefaultCodecsToTest, |
628 | ::testing::Values( |
629 | generateSeq<Int8 >(G(SameValueGenerator(-1000))), |
630 | generateSeq<Int16 >(G(SameValueGenerator(-1000))), |
631 | generateSeq<Int32 >(G(SameValueGenerator(-1000))), |
632 | generateSeq<Int64 >(G(SameValueGenerator(-1000))), |
633 | generateSeq<UInt8 >(G(SameValueGenerator(-1000))), |
634 | generateSeq<UInt16>(G(SameValueGenerator(-1000))), |
635 | generateSeq<UInt32>(G(SameValueGenerator(-1000))), |
636 | generateSeq<UInt64>(G(SameValueGenerator(-1000))) |
637 | ) |
638 | ), |
639 | ); |
640 | |
641 | INSTANTIATE_TEST_CASE_P(SameValueFloat, |
642 | CodecTest, |
643 | ::testing::Combine( |
644 | ::testing::Values( |
645 | Codec("Gorilla" ), |
646 | Codec("Gorilla, LZ4" ) |
647 | ), |
648 | ::testing::Values( |
649 | generateSeq<Float32>(G(SameValueGenerator(M_E))), |
650 | generateSeq<Float64>(G(SameValueGenerator(M_E))) |
651 | ) |
652 | ), |
653 | ); |
654 | |
655 | INSTANTIATE_TEST_CASE_P(SameNegativeValueFloat, |
656 | CodecTest, |
657 | ::testing::Combine( |
658 | ::testing::Values( |
659 | Codec("Gorilla" ), |
660 | Codec("Gorilla, LZ4" ) |
661 | ), |
662 | ::testing::Values( |
663 | generateSeq<Float32>(G(SameValueGenerator(-1 * M_E))), |
664 | generateSeq<Float64>(G(SameValueGenerator(-1 * M_E))) |
665 | ) |
666 | ), |
667 | ); |
668 | |
669 | INSTANTIATE_TEST_CASE_P(SequentialInt, |
670 | CodecTest, |
671 | ::testing::Combine( |
672 | DefaultCodecsToTest, |
673 | ::testing::Values( |
674 | generateSeq<Int8 >(G(SequentialGenerator(1))), |
675 | generateSeq<Int16 >(G(SequentialGenerator(1))), |
676 | generateSeq<Int32 >(G(SequentialGenerator(1))), |
677 | generateSeq<Int64 >(G(SequentialGenerator(1))), |
678 | generateSeq<UInt8 >(G(SequentialGenerator(1))), |
679 | generateSeq<UInt16>(G(SequentialGenerator(1))), |
680 | generateSeq<UInt32>(G(SequentialGenerator(1))), |
681 | generateSeq<UInt64>(G(SequentialGenerator(1))) |
682 | ) |
683 | ), |
684 | ); |
685 | |
686 | // -1, -2, -3, ... etc for signed |
687 | // 0xFF, 0xFE, 0xFD, ... for unsigned |
688 | INSTANTIATE_TEST_CASE_P(SequentialReverseInt, |
689 | CodecTest, |
690 | ::testing::Combine( |
691 | DefaultCodecsToTest, |
692 | ::testing::Values( |
693 | generateSeq<Int8 >(G(SequentialGenerator(-1))), |
694 | generateSeq<Int16 >(G(SequentialGenerator(-1))), |
695 | generateSeq<Int32 >(G(SequentialGenerator(-1))), |
696 | generateSeq<Int64 >(G(SequentialGenerator(-1))), |
697 | generateSeq<UInt8 >(G(SequentialGenerator(-1))), |
698 | generateSeq<UInt16>(G(SequentialGenerator(-1))), |
699 | generateSeq<UInt32>(G(SequentialGenerator(-1))), |
700 | generateSeq<UInt64>(G(SequentialGenerator(-1))) |
701 | ) |
702 | ), |
703 | ); |
704 | |
705 | INSTANTIATE_TEST_CASE_P(SequentialFloat, |
706 | CodecTest, |
707 | ::testing::Combine( |
708 | ::testing::Values( |
709 | Codec("Gorilla" ), |
710 | Codec("Gorilla, LZ4" ) |
711 | ), |
712 | ::testing::Values( |
713 | generateSeq<Float32>(G(SequentialGenerator(M_E))), |
714 | generateSeq<Float64>(G(SequentialGenerator(M_E))) |
715 | ) |
716 | ), |
717 | ); |
718 | |
719 | INSTANTIATE_TEST_CASE_P(SequentialReverseFloat, |
720 | CodecTest, |
721 | ::testing::Combine( |
722 | ::testing::Values( |
723 | Codec("Gorilla" ), |
724 | Codec("Gorilla, LZ4" ) |
725 | ), |
726 | ::testing::Values( |
727 | generateSeq<Float32>(G(SequentialGenerator(-1 * M_E))), |
728 | generateSeq<Float64>(G(SequentialGenerator(-1 * M_E))) |
729 | ) |
730 | ), |
731 | ); |
732 | |
733 | INSTANTIATE_TEST_CASE_P(MonotonicInt, |
734 | CodecTest, |
735 | ::testing::Combine( |
736 | DefaultCodecsToTest, |
737 | ::testing::Values( |
738 | generateSeq<Int8 >(G(MonotonicGenerator(1, 5))), |
739 | generateSeq<Int16 >(G(MonotonicGenerator(1, 5))), |
740 | generateSeq<Int32 >(G(MonotonicGenerator(1, 5))), |
741 | generateSeq<Int64 >(G(MonotonicGenerator(1, 5))), |
742 | generateSeq<UInt8 >(G(MonotonicGenerator(1, 5))), |
743 | generateSeq<UInt16>(G(MonotonicGenerator(1, 5))), |
744 | generateSeq<UInt32>(G(MonotonicGenerator(1, 5))), |
745 | generateSeq<UInt64>(G(MonotonicGenerator(1, 5))) |
746 | ) |
747 | ), |
748 | ); |
749 | |
750 | INSTANTIATE_TEST_CASE_P(MonotonicReverseInt, |
751 | CodecTest, |
752 | ::testing::Combine( |
753 | DefaultCodecsToTest, |
754 | ::testing::Values( |
755 | generateSeq<Int8 >(G(MonotonicGenerator(-1, 5))), |
756 | generateSeq<Int16 >(G(MonotonicGenerator(-1, 5))), |
757 | generateSeq<Int32 >(G(MonotonicGenerator(-1, 5))), |
758 | generateSeq<Int64 >(G(MonotonicGenerator(-1, 5))), |
759 | generateSeq<UInt8 >(G(MonotonicGenerator(-1, 5))), |
760 | generateSeq<UInt16>(G(MonotonicGenerator(-1, 5))), |
761 | generateSeq<UInt32>(G(MonotonicGenerator(-1, 5))), |
762 | generateSeq<UInt64>(G(MonotonicGenerator(-1, 5))) |
763 | ) |
764 | ), |
765 | ); |
766 | |
767 | INSTANTIATE_TEST_CASE_P(MonotonicFloat, |
768 | CodecTest, |
769 | ::testing::Combine( |
770 | ::testing::Values( |
771 | Codec("Gorilla" ) |
772 | ), |
773 | ::testing::Values( |
774 | generateSeq<Float32>(G(MonotonicGenerator<Float32>(M_E, 5))), |
775 | generateSeq<Float64>(G(MonotonicGenerator<Float64>(M_E, 5))) |
776 | ) |
777 | ), |
778 | ); |
779 | |
780 | INSTANTIATE_TEST_CASE_P(MonotonicReverseFloat, |
781 | CodecTest, |
782 | ::testing::Combine( |
783 | ::testing::Values( |
784 | Codec("Gorilla" ) |
785 | ), |
786 | ::testing::Values( |
787 | generateSeq<Float32>(G(MonotonicGenerator<Float32>(-1 * M_E, 5))), |
788 | generateSeq<Float64>(G(MonotonicGenerator<Float64>(-1 * M_E, 5))) |
789 | ) |
790 | ), |
791 | ); |
792 | |
793 | INSTANTIATE_TEST_CASE_P(RandomInt, |
794 | CodecTest, |
795 | ::testing::Combine( |
796 | DefaultCodecsToTest, |
797 | ::testing::Values( |
798 | generateSeq<UInt8 >(G(RandomGenerator<UInt8>(0))), |
799 | generateSeq<UInt16>(G(RandomGenerator<UInt16>(0))), |
800 | generateSeq<UInt32>(G(RandomGenerator<UInt32>(0, 0, 1000'000'000))), |
801 | generateSeq<UInt64>(G(RandomGenerator<UInt64>(0, 0, 1000'000'000))) |
802 | ) |
803 | ), |
804 | ); |
805 | |
806 | INSTANTIATE_TEST_CASE_P(RandomishInt, |
807 | CodecTest, |
808 | ::testing::Combine( |
809 | DefaultCodecsToTest, |
810 | ::testing::Values( |
811 | generateSeq<Int32>(G(RandomishGenerator)), |
812 | generateSeq<Int64>(G(RandomishGenerator)), |
813 | generateSeq<UInt32>(G(RandomishGenerator)), |
814 | generateSeq<UInt64>(G(RandomishGenerator)), |
815 | generateSeq<Float32>(G(RandomishGenerator)), |
816 | generateSeq<Float64>(G(RandomishGenerator)) |
817 | ) |
818 | ), |
819 | ); |
820 | |
821 | INSTANTIATE_TEST_CASE_P(RandomishFloat, |
822 | CodecTest, |
823 | ::testing::Combine( |
824 | DefaultCodecsToTest, |
825 | ::testing::Values( |
826 | generateSeq<Float32>(G(RandomishGenerator)), |
827 | generateSeq<Float64>(G(RandomishGenerator)) |
828 | ) |
829 | ), |
830 | ); |
831 | |
832 | // Double delta overflow case, deltas are out of bounds for target type |
833 | INSTANTIATE_TEST_CASE_P(OverflowInt, |
834 | CodecTest, |
835 | ::testing::Combine( |
836 | ::testing::Values( |
837 | Codec("DoubleDelta" , 1.2), |
838 | Codec("DoubleDelta, LZ4" , 1.0) |
839 | ), |
840 | ::testing::Values( |
841 | generateSeq<UInt32>(G(MinMaxGenerator())), |
842 | generateSeq<Int32>(G(MinMaxGenerator())), |
843 | generateSeq<UInt64>(G(MinMaxGenerator())), |
844 | generateSeq<Int64>(G(MinMaxGenerator())) |
845 | ) |
846 | ), |
847 | ); |
848 | |
849 | INSTANTIATE_TEST_CASE_P(OverflowFloat, |
850 | CodecTest, |
851 | ::testing::Combine( |
852 | ::testing::Values( |
853 | Codec("Gorilla" , 1.1), |
854 | Codec("Gorilla, LZ4" , 1.0) |
855 | ), |
856 | ::testing::Values( |
857 | generateSeq<Float32>(G(MinMaxGenerator())), |
858 | generateSeq<Float64>(G(MinMaxGenerator())), |
859 | generateSeq<Float32>(G(FFand0Generator())), |
860 | generateSeq<Float64>(G(FFand0Generator())) |
861 | ) |
862 | ), |
863 | ); |
864 | |
865 | } |
866 | |