summaryrefslogtreecommitdiff
path: root/xdelta3/testing
diff options
context:
space:
mode:
Diffstat (limited to 'xdelta3/testing')
-rw-r--r--xdelta3/testing/Makefile3
-rw-r--r--xdelta3/testing/checksum_test.cc770
-rw-r--r--xdelta3/testing/checksum_test_c.c189
-rw-r--r--xdelta3/testing/delta.h38
-rw-r--r--xdelta3/testing/file.h30
-rw-r--r--xdelta3/testing/regtest.cc37
-rwxr-xr-xxdelta3/testing/run_release.sh2
-rw-r--r--xdelta3/testing/test.h6
8 files changed, 1022 insertions, 53 deletions
diff --git a/xdelta3/testing/Makefile b/xdelta3/testing/Makefile
index f859f94..d0b9c9e 100644
--- a/xdelta3/testing/Makefile
+++ b/xdelta3/testing/Makefile
@@ -3,3 +3,6 @@ all:
3 3
4xdelta3regtest: 4xdelta3regtest:
5 (cd .. && make xdelta3regtest) 5 (cd .. && make xdelta3regtest)
6
7xdelta3checksum:
8 (cd .. && make xdelta3checksum)
diff --git a/xdelta3/testing/checksum_test.cc b/xdelta3/testing/checksum_test.cc
new file mode 100644
index 0000000..9cd3740
--- /dev/null
+++ b/xdelta3/testing/checksum_test.cc
@@ -0,0 +1,770 @@
1/* xdelta3 - delta compression tools and library -*- Mode: C++ -*-
2 Copyright 2016 Joshua MacDonald
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17#include "test.h"
18#include <assert.h>
19#include <list>
20#include <vector>
21#include <algorithm>
22
23#include "../cpp-btree/btree_map.h"
24
25extern "C" {
26uint32_t xd3_large32_cksum_old (xd3_hash_cfg *cfg, const uint8_t *base, const usize_t look);
27uint32_t xd3_large32_cksum_update_old (xd3_hash_cfg *cfg, uint32_t cksum,
28 const uint8_t *base, const usize_t look);
29
30uint64_t xd3_large64_cksum_old (xd3_hash_cfg *cfg, const uint8_t *base, const usize_t look);
31uint64_t xd3_large64_cksum_update_old (xd3_hash_cfg *cfg, uint64_t cksum,
32 const uint8_t *base, const usize_t look);
33}
34
35using btree::btree_map;
36using std::list;
37using std::vector;
38
39// MLCG parameters
40// a, a*
41uint32_t good_32bit_values[] = {
42 1597334677U, // ...
43 741103597U, 887987685U,
44};
45
46// a, a*
47uint64_t good_64bit_values[] = {
48 1181783497276652981ULL, 4292484099903637661ULL,
49 7664345821815920749ULL, // ...
50};
51
52void print_header() {
53 static int hdr_cnt = 0;
54 if (hdr_cnt++ % 20 == 0) {
55 printf("%-32sConf\t\tCount\tUniq\tFull\tCover\tColls"
56 "\tMB/s\tIters\t#Colls\n", "Name");
57 }
58}
59
60struct true_type { };
61struct false_type { };
62
63template <typename Word>
64usize_t bitsof();
65
66template<>
67usize_t bitsof<unsigned int>() {
68 return sizeof(unsigned int) * 8;
69}
70
71template<>
72usize_t bitsof<unsigned long>() {
73 return sizeof(unsigned long) * 8;
74}
75
76template<>
77usize_t bitsof<unsigned long long>() {
78 return sizeof(unsigned long long) * 8;
79}
80
81template <typename Word>
82struct hhash { // shift "s" bits leaving the high bits as a hash value for
83 // this checksum, which are the most "distant" in terms of the
84 // spectral test for the rabin_karp MLCG. For short windows,
85 // the high bits aren't enough, XOR "mask" worth of these in.
86 Word operator()(const Word t, const Word s, const Word mask) {
87 return (t >> s) ^ (t & mask);
88 }
89};
90
91template <typename Word>
92Word good_word();
93
94template<>
95uint32_t good_word<uint32_t>() {
96 return good_32bit_values[0];
97}
98
99template<>
100uint64_t good_word<uint64_t>() {
101 return good_64bit_values[0];
102}
103
104// CLASSES
105
106#define SELF Word, CksumSize, CksumSkip, Hash, Compaction
107#define MEMBER template <typename Word, \
108 int CksumSize, \
109 int CksumSkip, \
110 typename Hash, \
111 int Compaction>
112
113MEMBER
114struct cksum_params {
115 typedef Word word_type;
116 typedef Hash hash_type;
117
118 static const int cksum_size = CksumSize;
119 static const int cksum_skip = CksumSkip;
120 static const int compaction = Compaction;
121};
122
123MEMBER
124struct rabin_karp : public cksum_params<SELF> {
125 // (a^cksum_size-1 c_0) + (a^cksum_size-2 c_1) ...
126 rabin_karp()
127 : powers(make_powers()),
128 product(powers[0] * good_word<Word>()),
129 incr_state(0) { }
130
131 static Word* make_powers() {
132 Word *p = new Word[CksumSize];
133 p[CksumSize - 1] = 1;
134 for (int i = CksumSize - 2; i >= 0; i--) {
135 p[i] = p[i + 1] * good_word<Word>();
136 }
137 return p;
138 }
139
140 ~rabin_karp() {
141 delete [] powers;
142 }
143
144 Word step(const uint8_t *ptr) {
145 Word h = 0;
146 for (int i = 0; i < CksumSize; i++) {
147 h += (ptr[i]) * powers[i];
148 }
149 return h;
150 }
151
152 Word state0(const uint8_t *ptr) {
153 incr_state = step(ptr);
154 return incr_state;
155 }
156
157 Word incr(const uint8_t *ptr) {
158 incr_state = good_word<Word>() * incr_state -
159 product * (ptr[-1]) + (ptr[CksumSize - 1]);
160 return incr_state;
161 }
162
163 const Word *const powers;
164 const Word product;
165 Word incr_state;
166};
167
168MEMBER
169struct with_stream : public cksum_params<SELF> {
170 xd3_stream stream;
171
172 with_stream()
173 {
174 xd3_config cfg;
175 memset (&stream, 0, sizeof (stream));
176 xd3_init_config (&cfg, 0);
177 cfg.smatch_cfg = XD3_SMATCH_SOFT;
178 cfg.smatcher_soft.large_look = CksumSize;
179 cfg.smatcher_soft.large_step = CksumSkip;
180 cfg.smatcher_soft.small_look = 4;
181 cfg.smatcher_soft.small_chain = 4;
182 cfg.smatcher_soft.small_lchain = 4;
183 cfg.smatcher_soft.max_lazy = 4;
184 cfg.smatcher_soft.long_enough = 4;
185 CHECK_EQ(0, xd3_config_stream (&stream, &cfg));
186
187 CHECK_EQ(0, xd3_size_hashtable (&stream,
188 1<<10 /* ignored */,
189 stream.smatcher.large_look,
190 & stream.large_hash));
191 }
192 ~with_stream()
193 {
194 xd3_free_stream (&stream);
195 }
196};
197
198MEMBER
199struct large_cksum : public with_stream<SELF> {
200 Word step(const uint8_t *ptr) {
201 return xd3_large_cksum (&this->stream.large_hash, ptr, CksumSize);
202 }
203
204 Word state0(const uint8_t *ptr) {
205 incr_state = step(ptr);
206 return incr_state;
207 }
208
209 Word incr(const uint8_t *ptr) {
210 incr_state = xd3_large_cksum_update (&this->stream.large_hash,
211 incr_state, ptr - 1, CksumSize);
212 return incr_state;
213 }
214
215 Word incr_state;
216};
217
218#if SIZEOF_USIZE_T == 4
219#define xd3_large_cksum_old xd3_large32_cksum_old
220#define xd3_large_cksum_update_old xd3_large32_cksum_update_old
221#elif SIZEOF_USIZE_T == 8
222#define xd3_large_cksum_old xd3_large64_cksum_old
223#define xd3_large_cksum_update_old xd3_large64_cksum_update_old
224#endif
225
226MEMBER
227struct large_cksum_old : public with_stream<SELF> {
228 Word step(const uint8_t *ptr) {
229 return xd3_large_cksum_old (&this->stream.large_hash, ptr, CksumSize);
230 }
231
232 Word state0(const uint8_t *ptr) {
233 incr_state = step(ptr);
234 return incr_state;
235 }
236
237 Word incr(const uint8_t *ptr) {
238 incr_state = xd3_large_cksum_update_old (&this->stream.large_hash,
239 incr_state, ptr - 1, CksumSize);
240 return incr_state;
241 }
242
243 Word incr_state;
244};
245
246// TESTS
247
248template <typename Word>
249struct file_stats {
250 typedef const uint8_t* ptr_type;
251 typedef Word word_type;
252 typedef btree::btree_multimap<word_type, ptr_type> table_type;
253 typedef typename table_type::iterator table_iterator;
254
255 usize_t cksum_size;
256 usize_t cksum_skip;
257 usize_t unique;
258 usize_t unique_values;
259 usize_t count;
260 table_type table;
261
262 file_stats(usize_t size, usize_t skip)
263 : cksum_size(size),
264 cksum_skip(skip),
265 unique(0),
266 unique_values(0),
267 count(0) {
268 }
269
270 void reset() {
271 unique = 0;
272 unique_values = 0;
273 count = 0;
274 table.clear();
275 }
276
277 void update(word_type word, ptr_type ptr) {
278 table_iterator t_i = table.find(word);
279
280 count++;
281 if (t_i != table.end()) {
282 int collisions = 0;
283 for (table_iterator p_i = t_i;
284 p_i != table.end() && p_i->first == word;
285 ++p_i) {
286 if (memcmp(p_i->second, ptr, cksum_size) == 0) {
287 return;
288 }
289 collisions++;
290 }
291 if (collisions >= 1000) {
292 fprintf(stderr, "Something is not right, lots of collisions=%d\n",
293 collisions);
294 abort();
295 }
296 } else {
297 unique_values++;
298 }
299 unique++;
300 table.insert(std::make_pair(word, ptr));
301 return;
302 }
303
304 void freeze() {
305 table.clear();
306 }
307};
308
309struct test_result_base;
310
311static vector<test_result_base*> all_tests;
312
313struct test_result_base {
314 virtual ~test_result_base() {
315 }
316 virtual void reset() = 0;
317 virtual void print() = 0;
318 virtual void get(const uint8_t* buf, const size_t buf_size,
319 usize_t iters) = 0;
320 virtual void stat() = 0;
321 virtual usize_t count() = 0;
322 virtual usize_t dups() = 0;
323 virtual double uniqueness() = 0;
324 virtual double fullness() = 0;
325 virtual double collisions() = 0;
326 virtual double coverage() = 0;
327 virtual double compression() = 0;
328 virtual double time() = 0;
329 virtual double total_time() = 0;
330 virtual usize_t total_count() = 0;
331 virtual usize_t total_dups() = 0;
332};
333
334template <typename Checksum>
335struct test_result : public test_result_base {
336 Checksum cksum;
337 const char *test_name;
338 file_stats<typename Checksum::word_type> fstats;
339 usize_t test_size;
340 usize_t n_steps;
341 usize_t n_incrs;
342 typename Checksum::word_type s_bits;
343 typename Checksum::word_type s_mask;
344 usize_t t_entries;
345 usize_t h_bits;
346 usize_t h_buckets_full;
347 char *hash_table;
348 long accum_millis;
349 usize_t accum_iters;
350
351 // These are not reset
352 double accum_time;
353 usize_t accum_count;
354 usize_t accum_dups;
355 usize_t accum_colls;
356 size_t accum_size;
357
358 test_result(const char *name)
359 : test_name(name),
360 fstats(Checksum::cksum_size, Checksum::cksum_skip),
361 hash_table(NULL),
362 accum_millis(0),
363 accum_iters(0),
364 accum_time(0.0),
365 accum_count(0),
366 accum_dups(0),
367 accum_colls(0),
368 accum_size(0) {
369 all_tests.push_back(this);
370 }
371
372 ~test_result() {
373 reset();
374 }
375
376 void reset() {
377 // size of file
378 test_size = 0;
379
380 // count
381 n_steps = 0;
382 n_incrs = 0;
383
384 // four values used by new_table()/summarize_table()
385 s_bits = 0;
386 s_mask = 0;
387 t_entries = 0;
388 h_bits = 0;
389 h_buckets_full = 0;
390
391 accum_millis = 0;
392 accum_iters = 0;
393
394 fstats.reset();
395
396 // temporary
397 if (hash_table) {
398 delete(hash_table);
399 hash_table = NULL;
400 }
401 }
402
403 usize_t count() {
404 if (Checksum::cksum_skip == 1) {
405 return n_incrs;
406 } else {
407 return n_steps;
408 }
409 }
410
411 usize_t dups() {
412 return fstats.count - fstats.unique;
413 }
414
415 /* Fraction of distinct strings of length cksum_size which are not
416 * represented in the hash table. */
417 double collisions() {
418 return (fstats.unique - fstats.unique_values) / (double) fstats.unique;
419 }
420 usize_t colls() {
421 return (fstats.unique - fstats.unique_values);
422 }
423
424 double uniqueness() {
425 return 1.0 - (double) dups() / count();
426 }
427
428 double fullness() {
429 return (double) h_buckets_full / (1 << h_bits);
430 }
431
432 double coverage() {
433 return (double) h_buckets_full / uniqueness() / count();
434 }
435
436 double compression() {
437 return 1.0 - coverage();
438 }
439
440 double time() {
441 return (double) accum_millis / accum_iters;
442 }
443
444 double total_time() {
445 return accum_time;
446 }
447
448 usize_t total_count() {
449 return accum_count;
450 }
451
452 usize_t total_dups() {
453 return accum_dups;
454 }
455
456 usize_t total_colls() {
457 return accum_dups;
458 }
459
460 void stat() {
461 accum_time += time();
462 accum_count += count();
463 accum_dups += dups();
464 accum_colls += colls();
465 accum_size += test_size;
466 }
467
468 void print() {
469 if (fstats.count != count()) {
470 fprintf(stderr, "internal error: %" W "d != %" W "d\n", fstats.count, count());
471 abort();
472 }
473 print_header();
474 printf("%-32s%d/%d 2^%" W "u\t%" W "u\t%0.4f\t%.4f\t%.4f\t%.1e\t%.2f\t"
475 "%" W "u\t%" W "u\n",
476 test_name,
477 Checksum::cksum_size,
478 Checksum::cksum_skip,
479 h_bits,
480 count(),
481 uniqueness(),
482 fullness(),
483 coverage(),
484 collisions(),
485 0.001 * accum_iters * test_size / accum_millis,
486 accum_iters,
487 colls());
488 }
489
490 usize_t size_log2 (usize_t slots) {
491 usize_t bits = bitsof<typename Checksum::word_type>() - 1;
492 usize_t i;
493
494 for (i = 3; i <= bits; i += 1) {
495 if (slots <= (1U << i)) {
496 return i - Checksum::compaction;
497 }
498 }
499
500 return bits;
501 }
502
503 void new_table(usize_t entries) {
504 t_entries = entries;
505 h_bits = size_log2(entries);
506
507 usize_t n = 1 << h_bits;
508
509 s_bits = bitsof<typename Checksum::word_type>() - h_bits;
510 s_mask = n - 1U;
511
512 hash_table = new char[n / 8];
513 memset(hash_table, 0, n / 8);
514 }
515
516 int get_table_bit(usize_t i) {
517 return hash_table[i/8] & (1 << i%8);
518 }
519
520 int set_table_bit(usize_t i) {
521 return hash_table[i/8] |= (1 << i%8);
522 }
523
524 void summarize_table() {
525 usize_t n = 1 << h_bits;
526 usize_t f = 0;
527 for (usize_t i = 0; i < n; i++) {
528 if (get_table_bit(i)) {
529 f++;
530 }
531 }
532 h_buckets_full = f;
533 }
534
535 void get(const uint8_t* buf, const size_t buf_size, usize_t test_iters) {
536 typename Checksum::hash_type hash;
537 const uint8_t *ptr;
538 const uint8_t *end;
539 usize_t periods;
540 int64_t last_offset;
541 int64_t stop;
542
543 test_size = buf_size;
544 last_offset = buf_size - Checksum::cksum_size;
545
546 if (last_offset < 0) {
547 periods = 0;
548 n_steps = 0;
549 n_incrs = 0;
550 stop = -Checksum::cksum_size;
551 } else {
552 periods = last_offset / Checksum::cksum_skip;
553 n_steps = periods + 1;
554 n_incrs = last_offset + 1;
555 stop = last_offset - (periods + 1) * Checksum::cksum_skip;
556 }
557
558 // Compute file stats once.
559 if (fstats.unique_values == 0) {
560 if (Checksum::cksum_skip == 1) {
561 for (size_t i = 0; i <= buf_size - Checksum::cksum_size; i++) {
562 fstats.update(hash(cksum.step(buf + i), s_bits, s_mask), buf + i);
563 }
564 } else {
565 ptr = buf + last_offset;
566 end = buf + stop;
567
568 for (; ptr != end; ptr -= Checksum::cksum_skip) {
569 fstats.update(hash(cksum.step(ptr), s_bits, s_mask), ptr);
570 }
571 }
572 fstats.freeze();
573 }
574
575 long start_test = get_millisecs_now();
576
577 if (Checksum::cksum_skip != 1) {
578 new_table(n_steps);
579
580 for (usize_t i = 0; i < test_iters; i++) {
581 ptr = buf + last_offset;
582 end = buf + stop;
583
584 for (; ptr != end; ptr -= Checksum::cksum_skip) {
585 set_table_bit(hash(cksum.step(ptr), s_bits, s_mask));
586 }
587 }
588
589 summarize_table();
590 }
591
592 stop = buf_size - Checksum::cksum_size + 1;
593 if (stop < 0) {
594 stop = 0;
595 }
596
597 if (Checksum::cksum_skip == 1) {
598 new_table(n_incrs);
599
600 for (usize_t i = 0; i < test_iters; i++) {
601 ptr = buf;
602 end = buf + stop;
603
604 if (ptr != end) {
605 set_table_bit(hash(cksum.state0(ptr++), s_bits, s_mask));
606 }
607
608 for (; ptr != end; ptr++) {
609 typename Checksum::word_type w = cksum.incr(ptr);
610 CHECK_EQ(w, cksum.step(ptr));
611 set_table_bit(hash(w, s_bits, s_mask));
612 }
613 }
614
615 summarize_table();
616 }
617
618 accum_iters += test_iters;
619 accum_millis += get_millisecs_now() - start_test;
620 }
621};
622
623static int read_whole_file(const char *name,
624 uint8_t **buf_ptr,
625 size_t *buf_len) {
626 main_file file;
627 int ret;
628 xoff_t len;
629 size_t nread;
630 main_file_init(&file);
631 file.filename = name;
632 ret = main_file_open(&file, name, XO_READ);
633 if (ret != 0) {
634 fprintf(stderr, "open failed\n");
635 goto exit;
636 }
637 ret = main_file_stat(&file, &len);
638 if (ret != 0) {
639 fprintf(stderr, "stat failed\n");
640 goto exit;
641 }
642
643 (*buf_len) = (size_t)len;
644 (*buf_ptr) = (uint8_t*) main_malloc(*buf_len);
645 ret = main_file_read(&file, *buf_ptr, *buf_len, &nread,
646 "read failed");
647 if (ret == 0 && *buf_len == nread) {
648 ret = 0;
649 } else {
650 fprintf(stderr, "invalid read\n");
651 ret = XD3_INTERNAL;
652 }
653 exit:
654 main_file_cleanup(&file);
655 return ret;
656}
657
658int main(int argc, char** argv) {
659 int i;
660 uint8_t *buf = NULL;
661 size_t buf_len = 0;
662 int ret;
663
664 if (argc <= 1) {
665 fprintf(stderr, "usage: %s file ...\n", argv[0]);
666 return 1;
667 }
668
669// TODO: The xdelta3-hash.h code is identical now; add sameness test.
670// using rabin_karp<> template.
671#define TEST(T,Z,S,C) \
672 test_result<large_cksum<T,Z,S,hhash<T>,C>> \
673 _xck_ ## T ## _ ## Z ## _ ## S ## _ ## C \
674 ("xck_" #T "_" #Z "_" #S "_" #C); \
675 test_result<large_cksum_old<T,Z,S,hhash<T>,C>> \
676 _old_ ## T ## _ ## Z ## _ ## S ## _ ## C \
677 ("old_" #T "_" #Z "_" #S "_" #C)
678
679#define TESTS(SIZE, SKIP) \
680 TEST(usize_t, SIZE, SKIP, 1); \
681 TEST(usize_t, SIZE, SKIP, 2)
682
683 TESTS(5, 1);
684 TESTS(6, 1);
685 TESTS(7, 1);
686 TESTS(8, 1);
687 TESTS(9, 1);
688 TESTS(10, 1);
689 TESTS(11, 1);
690 TESTS(12, 1);
691 TESTS(13, 1);
692 TESTS(14, 1);
693 TESTS(15, 1);
694 TESTS(16, 1);
695 TESTS(17, 1);
696 TESTS(18, 1);
697 TESTS(19, 1);
698 TESTS(20, 1);
699 TESTS(21, 1);
700 TESTS(22, 1);
701 TESTS(23, 1);
702 TESTS(24, 1);
703 TESTS(25, 1);
704 TESTS(26, 1);
705 TESTS(27, 1);
706 TESTS(28, 1);
707 TESTS(29, 1);
708 TESTS(30, 1);
709 TESTS(31, 1);
710 TESTS(32, 1);
711 TESTS(33, 1);
712 TESTS(34, 1);
713 TESTS(35, 1);
714 TESTS(36, 1);
715 TESTS(37, 1);
716 TESTS(38, 1);
717 TESTS(39, 1);
718
719
720 for (i = 1; i < argc; i++) {
721 if ((ret = read_whole_file(argv[i],
722 & buf,
723 & buf_len))) {
724 return 1;
725 }
726
727 fprintf(stderr, "file %s is %zu bytes\n",
728 argv[i], buf_len);
729
730 double min_time = -1.0;
731 double min_compression = 0.0;
732
733 for (vector<test_result_base*>::iterator iter = all_tests.begin();
734 iter != all_tests.end(); ++iter) {
735 test_result_base *test = *iter;
736 test->reset();
737
738 usize_t iters = 1;
739 long start_test = get_millisecs_now();
740
741 do {
742 test->get(buf, buf_len, iters);
743 iters *= 3;
744 iters /= 2;
745 } while (get_millisecs_now() - start_test < 2000);
746
747 test->stat();
748
749 if (min_time < 0.0) {
750 min_compression = test->compression();
751 min_time = test->time();
752 }
753
754 if (min_time > test->time()) {
755 min_time = test->time();
756 }
757
758 if (min_compression > test->compression()) {
759 min_compression = test->compression();
760 }
761
762 test->print();
763 }
764
765 main_free(buf);
766 buf = NULL;
767 }
768
769 return 0;
770}
diff --git a/xdelta3/testing/checksum_test_c.c b/xdelta3/testing/checksum_test_c.c
new file mode 100644
index 0000000..7b2ab44
--- /dev/null
+++ b/xdelta3/testing/checksum_test_c.c
@@ -0,0 +1,189 @@
1/* xdelta3 - delta compression tools and library -*- Mode: C++ -*-
2 Copyright 2016 Joshua MacDonald
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16#include "../xdelta3.c"
17
18// OLD CHECKSUM CODE
19
20#define PERMUTE32(x) (__single_hash32[x])
21#define PERMUTE64(x) (__single_hash64[x])
22
23const uint16_t __single_hash32[256] =
24{
25 /* This hashes the input alphabet (Scheme SLIB pseudo-random). */
26 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46,
27 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602,
28 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6,
29 0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a,
30 0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58,
31 0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b,
32 0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94,
33 0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176,
34 0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743,
35 0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6,
36 0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227,
37 0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d,
38 0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a,
39 0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31,
40 0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9,
41 0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6,
42 0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f,
43 0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f,
44 0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49,
45 0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037,
46 0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad,
47 0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f,
48 0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d,
49 0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b,
50 0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624,
51 0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272,
52 0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806,
53 0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050,
54 0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113,
55 0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2,
56 0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25,
57 0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5
58};
59
60const uint32_t __single_hash64[256] =
61{
62 /* http://random.org 2014.10.24 */
63 0xd25e9f0a, 0xb1af9d5e, 0xb753dfa2, 0x157050f7, /* 0 */
64 0xc84b072c, 0xdd14fe7c, 0xf92208c3, 0xdf08a0c0,
65 0x63a5c118, 0x76f5d90f, 0xa2f8b93e, 0xb6c12d22,
66 0xaf074957, 0x966fb7d9, 0x62f7b785, 0xb40e8a09,
67 0x0a811d5d, 0x323a6daa, 0xb62f7c5b, 0xfdcb9a53,
68 0xf25a9067, 0x4506bc7a, 0xff58a74b, 0x5ae62817,
69 0x74097675, 0x722c0fd9, 0x116a2a66, 0x65f76728,
70 0x72c79651, 0xe043cf9d, 0x64b867c7, 0x6604834f,
71 0xcdca58a6, 0x0f164e2d, 0x24515f05, 0x632cdbf8,
72 0x18091d4a, 0x3eff4128, 0x673d1c33, 0xd8e10c71,
73 0x1a3edf11, 0xba52892f, 0xa56949e0, 0xf3e1dd77, /* 10 */
74 0x86fcbe3e, 0x138d66d0, 0x4fc98359, 0xc22e5dd6,
75 0xc59f2267, 0x6c6dd739, 0xe03da190, 0x07e8469c,
76 0xadcfb02c, 0x00d3b0d9, 0xa1f44918, 0x8bd84d87,
77 0x08ec9ec1, 0xbbcd156f, 0xb57718e3, 0x3177e752,
78 0xf52a4d70, 0xde7aaad9, 0x075f1da0, 0x21ba00c6,
79 0xb9469a5c, 0xcf08d5ba, 0x91ac9edc, 0xc6167b63,
80 0xc1974919, 0xc8c8d195, 0x4b1996dd, 0xeff8991c,
81 0xf7f66c6b, 0x25b012e2, 0x59d12a98, 0xea40d3cc,
82 0x41f9970b, 0xec48101a, 0xa3bdcf90, 0x99f16905,
83 0x27af6c97, 0xc849af37, 0x49cad89b, 0xf48c2278, /* 20 */
84 0x5529c3d8, 0x9e7d6dce, 0x16feb52d, 0xf1b0aca1,
85 0xaf28fccb, 0x48e4ce3c, 0xc4436617, 0x64524e3e,
86 0x61806681, 0x6384f2d7, 0x1172880f, 0x34a5ef5f,
87 0xcc8cc0a8, 0x66e8f100, 0x2866085f, 0xba9b1b2d,
88 0x51285949, 0x2be4b574, 0x889b1ef5, 0x3dbe920d,
89 0x9277a62f, 0x0584a9f6, 0x085d8fc4, 0x4b5d403d,
90 0x4e46ca78, 0x3294c2f9, 0x29313e70, 0xe4f09b24,
91 0xe73b331c, 0x072f5552, 0x2e390b78, 0xea0021ca,
92 0xd8f40320, 0xed0e16fd, 0x7de9cf7a, 0xf17e3d6c,
93 0x8df1bd85, 0x052cae67, 0x3486e512, 0x3a1c09b8, /* 30 */
94 0x6c2a7b4e, 0x83455753, 0xbc0353ac, 0x0ffe20b6,
95 0x5fdcef85, 0x010f506c, 0x595ce972, 0xe28680d0,
96 0xa7e216b2, 0xa392ee0f, 0x25b73faa, 0x2b1f4983,
97 0xeeaefe98, 0x1d3d9cbc, 0x6aebe97b, 0x8b7b3584,
98 0x9e6a9a07, 0xd37f1e99, 0x4ac2a441, 0x8ae9a213,
99 0x7d0e27d7, 0x5de54b9a, 0x8621de1f, 0xf0f2f866,
100 0xcb08d275, 0x49c3f87e, 0xd5ee68c1, 0x9802fc77,
101 0x68be6c5e, 0x65aa8c27, 0xf423d5f7, 0x10ec5502,
102 0x9909bce1, 0x509cdf1b, 0x338fea72, 0x2733e9bf,
103 0xf92f4fd7, 0x87738ea2, 0x931a8bbc, 0x0a5c9155, /* 40 */
104 0xbe5edd9b, 0xadbf5838, 0x0338f8d2, 0x290da210,
105 0x390c37d8, 0xe7cffae8, 0x20617ebe, 0x464322dd,
106 0x7b3c4e78, 0xac142dcb, 0x2d5cef76, 0xd8fe49fc,
107 0x60f4e9a9, 0x7473816f, 0x0dc35f39, 0x5eed80c1,
108 0x0cb55ab6, 0x1d3ac541, 0x13c7f529, 0x7bffdf4a,
109 0xe334785b, 0x85263ec1, 0xd132ae56, 0x7c868b9e,
110 0x47f60638, 0x1012b979, 0x81c31dd3, 0x1af868c8,
111 0x0c5d0742, 0xd1b3e1a2, 0x5873200a, 0xf848465c,
112 0x0fc4d596, 0x609c18af, 0xc9f5a480, 0xd1a94a84,
113 0xa1431a3f, 0x7de8bb1a, 0x25f1256b, 0x1dcc732c, /* 50 */
114 0x6aa1549a, 0xa2367281, 0x32f2a77e, 0x82e62a0f,
115 0x045cbb56, 0x74b2027c, 0xd71a32d9, 0x022e7cb5,
116 0xe99be177, 0x60222fdf, 0xd69681ca, 0x9008ee2c,
117 0x32923db4, 0xcf82bf97, 0x38960a5b, 0xb3503d5b,
118 0x9bd4c7f2, 0x33c029c8, 0x1ef504a3, 0xdb249d3b,
119 0x91e89676, 0x4ca43b36, 0x9191433c, 0x465d5dc4,
120 0xf4dcb118, 0x9d11dd00, 0xb592f058, 0xdbe5ce30,
121 0x74790d92, 0x779850a8, 0x7180d25b, 0xfa951d99,
122 0x5990935a, 0x921cb022, 0x3b7c39bc, 0x6a38a7c7,
123 0xdc22703b, 0x142bab3b, 0x4e3d9479, 0x44bb8482, /* 60 */
124 0x8043abce, 0xfebe832a, 0x8e6a2f98, 0x4d43c4fe,
125 0xd192a70a, 0x802f3c3a, 0x5d11bbab, 0x2665d241,
126 0xb3f3a680, 0x3a8d223f, 0xcf82cdb4, 0x4ed28743,
127};
128
129uint64_t
130xd3_large64_cksum_old (xd3_hash_cfg *ignore, const uint8_t *base, const usize_t look)
131{
132 static const uint64_t kBits = 32;
133 static const uint64_t kMask = 0xffffffff;
134 usize_t i = 0;
135 uint64_t low = 0;
136 uint64_t high = 0;
137
138 for (; i < look; i += 1)
139 {
140 low += PERMUTE64(*base++);
141 high += low;
142 }
143
144 return ((high & kMask) << kBits) | (low & kMask);
145}
146
147uint64_t
148xd3_large64_cksum_update_old (xd3_hash_cfg *ignore, const uint64_t cksum,
149 const uint8_t *base, const usize_t look)
150{
151 static const uint64_t kBits = 32;
152 static const uint64_t kMask = 0xffffffff;
153 uint64_t old_c = PERMUTE64(base[0]);
154 uint64_t new_c = PERMUTE64(base[look]);
155 uint64_t low = ((cksum & kMask) - old_c + new_c) & kMask;
156 uint64_t high = ((cksum >> kBits) - (old_c * look) + low) & kMask;
157 return (high << kBits) | low;
158}
159
160uint32_t
161xd3_large32_cksum_old (xd3_hash_cfg *ignore, const uint8_t *base, const usize_t look)
162{
163 static const uint32_t kBits = 16;
164 static const uint32_t kMask = 0xffff;
165 usize_t i = 0;
166 uint32_t low = 0;
167 uint32_t high = 0;
168
169 for (; i < look; i += 1)
170 {
171 low += PERMUTE32(*base++);
172 high += low;
173 }
174
175 return ((high & kMask) << kBits) | (low & kMask);
176}
177
178uint32_t
179xd3_large32_cksum_update_old (xd3_hash_cfg *ignore, const uint32_t cksum,
180 const uint8_t *base, const usize_t look)
181{
182 static const uint32_t kBits = 16;
183 static const uint32_t kMask = 0xffff;
184 uint32_t old_c = PERMUTE32(base[0]);
185 uint32_t new_c = PERMUTE32(base[look]);
186 uint32_t low = ((cksum & kMask) - old_c + new_c) & kMask;
187 uint32_t high = ((cksum >> kBits) - (old_c * look) + low) & kMask;
188 return (high << kBits) | low;
189}
diff --git a/xdelta3/testing/delta.h b/xdelta3/testing/delta.h
index af1b211..bd38c6c 100644
--- a/xdelta3/testing/delta.h
+++ b/xdelta3/testing/delta.h
@@ -44,7 +44,7 @@ public:
44 case XD3_WINFINISH: 44 case XD3_WINFINISH:
45 break; 45 break;
46 default: 46 default:
47 DP(RINT "error code %s\n", xd3_strerror (ret)); 47 cerr << "decode: " << done;
48 abort(); 48 abort();
49 } 49 }
50 } 50 }
@@ -62,23 +62,25 @@ public:
62 return stream_.whole_target.wininfolen; 62 return stream_.whole_target.wininfolen;
63 } 63 }
64 64
65 void Print() const { 65// Note: This does not benefit from -Wformat= checking, due to the
66 for (size_t i = 0; i < stream_.whole_target.instlen; i++) { 66// enclosing template. Further, it was not used.
67 xd3_winst &winst = stream_.whole_target.inst[i]; 67// void Print() const {
68 switch (winst.type) { 68// for (size_t i = 0; i < stream_.whole_target.instlen; i++) {
69 case XD3_RUN: 69// xd3_winst &winst = stream_.whole_target.inst[i];
70 DP(RINT "%"Q"u run %u\n", winst.position, winst.size); 70// switch (winst.type) {
71 break; 71// case XD3_RUN:
72 case XD3_ADD: 72// DP(RINT, "%" Q "u run %" W "u\n", winst.position, winst.size);
73 DP(RINT "%"Q"u add %u\n", winst.position, winst.size); 73// break;
74 break; 74// case XD3_ADD:
75 default: 75// DP(RINT "%" Q "u add %" W "u\n", winst.position, winst.size);
76 DP(RINT "%"Q"u copy %u @ %"Q"u (mode %u)\n", 76// break;
77 winst.position, winst.size, winst.addr, winst.mode); 77// default:
78 break; 78// DP(RINT "%" Q "u copy %" W "u @ %" Q "u (mode %u)\n",
79 } 79// winst.position, winst.size, winst.addr, winst.mode);
80 } 80// break;
81 } 81// }
82// }
83// }
82 84
83private: 85private:
84 xd3_stream stream_; 86 xd3_stream stream_;
diff --git a/xdelta3/testing/file.h b/xdelta3/testing/file.h
index 9e8dee6..d1828cf 100644
--- a/xdelta3/testing/file.h
+++ b/xdelta3/testing/file.h
@@ -76,20 +76,22 @@ public:
76 size_ = 0; 76 size_ = 0;
77 } 77 }
78 78
79 void Print() const { 79 // Note: This does not benefit from -Wformat= checking, due to the
80 xoff_t pos = 0; 80 // enclosing template. Further, it was not used.
81 for (size_t i = 0; i < Size(); i++) { 81 // void Print() const {
82 if (pos % 16 == 0) { 82 // xoff_t pos = 0;
83 DP(RINT "%5"Q"x: ", pos); 83 // for (size_t i = 0; i < Size(); i++) {
84 } 84 // if (pos % 16 == 0) {
85 DP(RINT "%02x ", (*this)[i]); 85 // DP(RINT "%5" Q "x: ", pos);
86 if (pos % 16 == 15) { 86 // }
87 DP(RINT "\n"); 87 // DP(RINT "%02x ", (*this)[i]);
88 } 88 // if (pos % 16 == 15) {
89 pos++; 89 // DP(RINT "\n");
90 } 90 // }
91 DP(RINT "\n"); 91 // pos++;
92 } 92 // }
93 // DP(RINT "\n");
94 // }
93 95
94 void WriteTmpFile(TmpFile *f) const { 96 void WriteTmpFile(TmpFile *f) const {
95 f->Append(this); 97 f->Append(this);
diff --git a/xdelta3/testing/regtest.cc b/xdelta3/testing/regtest.cc
index 49cfe5d..daddc0d 100644
--- a/xdelta3/testing/regtest.cc
+++ b/xdelta3/testing/regtest.cc
@@ -107,22 +107,24 @@ public:
107 bool done = false; 107 bool done = false;
108 bool done_after_input = false; 108 bool done_after_input = false;
109 109
110 IF_DEBUG1 (XPR(NTR "source %"Q"u[%"Q"u] target %"Q"u winsize %"Z"u\n", 110 IF_DEBUG1 (XPR(NTR "source %" Q "u[%" Z "u] target %" Q "u winsize %" Z "u\n",
111 source_file.Size(), options.block_size, 111 source_file.Size(), options.block_size,
112 target_file.Size(), 112 target_file.Size(),
113 Constants::WINDOW_SIZE)); 113 Constants::WINDOW_SIZE));
114 114
115 while (!done) { 115 while (!done) {
116 target_iterator.Get(&target_block); 116 target_iterator.Get(&target_block);
117 117
118 xoff_t blks = target_iterator.Blocks(); 118 xoff_t blks = target_iterator.Blocks();
119 119
120 IF_DEBUG2(XPR(NTR "target in %s: %"Q"u..%"Q"u %"Q"u(%"Q"u) " 120 IF_DEBUG2(XPR(NTR "target in %s: %" Q "u[%" Z "u] %" Q "u(%" Q "u) "
121 "verified %"Q"u\n", 121 "verified %" Q "u\n",
122 encoding ? "encoding" : "decoding", 122 encoding ? "encoding" : "decoding",
123 target_iterator.Offset(), 123 target_iterator.Offset(),
124 target_iterator.Offset() + target_block.Size(), 124 target_block.Size(),
125 target_iterator.Blkno(), blks, verified_bytes)); 125 target_iterator.Blkno(),
126 blks,
127 verified_bytes));
126 128
127 if (blks == 0 || target_iterator.Blkno() == (blks - 1)) { 129 if (blks == 0 || target_iterator.Blkno() == (blks - 1)) {
128 xd3_set_flags(&encode_stream, XD3_FLUSH | encode_stream.flags); 130 xd3_set_flags(&encode_stream, XD3_FLUSH | encode_stream.flags);
@@ -168,8 +170,8 @@ public:
168 xd3_source *src = (encoding ? &encode_source : &decode_source); 170 xd3_source *src = (encoding ? &encode_source : &decode_source);
169 Block *block = (encoding ? &encode_source_block : &decode_source_block); 171 Block *block = (encoding ? &encode_source_block : &decode_source_block);
170 if (encoding) { 172 if (encoding) {
171 IF_DEBUG2(XPR(NTR "[srcblock] %"Q"u last srcpos %"Q"u " 173 IF_DEBUG2(XPR(NTR "[srcblock] %" Q "u last srcpos %" Q "u "
172 "encodepos %"Q"u\n", 174 "encodepos %" Q "u\n",
173 encode_source.getblkno, 175 encode_source.getblkno,
174 encode_stream.match_last_srcpos, 176 encode_stream.match_last_srcpos,
175 encode_stream.input_position + encode_stream.total_in)); 177 encode_stream.input_position + encode_stream.total_in));
@@ -246,7 +248,7 @@ public:
246 const Options &options) { 248 const Options &options) {
247 vector<const char*> ecmd; 249 vector<const char*> ecmd;
248 char bbuf[16]; 250 char bbuf[16];
249 snprintf(bbuf, sizeof(bbuf), "-B%"Q"u", options.encode_srcwin_maxsz); 251 snprintf(bbuf, sizeof(bbuf), "-B%" Q "u", options.encode_srcwin_maxsz);
250 ecmd.push_back("xdelta3"); 252 ecmd.push_back("xdelta3");
251 ecmd.push_back(bbuf); 253 ecmd.push_back(bbuf);
252 ecmd.push_back("-s"); 254 ecmd.push_back("-s");
@@ -386,7 +388,7 @@ public:
386void TestPrintf() { 388void TestPrintf() {
387 char buf[64]; 389 char buf[64];
388 xoff_t x = XOFF_T_MAX; 390 xoff_t x = XOFF_T_MAX;
389 snprintf_func (buf, sizeof(buf), "%"Q"u", x); 391 snprintf_func (buf, sizeof(buf), "%" Q "u", x);
390 const char *expect = XD3_USE_LARGEFILE64 ? 392 const char *expect = XD3_USE_LARGEFILE64 ?
391 "18446744073709551615" : "4294967295"; 393 "18446744073709551615" : "4294967295";
392 XD3_ASSERT(strcmp (buf, expect) == 0); 394 XD3_ASSERT(strcmp (buf, expect) == 0);
@@ -711,8 +713,9 @@ void TestOverwriteMutator() {
711 CHECK(memcmp(b0.Data() + 30, b1.Data() + 30, 713 CHECK(memcmp(b0.Data() + 30, b1.Data() + 30,
712 Constants::BLOCK_SIZE - 30) == 0); 714 Constants::BLOCK_SIZE - 30) == 0);
713 715
716 xoff_t zero = 0;
714 cl1.clear(); 717 cl1.clear();
715 cl1.push_back(Change(Change::COPYOVER, 10, 20, (xoff_t)0)); 718 cl1.push_back(Change(Change::COPYOVER, 10, 20, zero));
716 spec0.ModifyTo(ChangeListMutator(cl1), &spec1); 719 spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
717 CHECK_EQ(spec0.Size(), spec1.Size()); 720 CHECK_EQ(spec0.Size(), spec1.Size());
718 721
@@ -828,7 +831,7 @@ void TestSmallStride() {
828 InMemoryEncodeDecode(spec0, spec1, &block, options); 831 InMemoryEncodeDecode(spec0, spec1, &block, options);
829 Delta delta(block); 832 Delta delta(block);
830 833
831 IF_DEBUG1(DP(RINT "[stride=%d] changes=%u adds=%"Q"u\n", 834 IF_DEBUG1(DP(RINT "[stride=%d] changes=%" W "u adds=%" Q "u\n",
832 s, changes, delta.AddedBytes())); 835 s, changes, delta.AddedBytes()));
833 double allowance = Constants::BLOCK_SIZE < 8192 || s < 30 ? 3.0 : 1.1; 836 double allowance = Constants::BLOCK_SIZE < 8192 || s < 30 ? 3.0 : 1.1;
834 CHECK_GE(allowance * changes, (double)delta.AddedBytes()); 837 CHECK_GE(allowance * changes, (double)delta.AddedBytes());
@@ -1274,7 +1277,7 @@ void UnitTest() {
1274// These are Xdelta tests. 1277// These are Xdelta tests.
1275template <class T> 1278template <class T>
1276void MainTest() { 1279void MainTest() {
1277 XPR(NT "Blocksize %"Q"u windowsize %"Z"u\n", 1280 XPR(NT "Blocksize %" Q "u windowsize %" Z "u\n",
1278 T::BLOCK_SIZE, T::WINDOW_SIZE); 1281 T::BLOCK_SIZE, T::WINDOW_SIZE);
1279 Regtest<T> regtest; 1282 Regtest<T> regtest;
1280 TEST(TestEmptyInMemory); 1283 TEST(TestEmptyInMemory);
diff --git a/xdelta3/testing/run_release.sh b/xdelta3/testing/run_release.sh
new file mode 100755
index 0000000..85ed1f7
--- /dev/null
+++ b/xdelta3/testing/run_release.sh
@@ -0,0 +1,2 @@
1#!/bin/sh
2(cd .. && ./run_release.sh)
diff --git a/xdelta3/testing/test.h b/xdelta3/testing/test.h
index 2bf81d5..628fb75 100644
--- a/xdelta3/testing/test.h
+++ b/xdelta3/testing/test.h
@@ -32,8 +32,8 @@ extern "C" {
32 32
33#define CHECK_OP(x,y,OP) \ 33#define CHECK_OP(x,y,OP) \
34 do { \ 34 do { \
35 typeof(x) _x(x); \ 35 __typeof__(x) _x(x); \
36 typeof(x) _y(y); \ 36 __typeof__(x) _y(y); \
37 if (!(_x OP _y)) { \ 37 if (!(_x OP _y)) { \
38 cerr << __FILE__ << ":" << __LINE__ << " Check failed: " << #x " " #OP " " #y << endl; \ 38 cerr << __FILE__ << ":" << __LINE__ << " Check failed: " << #x " " #OP " " #y << endl; \
39 cerr << __FILE__ << ":" << __LINE__ << " {0} " << _x << endl; \ 39 cerr << __FILE__ << ":" << __LINE__ << " {0} " << _x << endl; \
@@ -82,5 +82,3 @@ pair<T, U> make_pair(const T& t, const U& u) {
82 82
83using std::min; 83using std::min;
84using std::max; 84using std::max;
85
86