|
20 | 20 |
|
21 | 21 | #include <stdlib.h> |
22 | 22 | #include <string.h> |
23 | | -#include <zlib.h> |
24 | 23 | #include "delta.h" |
25 | 24 |
|
26 | 25 |
|
27 | | -/* block size: min = 16, max = 64k, power of 2 */ |
28 | | -#define BLK_SIZE 16 |
29 | | - |
30 | | -#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
31 | | - |
32 | | -#define GR_PRIME 0x9e370001 |
33 | | -#define HASH(v, shift) (((unsigned int)(v) * GR_PRIME) >> (shift)) |
34 | | - |
35 | 26 | struct index { |
36 | 27 | const unsigned char *ptr; |
37 | | - unsigned int val; |
38 | 28 | struct index *next; |
39 | 29 | }; |
40 | 30 |
|
41 | 31 | static struct index ** delta_index(const unsigned char *buf, |
42 | 32 | unsigned long bufsize, |
43 | 33 | unsigned int *hash_shift) |
44 | 34 | { |
45 | | - unsigned int hsize, hshift, entries, blksize, i; |
| 35 | + unsigned long hsize; |
| 36 | + unsigned int hshift, i; |
46 | 37 | const unsigned char *data; |
47 | 38 | struct index *entry, **hash; |
48 | 39 | void *mem; |
49 | 40 |
|
50 | 41 | /* determine index hash size */ |
51 | | - entries = (bufsize + BLK_SIZE - 1) / BLK_SIZE; |
52 | | - hsize = entries / 4; |
53 | | - for (i = 4; (1 << i) < hsize && i < 16; i++); |
| 42 | + hsize = bufsize / 4; |
| 43 | + for (i = 8; (1 << i) < hsize && i < 16; i++); |
54 | 44 | hsize = 1 << i; |
55 | | - hshift = 32 - i; |
| 45 | + hshift = i - 8; |
56 | 46 | *hash_shift = hshift; |
57 | 47 |
|
58 | 48 | /* allocate lookup index */ |
59 | | - mem = malloc(hsize * sizeof(*hash) + entries * sizeof(*entry)); |
| 49 | + mem = malloc(hsize * sizeof(*hash) + bufsize * sizeof(*entry)); |
60 | 50 | if (!mem) |
61 | 51 | return NULL; |
62 | 52 | hash = mem; |
63 | 53 | entry = mem + hsize * sizeof(*hash); |
64 | 54 | memset(hash, 0, hsize * sizeof(*hash)); |
65 | 55 |
|
66 | 56 | /* then populate it */ |
67 | | - data = buf + entries * BLK_SIZE - BLK_SIZE; |
68 | | - blksize = bufsize - (data - buf); |
69 | | - while (data >= buf) { |
70 | | - unsigned int val = adler32(0, data, blksize); |
71 | | - i = HASH(val, hshift); |
72 | | - entry->ptr = data; |
73 | | - entry->val = val; |
| 57 | + data = buf + bufsize - 2; |
| 58 | + while (data > buf) { |
| 59 | + entry->ptr = --data; |
| 60 | + i = data[0] ^ data[1] ^ (data[2] << hshift); |
74 | 61 | entry->next = hash[i]; |
75 | 62 | hash[i] = entry++; |
76 | | - blksize = BLK_SIZE; |
77 | | - data -= BLK_SIZE; |
78 | 63 | } |
79 | 64 |
|
80 | 65 | return hash; |
@@ -141,29 +126,27 @@ void *diff_delta(void *from_buf, unsigned long from_size, |
141 | 126 |
|
142 | 127 | while (data < top) { |
143 | 128 | unsigned int moff = 0, msize = 0; |
144 | | - unsigned int blksize = MIN(top - data, BLK_SIZE); |
145 | | - unsigned int val = adler32(0, data, blksize); |
146 | | - i = HASH(val, hash_shift); |
147 | | - for (entry = hash[i]; entry; entry = entry->next) { |
148 | | - const unsigned char *ref = entry->ptr; |
149 | | - const unsigned char *src = data; |
150 | | - unsigned int ref_size = ref_top - ref; |
151 | | - if (entry->val != val) |
152 | | - continue; |
153 | | - if (ref_size > top - src) |
154 | | - ref_size = top - src; |
155 | | - while (ref_size && *src++ == *ref) { |
156 | | - ref++; |
157 | | - ref_size--; |
158 | | - } |
159 | | - ref_size = ref - entry->ptr; |
160 | | - if (ref_size > msize) { |
161 | | - /* this is our best match so far */ |
162 | | - moff = entry->ptr - ref_data; |
163 | | - msize = ref_size; |
164 | | - if (msize >= 0x10000) { |
165 | | - msize = 0x10000; |
| 129 | + if (data + 2 < top) { |
| 130 | + i = data[0] ^ data[1] ^ (data[2] << hash_shift); |
| 131 | + for (entry = hash[i]; entry; entry = entry->next) { |
| 132 | + const unsigned char *ref = entry->ptr; |
| 133 | + const unsigned char *src = data; |
| 134 | + unsigned int ref_size = ref_top - ref; |
| 135 | + if (ref_size > top - src) |
| 136 | + ref_size = top - src; |
| 137 | + if (ref_size > 0x10000) |
| 138 | + ref_size = 0x10000; |
| 139 | + if (ref_size <= msize) |
166 | 140 | break; |
| 141 | + while (ref_size && *src++ == *ref) { |
| 142 | + ref++; |
| 143 | + ref_size--; |
| 144 | + } |
| 145 | + ref_size = ref - entry->ptr; |
| 146 | + if (msize < ref - entry->ptr) { |
| 147 | + /* this is our best match so far */ |
| 148 | + msize = ref - entry->ptr; |
| 149 | + moff = entry->ptr - ref_data; |
167 | 150 | } |
168 | 151 | } |
169 | 152 | } |
|
0 commit comments