summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
Diffstat (limited to 'testing')
-rw-r--r--testing/Makefile8
-rw-r--r--testing/checksum_test.cc756
-rw-r--r--testing/checksum_test_c.c174
-rw-r--r--testing/delta.h38
-rw-r--r--testing/file.h51
-rw-r--r--testing/modify.h12
-rw-r--r--testing/random.h2
-rw-r--r--testing/regtest.cc573
-rwxr-xr-xtesting/run_release.sh2
-rw-r--r--testing/sizes.h19
-rw-r--r--testing/test.h10
11 files changed, 212 insertions, 1433 deletions
diff --git a/testing/Makefile b/testing/Makefile
deleted file mode 100644
index d0b9c9e..0000000
--- a/testing/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-all:
- (cd .. && make all)
-
-xdelta3regtest:
- (cd .. && make xdelta3regtest)
-
-xdelta3checksum:
- (cd .. && make xdelta3checksum)
diff --git a/testing/checksum_test.cc b/testing/checksum_test.cc
deleted file mode 100644
index 9418d24..0000000
--- a/testing/checksum_test.cc
+++ /dev/null
@@ -1,756 +0,0 @@
-/* Copyright (C) 2007 Josh MacDonald */
-
-#include "test.h"
-#include <assert.h>
-#include <list>
-#include <vector>
-#include <algorithm>
-
-#include "../cpp-btree/btree_map.h"
-
-extern "C" {
-uint32_t xd3_large32_cksum_old (xd3_hash_cfg *cfg, const uint8_t *base, const usize_t look);
-uint32_t xd3_large32_cksum_update_old (xd3_hash_cfg *cfg, uint32_t cksum,
- const uint8_t *base, const usize_t look);
-
-uint64_t xd3_large64_cksum_old (xd3_hash_cfg *cfg, const uint8_t *base, const usize_t look);
-uint64_t xd3_large64_cksum_update_old (xd3_hash_cfg *cfg, uint64_t cksum,
- const uint8_t *base, const usize_t look);
-}
-
-using btree::btree_map;
-using std::list;
-using std::vector;
-
-// MLCG parameters
-// a, a*
-uint32_t good_32bit_values[] = {
- 1597334677U, // ...
- 741103597U, 887987685U,
-};
-
-// a, a*
-uint64_t good_64bit_values[] = {
- 1181783497276652981ULL, 4292484099903637661ULL,
- 7664345821815920749ULL, // ...
-};
-
-void print_header() {
- static int hdr_cnt = 0;
- if (hdr_cnt++ % 20 == 0) {
- printf("%-32sConf\t\tCount\tUniq\tFull\tCover\tColls"
- "\tMB/s\tIters\t#Colls\n", "Name");
- }
-}
-
-struct true_type { };
-struct false_type { };
-
-template <typename Word>
-usize_t bitsof();
-
-template<>
-usize_t bitsof<unsigned int>() {
- return sizeof(unsigned int) * 8;
-}
-
-template<>
-usize_t bitsof<unsigned long>() {
- return sizeof(unsigned long) * 8;
-}
-
-template<>
-usize_t bitsof<unsigned long long>() {
- return sizeof(unsigned long long) * 8;
-}
-
-template <typename Word>
-struct hhash { // shift "s" bits leaving the high bits as a hash value for
- // this checksum, which are the most "distant" in terms of the
- // spectral test for the rabin_karp MLCG. For short windows,
- // the high bits aren't enough, XOR "mask" worth of these in.
- Word operator()(const Word t, const Word s, const Word mask) {
- return (t >> s) ^ (t & mask);
- }
-};
-
-template <typename Word>
-Word good_word();
-
-template<>
-uint32_t good_word<uint32_t>() {
- return good_32bit_values[0];
-}
-
-template<>
-uint64_t good_word<uint64_t>() {
- return good_64bit_values[0];
-}
-
-// CLASSES
-
-#define SELF Word, CksumSize, CksumSkip, Hash, Compaction
-#define MEMBER template <typename Word, \
- int CksumSize, \
- int CksumSkip, \
- typename Hash, \
- int Compaction>
-
-MEMBER
-struct cksum_params {
- typedef Word word_type;
- typedef Hash hash_type;
-
- static const int cksum_size = CksumSize;
- static const int cksum_skip = CksumSkip;
- static const int compaction = Compaction;
-};
-
-MEMBER
-struct rabin_karp : public cksum_params<SELF> {
- // (a^cksum_size-1 c_0) + (a^cksum_size-2 c_1) ...
- rabin_karp()
- : powers(make_powers()),
- product(powers[0] * good_word<Word>()),
- incr_state(0) { }
-
- static Word* make_powers() {
- Word *p = new Word[CksumSize];
- p[CksumSize - 1] = 1;
- for (int i = CksumSize - 2; i >= 0; i--) {
- p[i] = p[i + 1] * good_word<Word>();
- }
- return p;
- }
-
- ~rabin_karp() {
- delete [] powers;
- }
-
- Word step(const uint8_t *ptr) {
- Word h = 0;
- for (int i = 0; i < CksumSize; i++) {
- h += (ptr[i]) * powers[i];
- }
- return h;
- }
-
- Word state0(const uint8_t *ptr) {
- incr_state = step(ptr);
- return incr_state;
- }
-
- Word incr(const uint8_t *ptr) {
- incr_state = good_word<Word>() * incr_state -
- product * (ptr[-1]) + (ptr[CksumSize - 1]);
- return incr_state;
- }
-
- const Word *const powers;
- const Word product;
- Word incr_state;
-};
-
-MEMBER
-struct with_stream : public cksum_params<SELF> {
- xd3_stream stream;
-
- with_stream()
- {
- xd3_config cfg;
- memset (&stream, 0, sizeof (stream));
- xd3_init_config (&cfg, 0);
- cfg.smatch_cfg = XD3_SMATCH_SOFT;
- cfg.smatcher_soft.large_look = CksumSize;
- cfg.smatcher_soft.large_step = CksumSkip;
- cfg.smatcher_soft.small_look = 4;
- cfg.smatcher_soft.small_chain = 4;
- cfg.smatcher_soft.small_lchain = 4;
- cfg.smatcher_soft.max_lazy = 4;
- cfg.smatcher_soft.long_enough = 4;
- CHECK_EQ(0, xd3_config_stream (&stream, &cfg));
-
- CHECK_EQ(0, xd3_size_hashtable (&stream,
- 1<<10 /* ignored */,
- stream.smatcher.large_look,
- & stream.large_hash));
- }
- ~with_stream()
- {
- xd3_free_stream (&stream);
- }
-};
-
-MEMBER
-struct large_cksum : public with_stream<SELF> {
- Word step(const uint8_t *ptr) {
- return xd3_large_cksum (&this->stream.large_hash, ptr, CksumSize);
- }
-
- Word state0(const uint8_t *ptr) {
- incr_state = step(ptr);
- return incr_state;
- }
-
- Word incr(const uint8_t *ptr) {
- incr_state = xd3_large_cksum_update (&this->stream.large_hash,
- incr_state, ptr - 1, CksumSize);
- return incr_state;
- }
-
- Word incr_state;
-};
-
-#if SIZEOF_USIZE_T == 4
-#define xd3_large_cksum_old xd3_large32_cksum_old
-#define xd3_large_cksum_update_old xd3_large32_cksum_update_old
-#elif SIZEOF_USIZE_T == 8
-#define xd3_large_cksum_old xd3_large64_cksum_old
-#define xd3_large_cksum_update_old xd3_large64_cksum_update_old
-#endif
-
-MEMBER
-struct large_cksum_old : public with_stream<SELF> {
- Word step(const uint8_t *ptr) {
- return xd3_large_cksum_old (&this->stream.large_hash, ptr, CksumSize);
- }
-
- Word state0(const uint8_t *ptr) {
- incr_state = step(ptr);
- return incr_state;
- }
-
- Word incr(const uint8_t *ptr) {
- incr_state = xd3_large_cksum_update_old (&this->stream.large_hash,
- incr_state, ptr - 1, CksumSize);
- return incr_state;
- }
-
- Word incr_state;
-};
-
-// TESTS
-
-template <typename Word>
-struct file_stats {
- typedef const uint8_t* ptr_type;
- typedef Word word_type;
- typedef btree::btree_multimap<word_type, ptr_type> table_type;
- typedef typename table_type::iterator table_iterator;
-
- usize_t cksum_size;
- usize_t cksum_skip;
- usize_t unique;
- usize_t unique_values;
- usize_t count;
- table_type table;
-
- file_stats(usize_t size, usize_t skip)
- : cksum_size(size),
- cksum_skip(skip),
- unique(0),
- unique_values(0),
- count(0) {
- }
-
- void reset() {
- unique = 0;
- unique_values = 0;
- count = 0;
- table.clear();
- }
-
- void update(word_type word, ptr_type ptr) {
- table_iterator t_i = table.find(word);
-
- count++;
- if (t_i != table.end()) {
- int collisions = 0;
- for (table_iterator p_i = t_i;
- p_i != table.end() && p_i->first == word;
- ++p_i) {
- if (memcmp(p_i->second, ptr, cksum_size) == 0) {
- return;
- }
- collisions++;
- }
- if (collisions >= 1000) {
- fprintf(stderr, "Something is not right, lots of collisions=%d\n",
- collisions);
- abort();
- }
- } else {
- unique_values++;
- }
- unique++;
- table.insert(std::make_pair(word, ptr));
- return;
- }
-
- void freeze() {
- table.clear();
- }
-};
-
-struct test_result_base;
-
-static vector<test_result_base*> all_tests;
-
-struct test_result_base {
- virtual ~test_result_base() {
- }
- virtual void reset() = 0;
- virtual void print() = 0;
- virtual void get(const uint8_t* buf, const size_t buf_size,
- usize_t iters) = 0;
- virtual void stat() = 0;
- virtual usize_t count() = 0;
- virtual usize_t dups() = 0;
- virtual double uniqueness() = 0;
- virtual double fullness() = 0;
- virtual double collisions() = 0;
- virtual double coverage() = 0;
- virtual double compression() = 0;
- virtual double time() = 0;
- virtual double total_time() = 0;
- virtual usize_t total_count() = 0;
- virtual usize_t total_dups() = 0;
-};
-
-template <typename Checksum>
-struct test_result : public test_result_base {
- Checksum cksum;
- const char *test_name;
- file_stats<typename Checksum::word_type> fstats;
- usize_t test_size;
- usize_t n_steps;
- usize_t n_incrs;
- typename Checksum::word_type s_bits;
- typename Checksum::word_type s_mask;
- usize_t t_entries;
- usize_t h_bits;
- usize_t h_buckets_full;
- char *hash_table;
- long accum_millis;
- usize_t accum_iters;
-
- // These are not reset
- double accum_time;
- usize_t accum_count;
- usize_t accum_dups;
- usize_t accum_colls;
- size_t accum_size;
-
- test_result(const char *name)
- : test_name(name),
- fstats(Checksum::cksum_size, Checksum::cksum_skip),
- hash_table(NULL),
- accum_millis(0),
- accum_iters(0),
- accum_time(0.0),
- accum_count(0),
- accum_dups(0),
- accum_colls(0),
- accum_size(0) {
- all_tests.push_back(this);
- }
-
- ~test_result() {
- reset();
- }
-
- void reset() {
- // size of file
- test_size = 0;
-
- // count
- n_steps = 0;
- n_incrs = 0;
-
- // four values used by new_table()/summarize_table()
- s_bits = 0;
- s_mask = 0;
- t_entries = 0;
- h_bits = 0;
- h_buckets_full = 0;
-
- accum_millis = 0;
- accum_iters = 0;
-
- fstats.reset();
-
- // temporary
- if (hash_table) {
- delete(hash_table);
- hash_table = NULL;
- }
- }
-
- usize_t count() {
- if (Checksum::cksum_skip == 1) {
- return n_incrs;
- } else {
- return n_steps;
- }
- }
-
- usize_t dups() {
- return fstats.count - fstats.unique;
- }
-
- /* Fraction of distinct strings of length cksum_size which are not
- * represented in the hash table. */
- double collisions() {
- return (fstats.unique - fstats.unique_values) / (double) fstats.unique;
- }
- usize_t colls() {
- return (fstats.unique - fstats.unique_values);
- }
-
- double uniqueness() {
- return 1.0 - (double) dups() / count();
- }
-
- double fullness() {
- return (double) h_buckets_full / (1 << h_bits);
- }
-
- double coverage() {
- return (double) h_buckets_full / uniqueness() / count();
- }
-
- double compression() {
- return 1.0 - coverage();
- }
-
- double time() {
- return (double) accum_millis / accum_iters;
- }
-
- double total_time() {
- return accum_time;
- }
-
- usize_t total_count() {
- return accum_count;
- }
-
- usize_t total_dups() {
- return accum_dups;
- }
-
- usize_t total_colls() {
- return accum_dups;
- }
-
- void stat() {
- accum_time += time();
- accum_count += count();
- accum_dups += dups();
- accum_colls += colls();
- accum_size += test_size;
- }
-
- void print() {
- if (fstats.count != count()) {
- fprintf(stderr, "internal error: %" W "d != %" W "d\n", fstats.count, count());
- abort();
- }
- print_header();
- printf("%-32s%d/%d 2^%" W "u\t%" W "u\t%0.4f\t%.4f\t%.4f\t%.1e\t%.2f\t"
- "%" W "u\t%" W "u\n",
- test_name,
- Checksum::cksum_size,
- Checksum::cksum_skip,
- h_bits,
- count(),
- uniqueness(),
- fullness(),
- coverage(),
- collisions(),
- 0.001 * accum_iters * test_size / accum_millis,
- accum_iters,
- colls());
- }
-
- usize_t size_log2 (usize_t slots) {
- usize_t bits = bitsof<typename Checksum::word_type>() - 1;
- usize_t i;
-
- for (i = 3; i <= bits; i += 1) {
- if (slots <= (1U << i)) {
- return i - Checksum::compaction;
- }
- }
-
- return bits;
- }
-
- void new_table(usize_t entries) {
- t_entries = entries;
- h_bits = size_log2(entries);
-
- usize_t n = 1 << h_bits;
-
- s_bits = bitsof<typename Checksum::word_type>() - h_bits;
- s_mask = n - 1U;
-
- hash_table = new char[n / 8];
- memset(hash_table, 0, n / 8);
- }
-
- int get_table_bit(usize_t i) {
- return hash_table[i/8] & (1 << i%8);
- }
-
- int set_table_bit(usize_t i) {
- return hash_table[i/8] |= (1 << i%8);
- }
-
- void summarize_table() {
- usize_t n = 1 << h_bits;
- usize_t f = 0;
- for (usize_t i = 0; i < n; i++) {
- if (get_table_bit(i)) {
- f++;
- }
- }
- h_buckets_full = f;
- }
-
- void get(const uint8_t* buf, const size_t buf_size, usize_t test_iters) {
- typename Checksum::hash_type hash;
- const uint8_t *ptr;
- const uint8_t *end;
- usize_t periods;
- int64_t last_offset;
- int64_t stop;
-
- test_size = buf_size;
- last_offset = buf_size - Checksum::cksum_size;
-
- if (last_offset < 0) {
- periods = 0;
- n_steps = 0;
- n_incrs = 0;
- stop = -Checksum::cksum_size;
- } else {
- periods = last_offset / Checksum::cksum_skip;
- n_steps = periods + 1;
- n_incrs = last_offset + 1;
- stop = last_offset - (periods + 1) * Checksum::cksum_skip;
- }
-
- // Compute file stats once.
- if (fstats.unique_values == 0) {
- if (Checksum::cksum_skip == 1) {
- for (size_t i = 0; i <= buf_size - Checksum::cksum_size; i++) {
- fstats.update(hash(cksum.step(buf + i), s_bits, s_mask), buf + i);
- }
- } else {
- ptr = buf + last_offset;
- end = buf + stop;
-
- for (; ptr != end; ptr -= Checksum::cksum_skip) {
- fstats.update(hash(cksum.step(ptr), s_bits, s_mask), ptr);
- }
- }
- fstats.freeze();
- }
-
- long start_test = get_millisecs_now();
-
- if (Checksum::cksum_skip != 1) {
- new_table(n_steps);
-
- for (usize_t i = 0; i < test_iters; i++) {
- ptr = buf + last_offset;
- end = buf + stop;
-
- for (; ptr != end; ptr -= Checksum::cksum_skip) {
- set_table_bit(hash(cksum.step(ptr), s_bits, s_mask));
- }
- }
-
- summarize_table();
- }
-
- stop = buf_size - Checksum::cksum_size + 1;
- if (stop < 0) {
- stop = 0;
- }
-
- if (Checksum::cksum_skip == 1) {
- new_table(n_incrs);
-
- for (usize_t i = 0; i < test_iters; i++) {
- ptr = buf;
- end = buf + stop;
-
- if (ptr != end) {
- set_table_bit(hash(cksum.state0(ptr++), s_bits, s_mask));
- }
-
- for (; ptr != end; ptr++) {
- typename Checksum::word_type w = cksum.incr(ptr);
- CHECK_EQ(w, cksum.step(ptr));
- set_table_bit(hash(w, s_bits, s_mask));
- }
- }
-
- summarize_table();
- }
-
- accum_iters += test_iters;
- accum_millis += get_millisecs_now() - start_test;
- }
-};
-
-static int read_whole_file(const char *name,
- uint8_t **buf_ptr,
- size_t *buf_len) {
- main_file file;
- int ret;
- xoff_t len;
- size_t nread;
- main_file_init(&file);
- file.filename = name;
- ret = main_file_open(&file, name, XO_READ);
- if (ret != 0) {
- fprintf(stderr, "open failed\n");
- goto exit;
- }
- ret = main_file_stat(&file, &len);
- if (ret != 0) {
- fprintf(stderr, "stat failed\n");
- goto exit;
- }
-
- (*buf_len) = (size_t)len;
- (*buf_ptr) = (uint8_t*) main_malloc(*buf_len);
- ret = main_file_read(&file, *buf_ptr, *buf_len, &nread,
- "read failed");
- if (ret == 0 && *buf_len == nread) {
- ret = 0;
- } else {
- fprintf(stderr, "invalid read\n");
- ret = XD3_INTERNAL;
- }
- exit:
- main_file_cleanup(&file);
- return ret;
-}
-
-int main(int argc, char** argv) {
- int i;
- uint8_t *buf = NULL;
- size_t buf_len = 0;
- int ret;
-
- if (argc <= 1) {
- fprintf(stderr, "usage: %s file ...\n", argv[0]);
- return 1;
- }
-
-// TODO: The xdelta3-hash.h code is identical now; add sameness test.
-// using rabin_karp<> template.
-#define TEST(T,Z,S,C) \
- test_result<large_cksum<T,Z,S,hhash<T>,C>> \
- _xck_ ## T ## _ ## Z ## _ ## S ## _ ## C \
- ("xck_" #T "_" #Z "_" #S "_" #C); \
- test_result<large_cksum_old<T,Z,S,hhash<T>,C>> \
- _old_ ## T ## _ ## Z ## _ ## S ## _ ## C \
- ("old_" #T "_" #Z "_" #S "_" #C)
-
-#define TESTS(SIZE, SKIP) \
- TEST(usize_t, SIZE, SKIP, 1); \
- TEST(usize_t, SIZE, SKIP, 2)
-
- TESTS(5, 1);
- TESTS(6, 1);
- TESTS(7, 1);
- TESTS(8, 1);
- TESTS(9, 1);
- TESTS(10, 1);
- TESTS(11, 1);
- TESTS(12, 1);
- TESTS(13, 1);
- TESTS(14, 1);
- TESTS(15, 1);
- TESTS(16, 1);
- TESTS(17, 1);
- TESTS(18, 1);
- TESTS(19, 1);
- TESTS(20, 1);
- TESTS(21, 1);
- TESTS(22, 1);
- TESTS(23, 1);
- TESTS(24, 1);
- TESTS(25, 1);
- TESTS(26, 1);
- TESTS(27, 1);
- TESTS(28, 1);
- TESTS(29, 1);
- TESTS(30, 1);
- TESTS(31, 1);
- TESTS(32, 1);
- TESTS(33, 1);
- TESTS(34, 1);
- TESTS(35, 1);
- TESTS(36, 1);
- TESTS(37, 1);
- TESTS(38, 1);
- TESTS(39, 1);
-
-
- for (i = 1; i < argc; i++) {
- if ((ret = read_whole_file(argv[i],
- & buf,
- & buf_len))) {
- return 1;
- }
-
- fprintf(stderr, "file %s is %zu bytes\n",
- argv[i], buf_len);
-
- double min_time = -1.0;
- double min_compression = 0.0;
-
- for (vector<test_result_base*>::iterator iter = all_tests.begin();
- iter != all_tests.end(); ++iter) {
- test_result_base *test = *iter;
- test->reset();
-
- usize_t iters = 1;
- long start_test = get_millisecs_now();
-
- do {
- test->get(buf, buf_len, iters);
- iters *= 3;
- iters /= 2;
- } while (get_millisecs_now() - start_test < 2000);
-
- test->stat();
-
- if (min_time < 0.0) {
- min_compression = test->compression();
- min_time = test->time();
- }
-
- if (min_time > test->time()) {
- min_time = test->time();
- }
-
- if (min_compression > test->compression()) {
- min_compression = test->compression();
- }
-
- test->print();
- }
-
- main_free(buf);
- buf = NULL;
- }
-
- return 0;
-}
diff --git a/testing/checksum_test_c.c b/testing/checksum_test_c.c
deleted file mode 100644
index 8f0507a..0000000
--- a/testing/checksum_test_c.c
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "../xdelta3.c"
-
-// OLD CHECKSUM CODE
-
-#define PERMUTE32(x) (__single_hash32[x])
-#define PERMUTE64(x) (__single_hash64[x])
-
-const uint16_t __single_hash32[256] =
-{
- /* This hashes the input alphabet (Scheme SLIB pseudo-random). */
- 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46,
- 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602,
- 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6,
- 0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a,
- 0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58,
- 0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b,
- 0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94,
- 0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176,
- 0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743,
- 0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6,
- 0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227,
- 0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d,
- 0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a,
- 0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31,
- 0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9,
- 0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6,
- 0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f,
- 0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f,
- 0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49,
- 0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037,
- 0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad,
- 0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f,
- 0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d,
- 0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b,
- 0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624,
- 0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272,
- 0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806,
- 0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050,
- 0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113,
- 0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2,
- 0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25,
- 0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5
-};
-
-const uint32_t __single_hash64[256] =
-{
- /* http://random.org 2014.10.24 */
- 0xd25e9f0a, 0xb1af9d5e, 0xb753dfa2, 0x157050f7, /* 0 */
- 0xc84b072c, 0xdd14fe7c, 0xf92208c3, 0xdf08a0c0,
- 0x63a5c118, 0x76f5d90f, 0xa2f8b93e, 0xb6c12d22,
- 0xaf074957, 0x966fb7d9, 0x62f7b785, 0xb40e8a09,
- 0x0a811d5d, 0x323a6daa, 0xb62f7c5b, 0xfdcb9a53,
- 0xf25a9067, 0x4506bc7a, 0xff58a74b, 0x5ae62817,
- 0x74097675, 0x722c0fd9, 0x116a2a66, 0x65f76728,
- 0x72c79651, 0xe043cf9d, 0x64b867c7, 0x6604834f,
- 0xcdca58a6, 0x0f164e2d, 0x24515f05, 0x632cdbf8,
- 0x18091d4a, 0x3eff4128, 0x673d1c33, 0xd8e10c71,
- 0x1a3edf11, 0xba52892f, 0xa56949e0, 0xf3e1dd77, /* 10 */
- 0x86fcbe3e, 0x138d66d0, 0x4fc98359, 0xc22e5dd6,
- 0xc59f2267, 0x6c6dd739, 0xe03da190, 0x07e8469c,
- 0xadcfb02c, 0x00d3b0d9, 0xa1f44918, 0x8bd84d87,
- 0x08ec9ec1, 0xbbcd156f, 0xb57718e3, 0x3177e752,
- 0xf52a4d70, 0xde7aaad9, 0x075f1da0, 0x21ba00c6,
- 0xb9469a5c, 0xcf08d5ba, 0x91ac9edc, 0xc6167b63,
- 0xc1974919, 0xc8c8d195, 0x4b1996dd, 0xeff8991c,
- 0xf7f66c6b, 0x25b012e2, 0x59d12a98, 0xea40d3cc,
- 0x41f9970b, 0xec48101a, 0xa3bdcf90, 0x99f16905,
- 0x27af6c97, 0xc849af37, 0x49cad89b, 0xf48c2278, /* 20 */
- 0x5529c3d8, 0x9e7d6dce, 0x16feb52d, 0xf1b0aca1,
- 0xaf28fccb, 0x48e4ce3c, 0xc4436617, 0x64524e3e,
- 0x61806681, 0x6384f2d7, 0x1172880f, 0x34a5ef5f,
- 0xcc8cc0a8, 0x66e8f100, 0x2866085f, 0xba9b1b2d,
- 0x51285949, 0x2be4b574, 0x889b1ef5, 0x3dbe920d,
- 0x9277a62f, 0x0584a9f6, 0x085d8fc4, 0x4b5d403d,
- 0x4e46ca78, 0x3294c2f9, 0x29313e70, 0xe4f09b24,
- 0xe73b331c, 0x072f5552, 0x2e390b78, 0xea0021ca,
- 0xd8f40320, 0xed0e16fd, 0x7de9cf7a, 0xf17e3d6c,
- 0x8df1bd85, 0x052cae67, 0x3486e512, 0x3a1c09b8, /* 30 */
- 0x6c2a7b4e, 0x83455753, 0xbc0353ac, 0x0ffe20b6,
- 0x5fdcef85, 0x010f506c, 0x595ce972, 0xe28680d0,
- 0xa7e216b2, 0xa392ee0f, 0x25b73faa, 0x2b1f4983,
- 0xeeaefe98, 0x1d3d9cbc, 0x6aebe97b, 0x8b7b3584,
- 0x9e6a9a07, 0xd37f1e99, 0x4ac2a441, 0x8ae9a213,
- 0x7d0e27d7, 0x5de54b9a, 0x8621de1f, 0xf0f2f866,
- 0xcb08d275, 0x49c3f87e, 0xd5ee68c1, 0x9802fc77,
- 0x68be6c5e, 0x65aa8c27, 0xf423d5f7, 0x10ec5502,
- 0x9909bce1, 0x509cdf1b, 0x338fea72, 0x2733e9bf,
- 0xf92f4fd7, 0x87738ea2, 0x931a8bbc, 0x0a5c9155, /* 40 */
- 0xbe5edd9b, 0xadbf5838, 0x0338f8d2, 0x290da210,
- 0x390c37d8, 0xe7cffae8, 0x20617ebe, 0x464322dd,
- 0x7b3c4e78, 0xac142dcb, 0x2d5cef76, 0xd8fe49fc,
- 0x60f4e9a9, 0x7473816f, 0x0dc35f39, 0x5eed80c1,
- 0x0cb55ab6, 0x1d3ac541, 0x13c7f529, 0x7bffdf4a,
- 0xe334785b, 0x85263ec1, 0xd132ae56, 0x7c868b9e,
- 0x47f60638, 0x1012b979, 0x81c31dd3, 0x1af868c8,
- 0x0c5d0742, 0xd1b3e1a2, 0x5873200a, 0xf848465c,
- 0x0fc4d596, 0x609c18af, 0xc9f5a480, 0xd1a94a84,
- 0xa1431a3f, 0x7de8bb1a, 0x25f1256b, 0x1dcc732c, /* 50 */
- 0x6aa1549a, 0xa2367281, 0x32f2a77e, 0x82e62a0f,
- 0x045cbb56, 0x74b2027c, 0xd71a32d9, 0x022e7cb5,
- 0xe99be177, 0x60222fdf, 0xd69681ca, 0x9008ee2c,
- 0x32923db4, 0xcf82bf97, 0x38960a5b, 0xb3503d5b,
- 0x9bd4c7f2, 0x33c029c8, 0x1ef504a3, 0xdb249d3b,
- 0x91e89676, 0x4ca43b36, 0x9191433c, 0x465d5dc4,
- 0xf4dcb118, 0x9d11dd00, 0xb592f058, 0xdbe5ce30,
- 0x74790d92, 0x779850a8, 0x7180d25b, 0xfa951d99,
- 0x5990935a, 0x921cb022, 0x3b7c39bc, 0x6a38a7c7,
- 0xdc22703b, 0x142bab3b, 0x4e3d9479, 0x44bb8482, /* 60 */
- 0x8043abce, 0xfebe832a, 0x8e6a2f98, 0x4d43c4fe,
- 0xd192a70a, 0x802f3c3a, 0x5d11bbab, 0x2665d241,
- 0xb3f3a680, 0x3a8d223f, 0xcf82cdb4, 0x4ed28743,
-};
-
-uint64_t
-xd3_large64_cksum_old (xd3_hash_cfg *ignore, const uint8_t *base, const usize_t look)
-{
- static const uint64_t kBits = 32;
- static const uint64_t kMask = 0xffffffff;
- usize_t i = 0;
- uint64_t low = 0;
- uint64_t high = 0;
-
- for (; i < look; i += 1)
- {
- low += PERMUTE64(*base++);
- high += low;
- }
-
- return ((high & kMask) << kBits) | (low & kMask);
-}
-
-uint64_t
-xd3_large64_cksum_update_old (xd3_hash_cfg *ignore, const uint64_t cksum,
- const uint8_t *base, const usize_t look)
-{
- static const uint64_t kBits = 32;
- static const uint64_t kMask = 0xffffffff;
- uint64_t old_c = PERMUTE64(base[0]);
- uint64_t new_c = PERMUTE64(base[look]);
- uint64_t low = ((cksum & kMask) - old_c + new_c) & kMask;
- uint64_t high = ((cksum >> kBits) - (old_c * look) + low) & kMask;
- return (high << kBits) | low;
-}
-
-uint32_t
-xd3_large32_cksum_old (xd3_hash_cfg *ignore, const uint8_t *base, const usize_t look)
-{
- static const uint32_t kBits = 16;
- static const uint32_t kMask = 0xffff;
- usize_t i = 0;
- uint32_t low = 0;
- uint32_t high = 0;
-
- for (; i < look; i += 1)
- {
- low += PERMUTE32(*base++);
- high += low;
- }
-
- return ((high & kMask) << kBits) | (low & kMask);
-}
-
-uint32_t
-xd3_large32_cksum_update_old (xd3_hash_cfg *ignore, const uint32_t cksum,
- const uint8_t *base, const usize_t look)
-{
- static const uint32_t kBits = 16;
- static const uint32_t kMask = 0xffff;
- uint32_t old_c = PERMUTE32(base[0]);
- uint32_t new_c = PERMUTE32(base[look]);
- uint32_t low = ((cksum & kMask) - old_c + new_c) & kMask;
- uint32_t high = ((cksum >> kBits) - (old_c * look) + low) & kMask;
- return (high << kBits) | low;
-}
diff --git a/testing/delta.h b/testing/delta.h
index deac217..b0cca7c 100644
--- a/testing/delta.h
+++ b/testing/delta.h
@@ -30,7 +30,7 @@ public:
case XD3_WINFINISH:
break;
default:
- cerr << "decode: " << done;
+ DP(RINT "error code %s\n", xd3_strerror (ret));
abort();
}
}
@@ -48,25 +48,23 @@ public:
return stream_.whole_target.wininfolen;
}
-// Note: This does not benefit from -Wformat= checking, due to the
-// enclosing template. Further, it was not used.
-// void Print() const {
-// for (size_t i = 0; i < stream_.whole_target.instlen; i++) {
-// xd3_winst &winst = stream_.whole_target.inst[i];
-// switch (winst.type) {
-// case XD3_RUN:
-// DP(RINT, "%" Q "u run %" W "u\n", winst.position, winst.size);
-// break;
-// case XD3_ADD:
-// DP(RINT "%" Q "u add %" W "u\n", winst.position, winst.size);
-// break;
-// default:
-// DP(RINT "%" Q "u copy %" W "u @ %" Q "u (mode %u)\n",
-// winst.position, winst.size, winst.addr, winst.mode);
-// break;
-// }
-// }
-// }
+ void Print() const {
+ for (size_t i = 0; i < stream_.whole_target.instlen; i++) {
+ xd3_winst &winst = stream_.whole_target.inst[i];
+ switch (winst.type) {
+ case XD3_RUN:
+ DP(RINT "%"Q"u run %u\n", winst.position, winst.size);
+ break;
+ case XD3_ADD:
+ DP(RINT "%"Q"u add %u\n", winst.position, winst.size);
+ break;
+ default:
+ DP(RINT "%"Q"u copy %u @ %"Q"u (mode %u)\n",
+ winst.position, winst.size, winst.addr, winst.mode);
+ break;
+ }
+ }
+ }
private:
xd3_stream stream_;
diff --git a/testing/file.h b/testing/file.h
index 2188f7a..a204d74 100644
--- a/testing/file.h
+++ b/testing/file.h
@@ -50,7 +50,7 @@ public:
}
data_ = new uint8_t[data_size_];
memcpy(data_, tmp, size_);
- delete [] tmp;
+ delete tmp;
}
memcpy(data_ + size_, data, size);
@@ -62,43 +62,36 @@ public:
size_ = 0;
}
- // Note: This does not benefit from -Wformat= checking, due to the
- // enclosing template. Further, it was not used.
- // void Print() const {
- // xoff_t pos = 0;
- // for (size_t i = 0; i < Size(); i++) {
- // if (pos % 16 == 0) {
- // DP(RINT "%5" Q "x: ", pos);
- // }
- // DP(RINT "%02x ", (*this)[i]);
- // if (pos % 16 == 15) {
- // DP(RINT "\n");
- // }
- // pos++;
- // }
- // DP(RINT "\n");
- // }
+ void Print() const {
+ xoff_t pos = 0;
+ for (size_t i = 0; i < Size(); i++) {
+ if (pos % 16 == 0) {
+ DP(RINT "%5"Q"x: ", pos);
+ }
+ DP(RINT "%02x ", (*this)[i]);
+ if (pos % 16 == 15) {
+ DP(RINT "\n");
+ }
+ pos++;
+ }
+ DP(RINT "\n");
+ }
void WriteTmpFile(TmpFile *f) const {
f->Append(this);
}
void SetSize(size_t size) {
- uint8_t *t = NULL;
+ size_ = size;
+
if (data_size_ < size) {
if (data_) {
- t = data_;
+ delete [] data_;
}
data_ = new uint8_t[size];
data_size_ = size;
}
- if (t && size < size_) {
- memcpy(data_, t, size);
- }
- delete [] t;
- size_ = size;
}
-
private:
friend class BlockIterator;
@@ -275,7 +268,6 @@ public:
}
void SetBlock(xoff_t blkno) {
- CHECK_LE(blkno, Blocks());
blkno_ = blkno;
}
@@ -313,10 +305,8 @@ class ExtFile {
public:
ExtFile() {
static int static_counter = 0;
- pid_t pid = getpid();
- char buf[64];
- xoff_t xpid = pid;
- snprintf(buf, 64, "/tmp/regtest.%" Q "u.%d", xpid, static_counter++);
+ char buf[32];
+ snprintf(buf, 32, "/tmp/regtest.%d", static_counter++);
filename_.append(buf);
unlink(filename_.c_str());
}
@@ -383,3 +373,4 @@ public:
private:
mutable main_file file_;
};
+
diff --git a/testing/modify.h b/testing/modify.h
index 93f7bde..5c2e316 100644
--- a/testing/modify.h
+++ b/testing/modify.h
@@ -12,12 +12,12 @@ public:
enum Kind {
MODIFY = 1, // Mutate a certain range w/ random or supplied data
ADD = 2, // Insert random or supplied data
- DELRANGE = 3, // Delete a specified range of data
+ DELETE = 3, // Delete a specified range of data
COPY = 4, // Copy from one region, inserting elsewhere
MOVE = 5, // Copy then delete copied-from range
- COPYOVER = 6 // Copy then delete copied-to range
+ COPYOVER = 6 // Copy then delete copied-to range
- // ADD, DELRANGE, and COPY change the file size
+ // ADD, DELETE, and COPY change the file size
// MODIFY, MOVE, COPYOVER preserve the file size
};
@@ -97,7 +97,7 @@ public:
case Change::MODIFY:
ModifyChange(ch, table, source_table, rand);
break;
- case Change::DELRANGE:
+ case Change::DELETE:
DeleteChange(ch, table, source_table, rand);
break;
case Change::COPY:
@@ -269,7 +269,7 @@ public:
SegmentMap tmp;
CHECK_NE(ch.addr1, ch.addr2);
CopyChange(ch, &tmp, source_table, rand);
- Change d(Change::DELRANGE, ch.size,
+ Change d(Change::DELETE, ch.size,
ch.addr1 < ch.addr2 ? ch.addr1 : ch.addr1 + ch.size);
DeleteChange(d, table, &tmp, rand);
}
@@ -282,7 +282,7 @@ public:
SegmentMap tmp;
CHECK_NE(ch.addr1, ch.addr2);
CopyChange(ch, &tmp, source_table, rand);
- Change d(Change::DELRANGE, ch.size, ch.addr2 + ch.size);
+ Change d(Change::DELETE, ch.size, ch.addr2 + ch.size);
DeleteChange(d, table, &tmp, rand);
}
diff --git a/testing/random.h b/testing/random.h
index 8ff64db..d1a6840 100644
--- a/testing/random.h
+++ b/testing/random.h
@@ -21,7 +21,7 @@ class MTRandom {
Init(TEST_SEED1);
}
- explicit MTRandom(uint32_t seed) {
+ MTRandom(uint32_t seed) {
Init(seed);
}
diff --git a/testing/regtest.cc b/testing/regtest.cc
index dd2ab8d..8219cc0 100644
--- a/testing/regtest.cc
+++ b/testing/regtest.cc
@@ -9,20 +9,12 @@ public:
typedef typename Constants::Sizes Sizes;
struct Options {
- Options()
- : encode_srcwin_maxsz(1<<20),
- block_size(Constants::BLOCK_SIZE),
- window_size(Constants::WINDOW_SIZE),
- size_known(false),
- iopt_size(XD3_DEFAULT_IOPT_SIZE),
- smatch_cfg(XD3_SMATCH_DEFAULT) { }
-
- xoff_t encode_srcwin_maxsz;
+ Options() : encode_srcwin_maxsz(1<<20),
+ block_size(Constants::BLOCK_SIZE),
+ size_known(false) { }
+ uint64_t encode_srcwin_maxsz;
size_t block_size;
- xoff_t window_size;
bool size_known;
- usize_t iopt_size;
- xd3_smatch_cfg smatch_cfg;
};
#include "segment.h"
@@ -34,7 +26,7 @@ public:
void InMemoryEncodeDecode(const FileSpec &source_file,
const FileSpec &target_file,
Block *coded_data,
- const Options &options) {
+ const Options &options = Options()) {
xd3_stream encode_stream;
xd3_config encode_config;
xd3_source encode_source;
@@ -58,9 +50,17 @@ public:
xd3_init_config(&encode_config, XD3_ADLER32);
xd3_init_config(&decode_config, XD3_ADLER32);
- encode_config.winsize = options.window_size;
- encode_config.iopt_size = options.iopt_size;
- encode_config.smatch_cfg = options.smatch_cfg;
+ encode_config.winsize = Constants::WINDOW_SIZE;
+
+ // TODO! the smatcher setup isn't working,
+ // if (options.large_cksum_step) {
+ // encode_config.smatch_cfg = XD3_SMATCH_SOFT;
+ // encode_config.smatcher_soft.large_step = options.large_cksum_step;
+ // }
+ // if (options.large_cksum_size) {
+ // encode_config.smatch_cfg = XD3_SMATCH_SOFT;
+ // encode_config.smatcher_soft.large_look = options.large_cksum_size;
+ // }
CHECK_EQ(0, xd3_config_stream (&encode_stream, &encode_config));
CHECK_EQ(0, xd3_config_stream (&decode_stream, &decode_config));
@@ -71,45 +71,42 @@ public:
encode_source.max_winsize = options.encode_srcwin_maxsz;
decode_source.max_winsize = options.encode_srcwin_maxsz;
- if (!options.size_known)
+ if (!options.size_known)
{
xd3_set_source (&encode_stream, &encode_source);
xd3_set_source (&decode_stream, &decode_source);
}
- else
+ else
{
- xd3_set_source_and_size (&encode_stream, &encode_source,
+ xd3_set_source_and_size (&encode_stream, &encode_source,
source_file.Size());
xd3_set_source_and_size (&decode_stream, &decode_source,
source_file.Size());
}
BlockIterator source_iterator(source_file, options.block_size);
- BlockIterator target_iterator(target_file, Constants::WINDOW_SIZE);
+ BlockIterator target_iterator(target_file, Constants::READ_SIZE);
Block encode_source_block, decode_source_block;
Block decoded_block, target_block;
bool encoding = true;
bool done = false;
bool done_after_input = false;
- IF_DEBUG1 (XPR(NTR "source %" Q "u[%" Z "u] target %" Q "u winsize %" Z "u\n",
- source_file.Size(), options.block_size,
- target_file.Size(),
- Constants::WINDOW_SIZE));
+ IF_DEBUG1 (XPR(NTR "source %"Q"u[%"Q"u] target %"Q"u[%lu] winsize %lu\n",
+ source_file.Size(), options.block_size,
+ target_file.Size(), Constants::READ_SIZE,
+ Constants::WINDOW_SIZE));
while (!done) {
target_iterator.Get(&target_block);
xoff_t blks = target_iterator.Blocks();
- IF_DEBUG2(XPR(NTR "target in %s: %" Q "u[%" Z "u] %" Q "u(%" Q "u) "
- "verified %" Q "u\n",
- encoding ? "encoding" : "decoding",
- target_iterator.Offset(),
- target_block.Size(),
- target_iterator.Blkno(),
- blks,
- verified_bytes));
+ IF_DEBUG2(XPR(NTR "target in %s: %llu..%llu %"Q"u(%"Q"u) verified %"Q"u\n",
+ encoding ? "encoding" : "decoding",
+ target_iterator.Offset(),
+ target_iterator.Offset() + target_block.Size(),
+ target_iterator.Blkno(), blks, verified_bytes));
if (blks == 0 || target_iterator.Blkno() == (blks - 1)) {
xd3_set_flags(&encode_stream, XD3_FLUSH | encode_stream.flags);
@@ -155,11 +152,11 @@ public:
xd3_source *src = (encoding ? &encode_source : &decode_source);
Block *block = (encoding ? &encode_source_block : &decode_source_block);
if (encoding) {
- IF_DEBUG2(XPR(NTR "[srcblock] %" Q "u last srcpos %" Q "u "
- "encodepos %" Q "u\n",
- encode_source.getblkno,
- encode_stream.match_last_srcpos,
- encode_stream.input_position + encode_stream.total_in));
+ IF_DEBUG1(XPR(NTR "[srcblock] %"Q"u last srcpos %"Q"u "
+ "encodepos %"Q"u\n",
+ encode_source.getblkno,
+ encode_stream.match_last_srcpos,
+ encode_stream.input_position + encode_stream.total_in));
}
source_iterator.SetBlock(src->getblkno);
@@ -232,10 +229,10 @@ public:
ExtFile *coded_data,
const Options &options) {
vector<const char*> ecmd;
- char bbuf[16];
- snprintf(bbuf, sizeof(bbuf), "-B%" Q "u", options.encode_srcwin_maxsz);
+ char buf[16];
+ snprintf(buf, sizeof(buf), "-B%"Q"u", options.encode_srcwin_maxsz);
ecmd.push_back("xdelta3");
- ecmd.push_back(bbuf);
+ ecmd.push_back(buf);
ecmd.push_back("-s");
ecmd.push_back(source_file.Name());
ecmd.push_back(target_file.Name());
@@ -248,7 +245,7 @@ public:
vector<const char*> dcmd;
ExtFile recon_file;
dcmd.push_back("xdelta3");
- ecmd.push_back(bbuf);
+ ecmd.push_back(buf);
dcmd.push_back("-d");
dcmd.push_back("-s");
dcmd.push_back(source_file.Name());
@@ -259,146 +256,32 @@ public:
CHECK_EQ(0, xd3_main_cmdline(dcmd.size() - 1,
const_cast<char**>(&dcmd[0])));
- CHECK_EQ(0, test_compare_files(recon_file.Name(),
+ CHECK_EQ(0, test_compare_files(recon_file.Name(),
target_file.Name()));
}
- // Similar to xd3_process_memory, with support for test Options.
- // Exercises xd3_process_stream.
- int TestProcessMemory (int is_encode,
- int (*func) (xd3_stream *),
- const uint8_t *input,
- usize_t input_size,
- const uint8_t *source,
- usize_t source_size,
- uint8_t *output,
- usize_t *output_size,
- usize_t output_size_max,
- const Options &options) {
- xd3_stream stream;
- xd3_config config;
- xd3_source src;
- int ret;
-
- memset (& stream, 0, sizeof (stream));
- memset (& config, 0, sizeof (config));
-
- if (is_encode)
- {
- config.winsize = input_size;
- config.iopt_size = options.iopt_size;
- config.sprevsz = xd3_pow2_roundup (config.winsize);
- }
-
- if ((ret = xd3_config_stream (&stream, &config)) != 0)
- {
- goto exit;
- }
-
- if (source != NULL)
- {
- memset (& src, 0, sizeof (src));
-
- src.blksize = source_size;
- src.onblk = source_size;
- src.curblk = source;
- src.curblkno = 0;
- src.max_winsize = source_size;
-
- if ((ret = xd3_set_source_and_size (&stream, &src, source_size)) != 0)
- {
- goto exit;
- }
- }
-
- if ((ret = xd3_process_stream (is_encode,
- & stream,
- func, 1,
- input, input_size,
- output,
- output_size,
- output_size_max)) != 0)
- {
- goto exit;
- }
-
- exit:
- if (ret != 0)
- {
- IF_DEBUG2 (DP(RINT "test_process_memory: %d: %s\n", ret, stream.msg));
- }
- xd3_free_stream(&stream);
- return ret;
- }
-
- void EncodeDecodeAPI(const FileSpec &spec0, const FileSpec &spec1,
- Block *delta, const Options &options) {
- Block from;
- Block to;
- spec0.Get(&from, 0, spec0.Size());
- spec1.Get(&to, 0, spec1.Size());
-
- delta->SetSize(to.Size() * 1.5);
- usize_t out_size;
- int enc_ret = TestProcessMemory(true,
- &xd3_encode_input,
- to.Data(),
- to.Size(),
- from.Data(),
- from.Size(),
- delta->Data(),
- &out_size,
- delta->Size(),
- options);
- CHECK_EQ(0, enc_ret);
- delta->SetSize(out_size);
-
- Block recon;
- recon.SetSize(to.Size());
- usize_t recon_size;
- int dec_ret = xd3_decode_memory(delta->Data(),
- delta->Size(),
- from.Data(),
- from.Size(),
- recon.Data(),
- &recon_size,
- recon.Size(),
- 0);
- CHECK_EQ(0, dec_ret);
- CHECK_EQ(0, CmpDifferentBlockBytes(to, recon));
- }
+ //////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////
+ void TestRandomNumbers() {
+ MTRandom rand;
+ int rounds = 1<<20;
+ uint64_t usum = 0;
+ uint64_t esum = 0;
-void TestPrintf() {
- char buf[64];
- xoff_t x = XOFF_T_MAX;
- snprintf_func (buf, sizeof(buf), "%" Q "u", x);
- const char *expect = XD3_USE_LARGEFILE64 ?
- "18446744073709551615" : "4294967295";
- XD3_ASSERT(strcmp (buf, expect) == 0);
-}
-
-void TestRandomNumbers() {
- MTRandom rand;
- int rounds = 1<<20;
- uint64_t usum = 0;
- uint64_t esum = 0;
-
- for (int i = 0; i < rounds; i++) {
- usum += rand.Rand32();
- esum += rand.ExpRand32(1024);
- }
+ for (int i = 0; i < rounds; i++) {
+ usum += rand.Rand32();
+ esum += rand.ExpRand32(1024);
+ }
- double allowed_error = 0.01;
+ double allowed_error = 0.01;
- uint32_t umean = usum / rounds;
- uint32_t emean = esum / rounds;
+ uint32_t umean = usum / rounds;
+ uint32_t emean = esum / rounds;
- uint32_t uexpect = UINT32_MAX / 2;
- uint32_t eexpect = 1024;
+ uint32_t uexpect = UINT32_MAX / 2;
+ uint32_t eexpect = 1024;
- if (umean < uexpect * (1.0 - allowed_error) ||
+ if (umean < uexpect * (1.0 - allowed_error) ||
umean > uexpect * (1.0 + allowed_error)) {
XPR(NT "uniform mean error: %u != %u\n", umean, uexpect);
abort();
@@ -487,7 +370,7 @@ void TestFirstByte() {
}
spec0.GenerateFixedSize(size);
spec0.ModifyTo(Modify1stByte(), &spec1);
- InMemoryEncodeDecode(spec0, spec1, NULL, Options());
+ InMemoryEncodeDecode(spec0, spec1, NULL);
}
}
@@ -523,7 +406,7 @@ void TestModifyMutator() {
// pass.
CHECK_GE(diff, test_cases[i].size - (2 * test_cases[i].size / 256));
- InMemoryEncodeDecode(spec0, spec1, NULL, Options());
+ InMemoryEncodeDecode(spec0, spec1, NULL);
}
}
@@ -556,7 +439,7 @@ void TestAddMutator() {
CHECK_EQ(spec0.Size() + test_cases[i].size, spec1.Size());
Block coded;
- InMemoryEncodeDecode(spec0, spec1, &coded, Options());
+ InMemoryEncodeDecode(spec0, spec1, &coded);
Delta delta(coded);
CHECK_EQ(test_cases[i].expected_adds,
@@ -587,13 +470,13 @@ void TestDeleteMutator() {
for (size_t i = 0; i < SIZEOF_ARRAY(test_cases); i++) {
ChangeList cl1;
- cl1.push_back(Change(Change::DELRANGE, test_cases[i].size,
+ cl1.push_back(Change(Change::DELETE, test_cases[i].size,
test_cases[i].addr));
spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
CHECK_EQ(spec0.Size() - test_cases[i].size, spec1.Size());
Block coded;
- InMemoryEncodeDecode(spec0, spec1, &coded, Options());
+ InMemoryEncodeDecode(spec0, spec1, &coded);
Delta delta(coded);
CHECK_EQ(0, delta.AddedBytes());
@@ -628,7 +511,7 @@ void TestCopyMutator() {
CHECK_EQ(spec0.Size() + test_cases[i].size, spec1.Size());
Block coded;
- InMemoryEncodeDecode(spec0, spec1, &coded, Options());
+ InMemoryEncodeDecode(spec0, spec1, &coded);
Delta delta(coded);
CHECK_EQ(0, delta.AddedBytes());
@@ -670,7 +553,7 @@ void TestMoveMutator() {
CHECK_EQ(spec0.Size(), spec1.Size());
Block coded;
- InMemoryEncodeDecode(spec0, spec1, &coded, Options());
+ InMemoryEncodeDecode(spec0, spec1, &coded);
Delta delta(coded);
CHECK_EQ(0, delta.AddedBytes());
@@ -698,9 +581,8 @@ void TestOverwriteMutator() {
CHECK(memcmp(b0.Data() + 30, b1.Data() + 30,
Constants::BLOCK_SIZE - 30) == 0);
- xoff_t zero = 0;
cl1.clear();
- cl1.push_back(Change(Change::COPYOVER, 10, 20, zero));
+ cl1.push_back(Change(Change::COPYOVER, 10, 20, (xoff_t)0));
spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
CHECK_EQ(spec0.Size(), spec1.Size());
@@ -714,7 +596,7 @@ void TestOverwriteMutator() {
// Note: this test is written to expose a problem, but the problem was
// only exposed with BLOCK_SIZE = 128.
-void TestNonBlocking() {
+void TestNonBlockingProgress() {
MTRandom rand;
FileSpec spec0(&rand);
FileSpec spec1(&rand);
@@ -753,7 +635,7 @@ void TestNonBlocking() {
spec0.ModifyTo(ChangeListMutator(ctl), &spec2);
- InMemoryEncodeDecode(spec1, spec2, NULL, Options());
+ InMemoryEncodeDecode(spec1, spec2, NULL);
}
void TestEmptyInMemory() {
@@ -765,7 +647,7 @@ void TestEmptyInMemory() {
spec0.GenerateFixedSize(0);
spec1.GenerateFixedSize(0);
- InMemoryEncodeDecode(spec0, spec1, &block, Options());
+ InMemoryEncodeDecode(spec0, spec1, &block);
Delta delta(block);
CHECK_LT(0, block.Size());
@@ -781,224 +663,94 @@ void TestBlockInMemory() {
spec0.GenerateFixedSize(Constants::BLOCK_SIZE);
spec1.GenerateFixedSize(Constants::BLOCK_SIZE);
- InMemoryEncodeDecode(spec0, spec1, &block, Options());
+ InMemoryEncodeDecode(spec0, spec1, &block);
Delta delta(block);
CHECK_EQ(spec1.Blocks(Constants::WINDOW_SIZE), delta.Windows());
}
-void TestSmallStride() {
+void TestHalfBlockCopy() {
MTRandom rand;
FileSpec spec0(&rand);
- usize_t size = Constants::BLOCK_SIZE * 4;
- spec0.GenerateFixedSize(size);
-
- // Note: Not very good performance due to hash collisions, note 3x
- // multiplier below.
- for (int s = 15; s < 101; s++) {
- usize_t changes = 0;
- ChangeList cl;
- for (usize_t j = s; j < size; j += s, ++changes)
- {
- cl.push_back(Change(Change::MODIFY, 1, j));
- }
-
- FileSpec spec1(&rand);
- spec0.ModifyTo(ChangeListMutator(cl), &spec1);
-
- Options options;
- options.encode_srcwin_maxsz = size;
- options.iopt_size = 128;
- options.smatch_cfg = XD3_SMATCH_SLOW;
- options.size_known = false;
-
- Block block;
- InMemoryEncodeDecode(spec0, spec1, &block, options);
- Delta delta(block);
-
- IF_DEBUG1(DP(RINT "[stride=%d] changes=%" W "u adds=%" Q "u\n",
- s, changes, delta.AddedBytes()));
- double allowance = Constants::BLOCK_SIZE < 8192 || s < 30 ? 3.0 : 1.1;
- CHECK_GE(allowance * changes, (double)delta.AddedBytes());
- }
-}
-
-void TestCopyWindow() {
- // Construct an input that has many copies, to fill the IOPT buffer
- // and force a source window decision. "srclen" may be set to a
- // value that goes beyond the end-of-source.
- const int clen = 16;
- const int size = 4096;
- const int nmov = size / clen;
- const int iters = 16;
- uint32_t added_01 = 0;
- uint32_t added_10 = 0;
- for (int i = 1; i <= iters; i++) {
- MTRandom rand(MTRandom::TEST_SEED1 * i);
- FileSpec spec0(&rand);
- ChangeList cl;
-
- spec0.GenerateFixedSize(size);
-
- for (int j = 0; j < nmov; j += 2)
- {
- cl.push_back(Change(Change::MOVE,
- clen, (j + 1) * clen, j * clen));
- }
-
- FileSpec spec1(&rand);
- spec0.ModifyTo(ChangeListMutator(cl), &spec1);
-
- Options options;
- options.encode_srcwin_maxsz = size;
- options.iopt_size = 128;
- options.smatch_cfg = XD3_SMATCH_SLOW;
-
- Block block1;
- InMemoryEncodeDecode(spec0, spec1, &block1, options);
- Delta delta1(block1);
- // Allow one missed window (e.g., hash collisions)
- added_01 += delta1.AddedBytes();
-
- Block block2;
- InMemoryEncodeDecode(spec1, spec0, &block2, options);
- Delta delta2(block2);
- // Allow one missed window (e.g., hash collisions)
- added_10 += delta2.AddedBytes();
-
- Block block3;
- Block block4;
- EncodeDecodeAPI(spec0, spec1, &block3, options);
- EncodeDecodeAPI(spec1, spec0, &block4, options);
- }
- // Average less than 0.5 misses (of length clen) per iteration.
- CHECK_GE(clen * iters / 2, added_01);
- CHECK_GE(clen * iters / 2, added_10);
-}
-
-void TestCopyFromEnd() {
- // Copies from the end of the source buffer, which reach a block
- // boundary end-of-file.
- const int size = 4096;
- const int clen = 16;
- const int nmov = (size / 2) / clen;
- const int iters = 16;
- uint32_t added_01 = 0;
- uint32_t added_10 = 0;
- for (int i = 1; i <= iters; i++) {
- MTRandom rand(MTRandom::TEST_SEED1 * i);
- FileSpec spec0(&rand);
- ChangeList cl;
-
- spec0.GenerateFixedSize(size);
-
- cl.push_back(Change(Change::MODIFY, 2012, 2048));
-
- for (int j = 0; j < nmov; j += 2)
- {
- cl.push_back(Change(Change::MOVE,
- clen, (j + 1) * clen, j * clen));
- }
-
- cl.push_back(Change(Change::COPYOVER, 28, 4068, 3000));
- cl.push_back(Change(Change::COPYOVER, 30, 4066, 3100));
- cl.push_back(Change(Change::COPYOVER, 32, 4064, 3200));
-
- FileSpec spec1(&rand);
- spec0.ModifyTo(ChangeListMutator(cl), &spec1);
+ FileSpec spec1(&rand);
- Options options;
- options.encode_srcwin_maxsz = size;
- options.iopt_size = 128;
- options.smatch_cfg = XD3_SMATCH_SLOW;
+ spec0.GenerateFixedSize(Constants::BLOCK_SIZE * 4);
- Block block1;
- InMemoryEncodeDecode(spec0, spec1, &block1, options);
- Delta delta1(block1);
- added_01 += delta1.AddedBytes();
+ // Create a half-block copy, 2.5 blocks apart, from the second half
+ // of the source version to the first half of the target version.
+ // 0 1 2 3
+ // spec0 [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb][ccccc][bbbbb]
+ // spec1 [aaaaa][ccccc][aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
+ ChangeList cl1;
+ cl1.push_back(Change(Change::MODIFY,
+ Constants::BLOCK_SIZE / 2, // size
+ 0));
+ cl1.push_back(Change(Change::COPYOVER,
+ Constants::BLOCK_SIZE / 2, // size
+ Constants::BLOCK_SIZE * 3, // offset
+ Constants::BLOCK_SIZE / 2));
+ cl1.push_back(Change(Change::MODIFY,
+ Constants::BLOCK_SIZE * 3,
+ Constants::BLOCK_SIZE));
+ spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
- Block block2;
- InMemoryEncodeDecode(spec1, spec0, &block2, options);
- Delta delta2(block2);
- added_10 += delta2.AddedBytes();
+ const int onecopy_adds =
+ 4 * Constants::BLOCK_SIZE - Constants::BLOCK_SIZE / 2;
+ const int nocopy_adds = 4 * Constants::BLOCK_SIZE;
- Block block3;
- Block block4;
- EncodeDecodeAPI(spec0, spec1, &block3, options);
- EncodeDecodeAPI(spec1, spec0, &block4, options);
- }
- CHECK_GE(2000 * iters, added_01);
- CHECK_LE(2000 * iters, added_10);
-}
-
-void TestHalfBlockCopy() {
- // Create a half-block copy, 7.5 blocks apart, in a pair of files:
- // 0 1 ... 6 7
- // spec0 [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb][ccccc][bbbb_]
- // spec1 [aaaaa][ccccc][aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_]
- // where stage=
- // 0: the final block is full
- // a. (source)spec1->(target)spec0 copies block C: reads 8 source
- // blocks during target block 0.
- // b. (source)spec0->(target)spec1 does not copy block C b/c attempt
- // to read past EOF empties block 0 from (virtual) block cache
- // 1: the final block is less than full.
- // a. (same) copies block C
- // b. (same) copies block C, unlike 0a, no attempt to read past EOF
- //
- // "virtual" above refers to XD3_TOOFARBACK, since there is no caching
- // in the API, there is simply a promise not to request blocks that are
- // beyond source->max_winsize from the last known source file position.
- for (int stage = 0; stage < 2; stage++)
+ // Note the case b=4 is contrived: the caller should use a single block
+ // containing the entire source, if possible.
+ for (int b = 1; b <= 4; b++)
{
- IF_DEBUG1 (DP(RINT "half_block_copy stage %d\n", stage));
-
- MTRandom rand;
- FileSpec spec0(&rand);
- FileSpec spec1(&rand);
-
- spec0.GenerateFixedSize(Constants::BLOCK_SIZE * 8 - stage);
-
- ChangeList cl1;
- cl1.push_back(Change(Change::MODIFY,
- Constants::BLOCK_SIZE / 2, // size
- 0));
- cl1.push_back(Change(Change::COPYOVER,
- Constants::BLOCK_SIZE / 2, // size
- Constants::BLOCK_SIZE * 7, // offset
- Constants::BLOCK_SIZE / 2));
- cl1.push_back(Change(Change::MODIFY,
- Constants::BLOCK_SIZE * 7,
- Constants::BLOCK_SIZE - stage));
- spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
-
Options options;
- options.encode_srcwin_maxsz = Constants::BLOCK_SIZE * 8;
+ options.encode_srcwin_maxsz = Constants::BLOCK_SIZE * b;
Block block0;
Block block1;
InMemoryEncodeDecode(spec0, spec1, &block0, options);
InMemoryEncodeDecode(spec1, spec0, &block1, options);
-
Delta delta0(block0);
Delta delta1(block1);
- const int yes =
- Constants::BLOCK_SIZE * 8 - Constants::BLOCK_SIZE / 2;
- const int no =
- Constants::BLOCK_SIZE * 8 - Constants::BLOCK_SIZE / 2;
-
- if (stage == 0)
- {
- CHECK_EQ(yes, delta0.AddedBytes());
- CHECK_EQ(no, delta1.AddedBytes());
- }
+ // The first block never copies from the last source block, by
+ // design, because if the last source block is available when
+ // the first target block is ready, the caller is expected to
+ // use a single block.
+ CHECK_EQ(nocopy_adds, delta0.AddedBytes());
+ if (Constants::BLOCK_SIZE < 8192 || b > 2)
+ {
+ // For small-block inputs, the entire file is read into one
+ // block (the min source window size is 16kB).
+ //
+ // For large blocks, at least 3 blocks of source window are
+ // needed.
+ CHECK_EQ(onecopy_adds, delta1.AddedBytes());
+ }
else
- {
- CHECK_EQ(yes, delta0.AddedBytes());
- CHECK_EQ(yes, delta1.AddedBytes());
- }
+ {
+ // When there are fewer than 3 source blocks.
+ CHECK_EQ(nocopy_adds, delta1.AddedBytes());
+ }
+ // XPR(NT "0=%zu 1=%zu\n", delta0.AddedBytes(), delta1.AddedBytes());
}
+
+ Options options;
+ options.encode_srcwin_maxsz = Constants::BLOCK_SIZE * 4;
+ options.block_size = Constants::BLOCK_SIZE * 4;
+
+ // Test the whole-buffer case.
+ Block block0;
+ Block block1;
+ InMemoryEncodeDecode(spec0, spec1, &block0, options);
+ InMemoryEncodeDecode(spec1, spec0, &block1, options);
+ Delta delta0(block0);
+ Delta delta1(block1);
+ // This <= >= are only for blocksize = 512, which has irregular readsize.
+ CHECK_LE(onecopy_adds, delta0.AddedBytes());
+ CHECK_GE(onecopy_adds + 1, delta0.AddedBytes());
+
+ CHECK_EQ(onecopy_adds, delta1.AddedBytes());
+ // XPR(NT "0=%zu 1=%zu\n", delta0.AddedBytes(), delta1.AddedBytes());
}
void FourWayMergeTest(const FileSpec &spec0,
@@ -1008,7 +760,7 @@ void FourWayMergeTest(const FileSpec &spec0,
TmpFile f0, f1, f2, f3;
ExtFile d01, d12, d23;
Options options;
- options.encode_srcwin_maxsz =
+ options.encode_srcwin_maxsz =
std::max(spec0.Size(), options.encode_srcwin_maxsz);
spec0.WriteTmpFile(&f0);
@@ -1131,7 +883,7 @@ void TestMergeCommand1() {
}
cl1.push_back(Change(Change::ADD, change1, add1_pos));
- cl2.push_back(Change(Change::DELRANGE, change1, del2_pos));
+ cl2.push_back(Change(Change::DELETE, change1, del2_pos));
cl3.push_back(Change(Change::MODIFY, change3, change3_pos));
spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
@@ -1185,9 +937,9 @@ void TestMergeCommand2() {
ChangeList cl1, cl2, cl3;
- cl1.push_back(Change(Change::DELRANGE, size0 - size1, 0));
- cl2.push_back(Change(Change::DELRANGE, size0 - size2, 0));
- cl3.push_back(Change(Change::DELRANGE, size0 - size3, 0));
+ cl1.push_back(Change(Change::DELETE, size0 - size1, 0));
+ cl2.push_back(Change(Change::DELETE, size0 - size2, 0));
+ cl3.push_back(Change(Change::DELETE, size0 - size3, 0));
spec0.ModifyTo(ChangeListMutator(cl1), &spec1);
spec0.ModifyTo(ChangeListMutator(cl2), &spec2);
@@ -1201,44 +953,6 @@ void TestMergeCommand2() {
}
}
-void TestLastFrontierBlock() {
- // This test constructs an input that can expose
- // https://github.com/jmacd/xdelta/issues/188
- // when run through the command-line with source via a FIFO.
- // That is not tested here, but the test stays.
- if (Constants::WINDOW_SIZE < XD3_ALLOCSIZE)
- {
- return;
- }
-
- MTRandom rand;
- FileSpec spec0(&rand);
- FileSpec spec1(&rand);
- const xoff_t size = XD3_ALLOCSIZE * 64; // == XD3_MINSRCWINSZ * 2
- const xoff_t edit = XD3_ALLOCSIZE;
-
- Options options;
- options.encode_srcwin_maxsz = XD3_MINSRCWINSZ;
- options.block_size = XD3_ALLOCSIZE;
- options.window_size = XD3_MINSRCWINSZ;
- options.size_known = false;
-
- spec0.GenerateFixedSize(size);
-
- ChangeList cl;
-
- // Modify the 0th byte in order to induce indexing of subsequent
- // bytes, but allow copying most of the file to keep the test fast.
- cl.push_back(Change(Change::MODIFY, 1, edit * 31));
- cl.push_back(Change(Change::COPYOVER, edit, edit * 31, edit * 63));
-
- spec0.ModifyTo(ChangeListMutator(cl), &spec1);
-
- Block noblock;
- InMemoryEncodeDecode(spec0, spec1, &noblock, options);
- InMemoryEncodeDecode(spec1, spec0, &noblock, options);
-}
-
}; // class Regtest<Constants>
#define TEST(x) XPR(NTR #x "...\n"); regtest.x()
@@ -1247,7 +961,6 @@ void TestLastFrontierBlock() {
template <class T>
void UnitTest() {
Regtest<T> regtest;
- TEST(TestPrintf);
TEST(TestRandomNumbers);
TEST(TestRandomFile);
TEST(TestFirstByte);
@@ -1262,24 +975,20 @@ void UnitTest() {
// These are Xdelta tests.
template <class T>
void MainTest() {
- XPR(NT "Blocksize %" Q "u windowsize %" Z "u\n",
- T::BLOCK_SIZE, T::WINDOW_SIZE);
+ XPR(NT "Blocksize %"Q"u readsize %"Q"u windowsize %"Q"u\n",
+ T::BLOCK_SIZE, T::READ_SIZE, T::WINDOW_SIZE);
Regtest<T> regtest;
TEST(TestEmptyInMemory);
TEST(TestBlockInMemory);
- TEST(TestSmallStride);
- TEST(TestCopyWindow);
- TEST(TestCopyFromEnd);
- TEST(TestNonBlocking);
+ TEST(TestNonBlockingProgress);
TEST(TestHalfBlockCopy);
- TEST(TestLastFrontierBlock);
TEST(TestMergeCommand1);
TEST(TestMergeCommand2);
}
#undef TEST
-int main(int argc, char **argv)
+int main(int argc, char **argv)
{
vector<const char*> mcmd;
string pn;
@@ -1295,6 +1004,7 @@ int main(int argc, char **argv)
UnitTest<SmallBlock>();
MainTest<SmallBlock>();
MainTest<MixedBlock>();
+ MainTest<PrimeBlock>();
MainTest<OversizeBlock>();
MainTest<LargeBlock>();
@@ -1303,4 +1013,3 @@ int main(int argc, char **argv)
return 0;
}
-
diff --git a/testing/run_release.sh b/testing/run_release.sh
deleted file mode 100755
index 85ed1f7..0000000
--- a/testing/run_release.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-(cd .. && ./run_release.sh)
diff --git a/testing/sizes.h b/testing/sizes.h
index 223d359..18f46e9 100644
--- a/testing/sizes.h
+++ b/testing/sizes.h
@@ -77,35 +77,54 @@ const size_t BaseConstants::TEST_ROUNDS = 10;
struct SmallBlock : public BaseConstants {
static const xoff_t BLOCK_SIZE;
static const size_t WINDOW_SIZE;
+ static const size_t READ_SIZE;
typedef SmallSizes Sizes;
};
+const size_t SmallBlock::READ_SIZE = 1<<7;
const xoff_t SmallBlock::BLOCK_SIZE = 1<<7;
const size_t SmallBlock::WINDOW_SIZE = 1<<7;
struct LargeBlock : public BaseConstants {
static const xoff_t BLOCK_SIZE;
static const size_t WINDOW_SIZE;
+ static const size_t READ_SIZE;
typedef LargeSizes Sizes;
};
+const size_t LargeBlock::READ_SIZE = (1 << 13);
const xoff_t LargeBlock::BLOCK_SIZE = (1 << 13);
const size_t LargeBlock::WINDOW_SIZE = (1 << 13);
struct MixedBlock : public BaseConstants {
static const xoff_t BLOCK_SIZE;
static const size_t WINDOW_SIZE;
+ static const size_t READ_SIZE;
typedef SmallSizes Sizes;
};
+const size_t MixedBlock::READ_SIZE = 1<<6;
const xoff_t MixedBlock::BLOCK_SIZE = 1<<7;
const size_t MixedBlock::WINDOW_SIZE = 1<<8;
struct OversizeBlock : public BaseConstants {
static const xoff_t BLOCK_SIZE;
static const size_t WINDOW_SIZE;
+ static const size_t READ_SIZE;
typedef SmallSizes Sizes;
};
+const size_t OversizeBlock::READ_SIZE = (1<<6) + (1<<7);
const xoff_t OversizeBlock::BLOCK_SIZE = 1<<8;
const size_t OversizeBlock::WINDOW_SIZE = 1<<7;
+
+struct PrimeBlock : public BaseConstants {
+ static const xoff_t BLOCK_SIZE;
+ static const size_t WINDOW_SIZE;
+ static const size_t READ_SIZE;
+ typedef SmallSizes Sizes;
+};
+
+const size_t PrimeBlock::READ_SIZE = 71;
+const xoff_t PrimeBlock::BLOCK_SIZE = 512; // Must be a power-of-2
+const size_t PrimeBlock::WINDOW_SIZE = 73;
diff --git a/testing/test.h b/testing/test.h
index 7de24fb..d1f1a22 100644
--- a/testing/test.h
+++ b/testing/test.h
@@ -18,12 +18,12 @@ extern "C" {
#define CHECK_OP(x,y,OP) \
do { \
- __typeof__(x) _x(x); \
- __typeof__(x) _y(y); \
+ typeof(x) _x(x); \
+ typeof(x) _y(y); \
if (!(_x OP _y)) { \
cerr << __FILE__ << ":" << __LINE__ << " Check failed: " << #x " " #OP " " #y << endl; \
- cerr << __FILE__ << ":" << __LINE__ << " {0} " << _x << endl; \
- cerr << __FILE__ << ":" << __LINE__ << " {1} " << _y << endl; \
+ cerr << __FILE__ << ":" << __LINE__ << " Expected: " << _x << endl; \
+ cerr << __FILE__ << ":" << __LINE__ << " Actual: " << _y << endl; \
abort(); \
} } while (false)
#undef CHECK
@@ -68,3 +68,5 @@ pair<T, U> make_pair(const T& t, const U& u) {
using std::min;
using std::max;
+
+