diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2007-11-13 04:02:15 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2007-11-13 04:02:15 +0000 |
commit | ba57c64d224ed4feb37ff7005e33f6a7d70cbbd9 (patch) | |
tree | fecf5dfdec9d4a49d5e81df5608f4e027dc7a8fd | |
parent | a4b5480a34e217e93e147f460b47e27741d809c1 (diff) |
-rw-r--r-- | xdelta3/examples/checksum_test.cc | 327 | ||||
-rw-r--r-- | xdelta3/xdelta3-hash.h | 10 | ||||
-rw-r--r-- | xdelta3/xdelta3-list.h | 212 | ||||
-rw-r--r-- | xdelta3/xdelta3-test.h | 11 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 11 |
5 files changed, 422 insertions, 149 deletions
diff --git a/xdelta3/examples/checksum_test.cc b/xdelta3/examples/checksum_test.cc index 821291a..a48c6ef 100644 --- a/xdelta3/examples/checksum_test.cc +++ b/xdelta3/examples/checksum_test.cc | |||
@@ -5,49 +5,263 @@ extern "C" { | |||
5 | #include <assert.h> | 5 | #include <assert.h> |
6 | } | 6 | } |
7 | 7 | ||
8 | // template <typename T, int Cklen> | 8 | #include <list> |
9 | #include <map> | ||
10 | |||
11 | using std::list; | ||
12 | using std::map; | ||
13 | |||
14 | // Need gcc4 | ||
15 | // template <typename T, int TestCklen> | ||
9 | // struct cksum_params { | 16 | // struct cksum_params { |
10 | // typedef T cksum_type; | 17 | // typedef T cksum_type; |
11 | // enum { cklen = Cklen }; | 18 | // enum { test_cklen = TestCklen }; |
12 | // }; | 19 | // }; |
13 | 20 | ||
14 | template <int Cklen> | 21 | |
15 | struct rabin_karp { | 22 | // MLCG parameters |
16 | enum { cklen = Cklen, }; | 23 | uint32_t good_32bit_values[] = { |
24 | // 741103597U, 887987685U, | ||
25 | 1597334677U, | ||
17 | }; | 26 | }; |
18 | 27 | ||
19 | template<typename T> | 28 | // a, a* |
20 | struct test_result { | 29 | uint64_t good_64bit_values[] = { |
30 | // 1181783497276652981ULL, 4292484099903637661ULL, | ||
31 | 7664345821815920749ULL, | ||
32 | }; | ||
21 | 33 | ||
22 | int n_data; | 34 | template <typename Word> |
35 | int bitsof(); | ||
23 | 36 | ||
24 | test_result() | 37 | template<> |
25 | : n_data(0) { | 38 | int bitsof<uint32_t>() { |
26 | } | 39 | return 32; |
40 | } | ||
27 | 41 | ||
28 | void print() { | 42 | template<> |
29 | fprintf(stderr, "cklen %u: %u results\n", T::cklen, n_data); | 43 | int bitsof<uint64_t>() { |
30 | } | 44 | return 64; |
45 | } | ||
31 | 46 | ||
32 | void add(uint8_t* ptr) { | 47 | struct noperm { |
33 | n_data++; | 48 | int operator()(const uint8_t &c) { |
34 | } | 49 | return c; |
50 | } | ||
35 | }; | 51 | }; |
36 | 52 | ||
37 | typedef rabin_karp<4> small_cksum; | 53 | struct permute { |
38 | typedef rabin_karp<9> large_cksum; | 54 | int operator()(const uint8_t &c) { |
55 | return __single_hash[c]; | ||
56 | } | ||
57 | }; | ||
39 | 58 | ||
40 | template<typename T> | 59 | template <typename Word> |
41 | void test(uint8_t* buf, usize_t buf_len) { | 60 | Word good_word(); |
42 | test_result<T> result; | ||
43 | 61 | ||
44 | for (usize_t i = 0; i < buf_len - T::cklen; i++) { | 62 | template<> |
45 | result.add(buf + i); | 63 | uint32_t good_word<uint32_t>() { |
46 | } | 64 | return good_32bit_values[0]; |
65 | } | ||
47 | 66 | ||
48 | result.print(); | 67 | template<> |
68 | uint64_t good_word<uint64_t>() { | ||
69 | return good_64bit_values[0]; | ||
49 | } | 70 | } |
50 | 71 | ||
72 | int | ||
73 | size_log2 (int slots) | ||
74 | { | ||
75 | int bits = 31; | ||
76 | int i; | ||
77 | |||
78 | for (i = 3; i <= bits; i += 1) | ||
79 | { | ||
80 | if (slots <= (1 << i)) | ||
81 | { | ||
82 | bits = i; | ||
83 | break; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | return bits; | ||
88 | } | ||
89 | |||
90 | template <typename Word, int CksumSize, int CksumSkip, typename Permute> | ||
91 | struct rabin_karp { | ||
92 | typedef Word word_type; | ||
93 | typedef Permute permute_type; | ||
94 | |||
95 | enum { cksum_size = CksumSize, | ||
96 | cksum_skip = CksumSkip, | ||
97 | }; | ||
98 | |||
99 | rabin_karp() { | ||
100 | multiplier = good_word<Word>(); | ||
101 | powers = new Word[cksum_size]; | ||
102 | powers[cksum_size - 1] = 1; | ||
103 | for (int i = cksum_size - 2; i >= 0; i--) { | ||
104 | powers[i] = powers[i + 1] * multiplier; | ||
105 | } | ||
106 | product = powers[0] * multiplier; | ||
107 | } | ||
108 | |||
109 | Word step(const uint8_t *ptr) { | ||
110 | Word h = 0; | ||
111 | for (int i = 0; i < cksum_size; i++) { | ||
112 | h += permute_type()(ptr[i]) * powers[i]; | ||
113 | } | ||
114 | return h; | ||
115 | } | ||
116 | |||
117 | Word state0(const uint8_t *ptr) { | ||
118 | state = step(ptr); | ||
119 | return state; | ||
120 | } | ||
121 | |||
122 | Word incr(const uint8_t *ptr) { | ||
123 | state = state - | ||
124 | product * permute_type()(ptr[-1]) + | ||
125 | permute_type()(ptr[cksum_size - 1]); | ||
126 | return state; | ||
127 | } | ||
128 | |||
129 | Word *powers; | ||
130 | Word product; | ||
131 | Word multiplier; | ||
132 | Word state; | ||
133 | }; | ||
134 | |||
135 | struct test_result_base; | ||
136 | |||
137 | static list<test_result_base*> all_tests; | ||
138 | |||
139 | struct test_result_base { | ||
140 | virtual ~test_result_base() { | ||
141 | } | ||
142 | virtual void print() = 0; | ||
143 | virtual void get(const uint8_t* buf, const int buf_size) = 0; | ||
144 | }; | ||
145 | |||
146 | template<typename T> | ||
147 | struct test_result : public test_result_base { | ||
148 | int n_steps; | ||
149 | int n_incrs; | ||
150 | int s_bits; | ||
151 | int s_mask; | ||
152 | int h_bits; | ||
153 | int t_entries; | ||
154 | double step_fill; | ||
155 | double incr_fill; | ||
156 | long start_step, end_step; | ||
157 | long start_incr, end_incr; | ||
158 | |||
159 | test_result() { | ||
160 | all_tests.push_back(this); | ||
161 | } | ||
162 | |||
163 | void print() { | ||
164 | fprintf(stderr, | ||
165 | "cksum size %u: skip %u: %u steps: %u incrs: " | ||
166 | "s_fill %0.2f%% i_fill %0.2f%%\n", | ||
167 | T::cksum_size, | ||
168 | T::cksum_skip, | ||
169 | n_steps, | ||
170 | n_incrs, | ||
171 | 100.0 * step_fill, | ||
172 | 100.0 * incr_fill); | ||
173 | } | ||
174 | |||
175 | int* new_table(int entries) { | ||
176 | t_entries = entries; | ||
177 | h_bits = size_log2(entries); | ||
178 | s_bits = bitsof<typename T::word_type>() - h_bits; | ||
179 | s_mask = (1 << h_bits) - 1; | ||
180 | |||
181 | int n = 1 << h_bits; | ||
182 | int *t = new int[n]; | ||
183 | memset(t, 0, sizeof(int) * n); | ||
184 | return t; | ||
185 | } | ||
186 | |||
187 | double summarize_table(int* table) { | ||
188 | int n = 1 << h_bits; | ||
189 | int f = 0; | ||
190 | for (int i = 0; i < n; i++) { | ||
191 | if (table[i] != 0) { | ||
192 | f++; | ||
193 | } | ||
194 | } | ||
195 | delete [] table; | ||
196 | return (double) f / (double) t_entries; | ||
197 | } | ||
198 | |||
199 | void get(const uint8_t* buf, const int buf_size) { | ||
200 | const uint8_t *ptr; | ||
201 | const uint8_t *end; | ||
202 | int last_offset; | ||
203 | int periods; | ||
204 | int stop; | ||
205 | int *hash_table; | ||
206 | |||
207 | last_offset = buf_size - T::cksum_size; | ||
208 | |||
209 | if (last_offset < 0) { | ||
210 | periods = 0; | ||
211 | n_steps = 0; | ||
212 | n_incrs = 0; | ||
213 | stop = -T::cksum_size; | ||
214 | } else { | ||
215 | periods = last_offset / T::cksum_skip; | ||
216 | n_steps = periods; | ||
217 | n_incrs = last_offset; | ||
218 | stop = last_offset - (periods + 1) * T::cksum_skip; | ||
219 | } | ||
220 | |||
221 | hash_table = new_table(n_steps); | ||
222 | |||
223 | start_step = get_millisecs_now(); | ||
224 | |||
225 | ptr = buf + last_offset; | ||
226 | end = buf + stop; | ||
227 | |||
228 | T t; | ||
229 | typename T::word_type w; | ||
230 | |||
231 | for (; ptr != end; ptr -= T::cksum_skip) { | ||
232 | w = t.step(ptr); | ||
233 | ++hash_table[(w >> s_bits) ^ (w & s_mask)]; | ||
234 | } | ||
235 | |||
236 | end_step = get_millisecs_now(); | ||
237 | |||
238 | step_fill = summarize_table(hash_table); | ||
239 | hash_table = new_table(n_incrs); | ||
240 | |||
241 | stop = buf_size - T::cksum_size + 1; | ||
242 | if (stop < 0) { | ||
243 | stop = 0; | ||
244 | } | ||
245 | |||
246 | start_incr = end_step; | ||
247 | |||
248 | ptr = buf; | ||
249 | end = buf + stop; | ||
250 | if (ptr != end) { | ||
251 | w = t.state0(ptr++); | ||
252 | ++hash_table[(w >> s_bits) ^ (w & s_mask)]; | ||
253 | } | ||
254 | for (; ptr != end; ptr++) { | ||
255 | w = t.incr(ptr); | ||
256 | ++hash_table[(w >> s_bits) ^ (w & s_mask)]; | ||
257 | } | ||
258 | |||
259 | end_incr = get_millisecs_now(); | ||
260 | |||
261 | incr_fill = summarize_table(hash_table); | ||
262 | } | ||
263 | }; | ||
264 | |||
51 | int main(int argc, char** argv) { | 265 | int main(int argc, char** argv) { |
52 | int i; | 266 | int i; |
53 | uint8_t *buf = NULL; | 267 | uint8_t *buf = NULL; |
@@ -55,10 +269,62 @@ int main(int argc, char** argv) { | |||
55 | int ret; | 269 | int ret; |
56 | 270 | ||
57 | if (argc <= 1) { | 271 | if (argc <= 1) { |
58 | fprintf(stderr, "usage: %s file ...", argv[0]); | 272 | fprintf(stderr, "usage: %s file ...\n", argv[0]); |
59 | return 1; | 273 | return 1; |
60 | } | 274 | } |
61 | 275 | ||
276 | test_result<rabin_karp<uint32_t, 4, 1, noperm> > small_1_cksum; | ||
277 | test_result<rabin_karp<uint32_t, 4, 4, noperm> > small_4_cksum; | ||
278 | test_result<rabin_karp<uint32_t, 9, 1, noperm> > large_1_cksum; | ||
279 | test_result<rabin_karp<uint32_t, 9, 2, noperm> > large_2_cksum; | ||
280 | test_result<rabin_karp<uint32_t, 9, 3, noperm> > large_3_cksum; | ||
281 | test_result<rabin_karp<uint32_t, 9, 5, noperm> > large_5_cksum; | ||
282 | test_result<rabin_karp<uint32_t, 9, 6, noperm> > large_6_cksum; | ||
283 | test_result<rabin_karp<uint32_t, 9, 7, noperm> > large_7_cksum; | ||
284 | test_result<rabin_karp<uint32_t, 9, 8, noperm> > large_8_cksum; | ||
285 | test_result<rabin_karp<uint32_t, 9, 15, noperm> > large_15_cksum; | ||
286 | test_result<rabin_karp<uint32_t, 9, 26, noperm> > large_26_cksum; | ||
287 | test_result<rabin_karp<uint32_t, 9, 55, noperm> > large_55_cksum; | ||
288 | |||
289 | test_result<rabin_karp<uint32_t, 4, 1, permute> > small_1_cksum_p; | ||
290 | test_result<rabin_karp<uint32_t, 4, 4, permute> > small_4_cksum_p; | ||
291 | test_result<rabin_karp<uint32_t, 9, 1, permute> > large_1_cksum_p; | ||
292 | test_result<rabin_karp<uint32_t, 9, 2, permute> > large_2_cksum_p; | ||
293 | test_result<rabin_karp<uint32_t, 9, 3, permute> > large_3_cksum_p; | ||
294 | test_result<rabin_karp<uint32_t, 9, 5, permute> > large_5_cksum_p; | ||
295 | test_result<rabin_karp<uint32_t, 9, 6, permute> > large_6_cksum_p; | ||
296 | test_result<rabin_karp<uint32_t, 9, 7, permute> > large_7_cksum_p; | ||
297 | test_result<rabin_karp<uint32_t, 9, 8, permute> > large_8_cksum_p; | ||
298 | test_result<rabin_karp<uint32_t, 9, 15, permute> > large_15_cksum_p; | ||
299 | test_result<rabin_karp<uint32_t, 9, 26, permute> > large_26_cksum_p; | ||
300 | test_result<rabin_karp<uint32_t, 9, 55, permute> > large_55_cksum_p; | ||
301 | |||
302 | test_result<rabin_karp<uint64_t, 4, 1, noperm> > small_1_cksum_64; | ||
303 | test_result<rabin_karp<uint64_t, 4, 4, noperm> > small_4_cksum_64; | ||
304 | test_result<rabin_karp<uint64_t, 9, 1, noperm> > large_1_cksum_64; | ||
305 | test_result<rabin_karp<uint64_t, 9, 2, noperm> > large_2_cksum_64; | ||
306 | test_result<rabin_karp<uint64_t, 9, 3, noperm> > large_3_cksum_64; | ||
307 | test_result<rabin_karp<uint64_t, 9, 5, noperm> > large_5_cksum_64; | ||
308 | test_result<rabin_karp<uint64_t, 9, 6, noperm> > large_6_cksum_64; | ||
309 | test_result<rabin_karp<uint64_t, 9, 7, noperm> > large_7_cksum_64; | ||
310 | test_result<rabin_karp<uint64_t, 9, 8, noperm> > large_8_cksum_64; | ||
311 | test_result<rabin_karp<uint64_t, 9, 15, noperm> > large_15_cksum_64; | ||
312 | test_result<rabin_karp<uint64_t, 9, 26, noperm> > large_26_cksum_64; | ||
313 | test_result<rabin_karp<uint64_t, 9, 55, noperm> > large_55_cksum_64; | ||
314 | |||
315 | test_result<rabin_karp<uint64_t, 4, 1, permute> > small_1_cksum_p_64; | ||
316 | test_result<rabin_karp<uint64_t, 4, 4, permute> > small_4_cksum_p_64; | ||
317 | test_result<rabin_karp<uint64_t, 9, 1, permute> > large_1_cksum_p_64; | ||
318 | test_result<rabin_karp<uint64_t, 9, 2, permute> > large_2_cksum_p_64; | ||
319 | test_result<rabin_karp<uint64_t, 9, 3, permute> > large_3_cksum_p_64; | ||
320 | test_result<rabin_karp<uint64_t, 9, 5, permute> > large_5_cksum_p_64; | ||
321 | test_result<rabin_karp<uint64_t, 9, 6, permute> > large_6_cksum_p_64; | ||
322 | test_result<rabin_karp<uint64_t, 9, 7, permute> > large_7_cksum_p_64; | ||
323 | test_result<rabin_karp<uint64_t, 9, 8, permute> > large_8_cksum_p_64; | ||
324 | test_result<rabin_karp<uint64_t, 9, 15, permute> > large_15_cksum_p_64; | ||
325 | test_result<rabin_karp<uint64_t, 9, 26, permute> > large_26_cksum_p_64; | ||
326 | test_result<rabin_karp<uint64_t, 9, 55, permute> > large_55_cksum_p_64; | ||
327 | |||
62 | for (i = 1; i < argc; i++) { | 328 | for (i = 1; i < argc; i++) { |
63 | if ((ret = read_whole_file(argv[i], | 329 | if ((ret = read_whole_file(argv[i], |
64 | & buf, | 330 | & buf, |
@@ -68,8 +334,11 @@ int main(int argc, char** argv) { | |||
68 | 334 | ||
69 | fprintf(stderr, "file %s is %u bytes\n", argv[i], buf_len); | 335 | fprintf(stderr, "file %s is %u bytes\n", argv[i], buf_len); |
70 | 336 | ||
71 | test<small_cksum>(buf, buf_len); | 337 | for (list<test_result_base*>::iterator i = all_tests.begin(); |
72 | test<large_cksum>(buf, buf_len); | 338 | i != all_tests.end(); ++i) { |
339 | (*i)->get(buf, buf_len); | ||
340 | (*i)->print(); | ||
341 | } | ||
73 | 342 | ||
74 | free(buf); | 343 | free(buf); |
75 | buf = NULL; | 344 | buf = NULL; |
diff --git a/xdelta3/xdelta3-hash.h b/xdelta3/xdelta3-hash.h index a1cc9d8..5d12804 100644 --- a/xdelta3/xdelta3-hash.h +++ b/xdelta3/xdelta3-hash.h | |||
@@ -77,8 +77,8 @@ | |||
77 | 77 | ||
78 | static const uint16_t __single_hash[256] = | 78 | static const uint16_t __single_hash[256] = |
79 | { | 79 | { |
80 | /* Random numbers generated using SLIB's pseudo-random number generator. This hashes | 80 | /* Random numbers generated using SLIB's pseudo-random number generator. |
81 | * the input alphabet. */ | 81 | * This hashes the input alphabet. */ |
82 | 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46, | 82 | 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46, |
83 | 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602, | 83 | 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602, |
84 | 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6, | 84 | 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6, |
@@ -208,9 +208,9 @@ xd3_size_hashtable (xd3_stream *stream, | |||
208 | usize_t slots, | 208 | usize_t slots, |
209 | xd3_hash_cfg *cfg) | 209 | xd3_hash_cfg *cfg) |
210 | { | 210 | { |
211 | /* initialize ctable: the number of hash buckets is computed from the table of primes or | 211 | /* initialize ctable: the number of hash buckets is computed from the table |
212 | * the nearest power-of-two, in both cases rounding down in favor of using less | 212 | * of primes or the nearest power-of-two, in both cases rounding down in |
213 | * memory. */ | 213 | * favor of using less memory. */ |
214 | 214 | ||
215 | #if HASH_PRIME | 215 | #if HASH_PRIME |
216 | usize_t i; | 216 | usize_t i; |
diff --git a/xdelta3/xdelta3-list.h b/xdelta3/xdelta3-list.h index 8d49e45..3c0df5e 100644 --- a/xdelta3/xdelta3-list.h +++ b/xdelta3/xdelta3-list.h | |||
@@ -19,112 +19,112 @@ | |||
19 | #ifndef __XDELTA3_LIST__ | 19 | #ifndef __XDELTA3_LIST__ |
20 | #define __XDELTA3_LIST__ | 20 | #define __XDELTA3_LIST__ |
21 | 21 | ||
22 | #define XD3_MAKELIST(LTYPE,ETYPE,LNAME) \ | 22 | #define XD3_MAKELIST(LTYPE,ETYPE,LNAME) \ |
23 | \ | 23 | \ |
24 | static inline ETYPE* \ | 24 | static inline ETYPE* \ |
25 | LTYPE ## _entry (LTYPE* l) \ | 25 | LTYPE ## _entry (LTYPE* l) \ |
26 | { \ | 26 | { \ |
27 | return (ETYPE*) ((char*) l - (unsigned long) &((ETYPE*) 0)->LNAME); \ | 27 | return (ETYPE*) ((char*) l - (unsigned long) &((ETYPE*) 0)->LNAME); \ |
28 | } \ | 28 | } \ |
29 | \ | 29 | \ |
30 | static inline void \ | 30 | static inline void \ |
31 | LTYPE ## _init (LTYPE *l) \ | 31 | LTYPE ## _init (LTYPE *l) \ |
32 | { \ | 32 | { \ |
33 | l->next = l; \ | 33 | l->next = l; \ |
34 | l->prev = l; \ | 34 | l->prev = l; \ |
35 | } \ | 35 | } \ |
36 | \ | 36 | \ |
37 | static inline void \ | 37 | static inline void \ |
38 | LTYPE ## _add (LTYPE *prev, LTYPE *next, LTYPE *ins) \ | 38 | LTYPE ## _add (LTYPE *prev, LTYPE *next, LTYPE *ins) \ |
39 | { \ | 39 | { \ |
40 | next->prev = ins; \ | 40 | next->prev = ins; \ |
41 | prev->next = ins; \ | 41 | prev->next = ins; \ |
42 | ins->next = next; \ | 42 | ins->next = next; \ |
43 | ins->prev = prev; \ | 43 | ins->prev = prev; \ |
44 | } \ | 44 | } \ |
45 | \ | 45 | \ |
46 | static inline void \ | 46 | static inline void \ |
47 | LTYPE ## _push_back (LTYPE *l, ETYPE *i) \ | 47 | LTYPE ## _push_back (LTYPE *l, ETYPE *i) \ |
48 | { \ | 48 | { \ |
49 | LTYPE ## _add (l->prev, l, & i->LNAME); \ | 49 | LTYPE ## _add (l->prev, l, & i->LNAME); \ |
50 | } \ | 50 | } \ |
51 | \ | 51 | \ |
52 | static inline void \ | 52 | static inline void \ |
53 | LTYPE ## _del (LTYPE *next, \ | 53 | LTYPE ## _del (LTYPE *next, \ |
54 | LTYPE *prev) \ | 54 | LTYPE *prev) \ |
55 | { \ | 55 | { \ |
56 | next->prev = prev; \ | 56 | next->prev = prev; \ |
57 | prev->next = next; \ | 57 | prev->next = next; \ |
58 | } \ | 58 | } \ |
59 | \ | 59 | \ |
60 | static inline ETYPE* \ | 60 | static inline ETYPE* \ |
61 | LTYPE ## _remove (ETYPE *f) \ | 61 | LTYPE ## _remove (ETYPE *f) \ |
62 | { \ | 62 | { \ |
63 | LTYPE *i = f->LNAME.next; \ | 63 | LTYPE *i = f->LNAME.next; \ |
64 | LTYPE ## _del (f->LNAME.next, f->LNAME.prev); \ | 64 | LTYPE ## _del (f->LNAME.next, f->LNAME.prev); \ |
65 | return LTYPE ## _entry (i); \ | 65 | return LTYPE ## _entry (i); \ |
66 | } \ | 66 | } \ |
67 | \ | 67 | \ |
68 | static inline ETYPE* \ | 68 | static inline ETYPE* \ |
69 | LTYPE ## _pop_back (LTYPE *l) \ | 69 | LTYPE ## _pop_back (LTYPE *l) \ |
70 | { \ | 70 | { \ |
71 | LTYPE *i = l->prev; \ | 71 | LTYPE *i = l->prev; \ |
72 | LTYPE ## _del (i->next, i->prev); \ | 72 | LTYPE ## _del (i->next, i->prev); \ |
73 | return LTYPE ## _entry (i); \ | 73 | return LTYPE ## _entry (i); \ |
74 | } \ | 74 | } \ |
75 | \ | 75 | \ |
76 | static inline ETYPE* \ | 76 | static inline ETYPE* \ |
77 | LTYPE ## _pop_front (LTYPE *l) \ | 77 | LTYPE ## _pop_front (LTYPE *l) \ |
78 | { \ | 78 | { \ |
79 | LTYPE *i = l->next; \ | 79 | LTYPE *i = l->next; \ |
80 | LTYPE ## _del (i->next, i->prev); \ | 80 | LTYPE ## _del (i->next, i->prev); \ |
81 | return LTYPE ## _entry (i); \ | 81 | return LTYPE ## _entry (i); \ |
82 | } \ | 82 | } \ |
83 | \ | 83 | \ |
84 | static inline int \ | 84 | static inline int \ |
85 | LTYPE ## _empty (LTYPE *l) \ | 85 | LTYPE ## _empty (LTYPE *l) \ |
86 | { \ | 86 | { \ |
87 | return l == l->next; \ | 87 | return l == l->next; \ |
88 | } \ | 88 | } \ |
89 | \ | 89 | \ |
90 | static inline ETYPE* \ | 90 | static inline ETYPE* \ |
91 | LTYPE ## _front (LTYPE *f) \ | 91 | LTYPE ## _front (LTYPE *f) \ |
92 | { \ | 92 | { \ |
93 | return LTYPE ## _entry (f->next); \ | 93 | return LTYPE ## _entry (f->next); \ |
94 | } \ | 94 | } \ |
95 | \ | 95 | \ |
96 | static inline ETYPE* \ | 96 | static inline ETYPE* \ |
97 | LTYPE ## _back (LTYPE *f) \ | 97 | LTYPE ## _back (LTYPE *f) \ |
98 | { \ | 98 | { \ |
99 | return LTYPE ## _entry (f->prev); \ | 99 | return LTYPE ## _entry (f->prev); \ |
100 | } \ | 100 | } \ |
101 | \ | 101 | \ |
102 | static inline int \ | 102 | static inline int \ |
103 | LTYPE ## _end (LTYPE *f, ETYPE *i) \ | 103 | LTYPE ## _end (LTYPE *f, ETYPE *i) \ |
104 | { \ | 104 | { \ |
105 | return f == & i->LNAME; \ | 105 | return f == & i->LNAME; \ |
106 | } \ | 106 | } \ |
107 | \ | 107 | \ |
108 | static inline ETYPE* \ | 108 | static inline ETYPE* \ |
109 | LTYPE ## _next (ETYPE *f) \ | 109 | LTYPE ## _next (ETYPE *f) \ |
110 | { \ | 110 | { \ |
111 | return LTYPE ## _entry (f->LNAME.next); \ | 111 | return LTYPE ## _entry (f->LNAME.next); \ |
112 | } \ | 112 | } \ |
113 | \ | 113 | \ |
114 | static inline int \ | 114 | static inline usize_t \ |
115 | LTYPE ## _length (LTYPE *l) \ | 115 | LTYPE ## _length (LTYPE *l) \ |
116 | { \ | 116 | { \ |
117 | LTYPE *p; \ | 117 | LTYPE *p; \ |
118 | int c = 0; \ | 118 | int c = 0; \ |
119 | \ | 119 | \ |
120 | for (p = l->next; p != l; p = p->next) \ | 120 | for (p = l->next; p != l; p = p->next) \ |
121 | { \ | 121 | { \ |
122 | c += 1; \ | 122 | c += 1; \ |
123 | } \ | 123 | } \ |
124 | \ | 124 | \ |
125 | return c; \ | 125 | return c; \ |
126 | } \ | 126 | } \ |
127 | \ | 127 | \ |
128 | typedef int unused_ ## LTYPE | 128 | typedef int unused_ ## LTYPE |
129 | 129 | ||
130 | #endif | 130 | #endif |
diff --git a/xdelta3/xdelta3-test.h b/xdelta3/xdelta3-test.h index c01f2e1..ee32565 100644 --- a/xdelta3/xdelta3-test.h +++ b/xdelta3/xdelta3-test.h | |||
@@ -2392,18 +2392,19 @@ xd3_selftest (void) | |||
2392 | DO_TEST (iopt_flush_instructions, 0, 0); | 2392 | DO_TEST (iopt_flush_instructions, 0, 0); |
2393 | DO_TEST (source_cksum_offset, 0, 0); | 2393 | DO_TEST (source_cksum_offset, 0, 0); |
2394 | 2394 | ||
2395 | IF_DJW (DO_TEST (secondary_huff, 0, DJW_MAX_GROUPS)); | ||
2396 | IF_FGK (DO_TEST (secondary_fgk, 0, 1)); | ||
2397 | |||
2398 | DO_TEST (decompress_single_bit_error, 0, 3); | 2395 | DO_TEST (decompress_single_bit_error, 0, 3); |
2399 | DO_TEST (decompress_single_bit_error, XD3_ADLER32, 3); | 2396 | DO_TEST (decompress_single_bit_error, XD3_ADLER32, 3); |
2400 | 2397 | ||
2401 | IF_FGK (DO_TEST (decompress_single_bit_error, XD3_SEC_FGK, 3)); | 2398 | IF_FGK (DO_TEST (decompress_single_bit_error, XD3_SEC_FGK, 3)); |
2402 | IF_DJW (DO_TEST (decompress_single_bit_error, XD3_SEC_DJW, 18)); | 2399 | IF_DJW (DO_TEST (decompress_single_bit_error, XD3_SEC_DJW, 17)); |
2403 | 2400 | ||
2404 | /* There are many expected non-failures for ALT_CODE_TABLE because | 2401 | /* There are many expected non-failures for ALT_CODE_TABLE because |
2405 | * not all of the instruction codes are used. */ | 2402 | * not all of the instruction codes are used. */ |
2406 | IF_GENCODETBL (DO_TEST (decompress_single_bit_error, XD3_ALT_CODE_TABLE, 224)); | 2403 | IF_GENCODETBL ( |
2404 | DO_TEST (decompress_single_bit_error, XD3_ALT_CODE_TABLE, 224)); | ||
2405 | |||
2406 | IF_DJW (DO_TEST (secondary_huff, 0, DJW_MAX_GROUPS)); | ||
2407 | IF_FGK (DO_TEST (secondary_fgk, 0, 1)); | ||
2407 | 2408 | ||
2408 | #ifndef WIN32 | 2409 | #ifndef WIN32 |
2409 | DO_TEST (force_behavior, 0, 0); | 2410 | DO_TEST (force_behavior, 0, 0); |
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 0f739f2..723a62a 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -2656,8 +2656,8 @@ xd3_set_appheader (xd3_stream *stream, | |||
2656 | static int | 2656 | static int |
2657 | xd3_iopt_check (xd3_stream *stream) | 2657 | xd3_iopt_check (xd3_stream *stream) |
2658 | { | 2658 | { |
2659 | int ul = xd3_rlist_length (& stream->iopt_used); | 2659 | usize_t ul = xd3_rlist_length (& stream->iopt_used); |
2660 | int fl = xd3_rlist_length (& stream->iopt_free); | 2660 | usize_t fl = xd3_rlist_length (& stream->iopt_free); |
2661 | 2661 | ||
2662 | return (ul + fl + (stream->iout ? 1 : 0)) == stream->iopt_size; | 2662 | return (ul + fl + (stream->iout ? 1 : 0)) == stream->iopt_size; |
2663 | } | 2663 | } |
@@ -3525,7 +3525,10 @@ xd3_encode_init (xd3_stream *stream) | |||
3525 | 3525 | ||
3526 | if (small_comp) | 3526 | if (small_comp) |
3527 | { | 3527 | { |
3528 | usize_t hash_values = min(stream->winsize, stream->sprevsz); | 3528 | /* TODO: This is under devel: used to have min(sprevsz) here, which sort |
3529 | * of makes sense, but observed fast performance w/ larger tables, which | ||
3530 | * also sort of makes sense. @@@ */ | ||
3531 | usize_t hash_values = stream->winsize; | ||
3529 | 3532 | ||
3530 | xd3_size_hashtable (stream, | 3533 | xd3_size_hashtable (stream, |
3531 | hash_values, | 3534 | hash_values, |
@@ -4579,7 +4582,7 @@ static int | |||
4579 | xd3_check_smatch (const uint8_t *ref0, const uint8_t *inp0, | 4582 | xd3_check_smatch (const uint8_t *ref0, const uint8_t *inp0, |
4580 | const uint8_t *inp_max, usize_t cmp_len) | 4583 | const uint8_t *inp_max, usize_t cmp_len) |
4581 | { | 4584 | { |
4582 | int i; | 4585 | usize_t i; |
4583 | 4586 | ||
4584 | for (i = 0; i < cmp_len; i += 1) | 4587 | for (i = 0; i < cmp_len; i += 1) |
4585 | { | 4588 | { |