Code

pretty-options.txt: tiny doc fix
[git.git] / diff-delta.c
1 /*
2  * diff-delta.c: generate a delta between two buffers
3  *
4  * This code was greatly inspired by parts of LibXDiff from Davide Libenzi
5  * http://www.xmailserver.org/xdiff-lib.html
6  *
7  * Rewritten for GIT by Nicolas Pitre <nico@cam.org>, (C) 2005-2007
8  *
9  * This code is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
14 #include "git-compat-util.h"
15 #include "delta.h"
17 /* maximum hash entry list for the same hash bucket */
18 #define HASH_LIMIT 64
20 #define RABIN_SHIFT 23
21 #define RABIN_WINDOW 16
23 static const unsigned int T[256] = {
24         0x00000000, 0xab59b4d1, 0x56b369a2, 0xfdeadd73, 0x063f6795, 0xad66d344,
25         0x508c0e37, 0xfbd5bae6, 0x0c7ecf2a, 0xa7277bfb, 0x5acda688, 0xf1941259,
26         0x0a41a8bf, 0xa1181c6e, 0x5cf2c11d, 0xf7ab75cc, 0x18fd9e54, 0xb3a42a85,
27         0x4e4ef7f6, 0xe5174327, 0x1ec2f9c1, 0xb59b4d10, 0x48719063, 0xe32824b2,
28         0x1483517e, 0xbfdae5af, 0x423038dc, 0xe9698c0d, 0x12bc36eb, 0xb9e5823a,
29         0x440f5f49, 0xef56eb98, 0x31fb3ca8, 0x9aa28879, 0x6748550a, 0xcc11e1db,
30         0x37c45b3d, 0x9c9defec, 0x6177329f, 0xca2e864e, 0x3d85f382, 0x96dc4753,
31         0x6b369a20, 0xc06f2ef1, 0x3bba9417, 0x90e320c6, 0x6d09fdb5, 0xc6504964,
32         0x2906a2fc, 0x825f162d, 0x7fb5cb5e, 0xd4ec7f8f, 0x2f39c569, 0x846071b8,
33         0x798aaccb, 0xd2d3181a, 0x25786dd6, 0x8e21d907, 0x73cb0474, 0xd892b0a5,
34         0x23470a43, 0x881ebe92, 0x75f463e1, 0xdeadd730, 0x63f67950, 0xc8afcd81,
35         0x354510f2, 0x9e1ca423, 0x65c91ec5, 0xce90aa14, 0x337a7767, 0x9823c3b6,
36         0x6f88b67a, 0xc4d102ab, 0x393bdfd8, 0x92626b09, 0x69b7d1ef, 0xc2ee653e,
37         0x3f04b84d, 0x945d0c9c, 0x7b0be704, 0xd05253d5, 0x2db88ea6, 0x86e13a77,
38         0x7d348091, 0xd66d3440, 0x2b87e933, 0x80de5de2, 0x7775282e, 0xdc2c9cff,
39         0x21c6418c, 0x8a9ff55d, 0x714a4fbb, 0xda13fb6a, 0x27f92619, 0x8ca092c8,
40         0x520d45f8, 0xf954f129, 0x04be2c5a, 0xafe7988b, 0x5432226d, 0xff6b96bc,
41         0x02814bcf, 0xa9d8ff1e, 0x5e738ad2, 0xf52a3e03, 0x08c0e370, 0xa39957a1,
42         0x584ced47, 0xf3155996, 0x0eff84e5, 0xa5a63034, 0x4af0dbac, 0xe1a96f7d,
43         0x1c43b20e, 0xb71a06df, 0x4ccfbc39, 0xe79608e8, 0x1a7cd59b, 0xb125614a,
44         0x468e1486, 0xedd7a057, 0x103d7d24, 0xbb64c9f5, 0x40b17313, 0xebe8c7c2,
45         0x16021ab1, 0xbd5bae60, 0x6cb54671, 0xc7ecf2a0, 0x3a062fd3, 0x915f9b02,
46         0x6a8a21e4, 0xc1d39535, 0x3c394846, 0x9760fc97, 0x60cb895b, 0xcb923d8a,
47         0x3678e0f9, 0x9d215428, 0x66f4eece, 0xcdad5a1f, 0x3047876c, 0x9b1e33bd,
48         0x7448d825, 0xdf116cf4, 0x22fbb187, 0x89a20556, 0x7277bfb0, 0xd92e0b61,
49         0x24c4d612, 0x8f9d62c3, 0x7836170f, 0xd36fa3de, 0x2e857ead, 0x85dcca7c,
50         0x7e09709a, 0xd550c44b, 0x28ba1938, 0x83e3ade9, 0x5d4e7ad9, 0xf617ce08,
51         0x0bfd137b, 0xa0a4a7aa, 0x5b711d4c, 0xf028a99d, 0x0dc274ee, 0xa69bc03f,
52         0x5130b5f3, 0xfa690122, 0x0783dc51, 0xacda6880, 0x570fd266, 0xfc5666b7,
53         0x01bcbbc4, 0xaae50f15, 0x45b3e48d, 0xeeea505c, 0x13008d2f, 0xb85939fe,
54         0x438c8318, 0xe8d537c9, 0x153feaba, 0xbe665e6b, 0x49cd2ba7, 0xe2949f76,
55         0x1f7e4205, 0xb427f6d4, 0x4ff24c32, 0xe4abf8e3, 0x19412590, 0xb2189141,
56         0x0f433f21, 0xa41a8bf0, 0x59f05683, 0xf2a9e252, 0x097c58b4, 0xa225ec65,
57         0x5fcf3116, 0xf49685c7, 0x033df00b, 0xa86444da, 0x558e99a9, 0xfed72d78,
58         0x0502979e, 0xae5b234f, 0x53b1fe3c, 0xf8e84aed, 0x17bea175, 0xbce715a4,
59         0x410dc8d7, 0xea547c06, 0x1181c6e0, 0xbad87231, 0x4732af42, 0xec6b1b93,
60         0x1bc06e5f, 0xb099da8e, 0x4d7307fd, 0xe62ab32c, 0x1dff09ca, 0xb6a6bd1b,
61         0x4b4c6068, 0xe015d4b9, 0x3eb80389, 0x95e1b758, 0x680b6a2b, 0xc352defa,
62         0x3887641c, 0x93ded0cd, 0x6e340dbe, 0xc56db96f, 0x32c6cca3, 0x999f7872,
63         0x6475a501, 0xcf2c11d0, 0x34f9ab36, 0x9fa01fe7, 0x624ac294, 0xc9137645,
64         0x26459ddd, 0x8d1c290c, 0x70f6f47f, 0xdbaf40ae, 0x207afa48, 0x8b234e99,
65         0x76c993ea, 0xdd90273b, 0x2a3b52f7, 0x8162e626, 0x7c883b55, 0xd7d18f84,
66         0x2c043562, 0x875d81b3, 0x7ab75cc0, 0xd1eee811
67 };
69 static const unsigned int U[256] = {
70         0x00000000, 0x7eb5200d, 0x5633f4cb, 0x2886d4c6, 0x073e5d47, 0x798b7d4a,
71         0x510da98c, 0x2fb88981, 0x0e7cba8e, 0x70c99a83, 0x584f4e45, 0x26fa6e48,
72         0x0942e7c9, 0x77f7c7c4, 0x5f711302, 0x21c4330f, 0x1cf9751c, 0x624c5511,
73         0x4aca81d7, 0x347fa1da, 0x1bc7285b, 0x65720856, 0x4df4dc90, 0x3341fc9d,
74         0x1285cf92, 0x6c30ef9f, 0x44b63b59, 0x3a031b54, 0x15bb92d5, 0x6b0eb2d8,
75         0x4388661e, 0x3d3d4613, 0x39f2ea38, 0x4747ca35, 0x6fc11ef3, 0x11743efe,
76         0x3eccb77f, 0x40799772, 0x68ff43b4, 0x164a63b9, 0x378e50b6, 0x493b70bb,
77         0x61bda47d, 0x1f088470, 0x30b00df1, 0x4e052dfc, 0x6683f93a, 0x1836d937,
78         0x250b9f24, 0x5bbebf29, 0x73386bef, 0x0d8d4be2, 0x2235c263, 0x5c80e26e,
79         0x740636a8, 0x0ab316a5, 0x2b7725aa, 0x55c205a7, 0x7d44d161, 0x03f1f16c,
80         0x2c4978ed, 0x52fc58e0, 0x7a7a8c26, 0x04cfac2b, 0x73e5d470, 0x0d50f47d,
81         0x25d620bb, 0x5b6300b6, 0x74db8937, 0x0a6ea93a, 0x22e87dfc, 0x5c5d5df1,
82         0x7d996efe, 0x032c4ef3, 0x2baa9a35, 0x551fba38, 0x7aa733b9, 0x041213b4,
83         0x2c94c772, 0x5221e77f, 0x6f1ca16c, 0x11a98161, 0x392f55a7, 0x479a75aa,
84         0x6822fc2b, 0x1697dc26, 0x3e1108e0, 0x40a428ed, 0x61601be2, 0x1fd53bef,
85         0x3753ef29, 0x49e6cf24, 0x665e46a5, 0x18eb66a8, 0x306db26e, 0x4ed89263,
86         0x4a173e48, 0x34a21e45, 0x1c24ca83, 0x6291ea8e, 0x4d29630f, 0x339c4302,
87         0x1b1a97c4, 0x65afb7c9, 0x446b84c6, 0x3adea4cb, 0x1258700d, 0x6ced5000,
88         0x4355d981, 0x3de0f98c, 0x15662d4a, 0x6bd30d47, 0x56ee4b54, 0x285b6b59,
89         0x00ddbf9f, 0x7e689f92, 0x51d01613, 0x2f65361e, 0x07e3e2d8, 0x7956c2d5,
90         0x5892f1da, 0x2627d1d7, 0x0ea10511, 0x7014251c, 0x5facac9d, 0x21198c90,
91         0x099f5856, 0x772a785b, 0x4c921c31, 0x32273c3c, 0x1aa1e8fa, 0x6414c8f7,
92         0x4bac4176, 0x3519617b, 0x1d9fb5bd, 0x632a95b0, 0x42eea6bf, 0x3c5b86b2,
93         0x14dd5274, 0x6a687279, 0x45d0fbf8, 0x3b65dbf5, 0x13e30f33, 0x6d562f3e,
94         0x506b692d, 0x2ede4920, 0x06589de6, 0x78edbdeb, 0x5755346a, 0x29e01467,
95         0x0166c0a1, 0x7fd3e0ac, 0x5e17d3a3, 0x20a2f3ae, 0x08242768, 0x76910765,
96         0x59298ee4, 0x279caee9, 0x0f1a7a2f, 0x71af5a22, 0x7560f609, 0x0bd5d604,
97         0x235302c2, 0x5de622cf, 0x725eab4e, 0x0ceb8b43, 0x246d5f85, 0x5ad87f88,
98         0x7b1c4c87, 0x05a96c8a, 0x2d2fb84c, 0x539a9841, 0x7c2211c0, 0x029731cd,
99         0x2a11e50b, 0x54a4c506, 0x69998315, 0x172ca318, 0x3faa77de, 0x411f57d3,
100         0x6ea7de52, 0x1012fe5f, 0x38942a99, 0x46210a94, 0x67e5399b, 0x19501996,
101         0x31d6cd50, 0x4f63ed5d, 0x60db64dc, 0x1e6e44d1, 0x36e89017, 0x485db01a,
102         0x3f77c841, 0x41c2e84c, 0x69443c8a, 0x17f11c87, 0x38499506, 0x46fcb50b,
103         0x6e7a61cd, 0x10cf41c0, 0x310b72cf, 0x4fbe52c2, 0x67388604, 0x198da609,
104         0x36352f88, 0x48800f85, 0x6006db43, 0x1eb3fb4e, 0x238ebd5d, 0x5d3b9d50,
105         0x75bd4996, 0x0b08699b, 0x24b0e01a, 0x5a05c017, 0x728314d1, 0x0c3634dc,
106         0x2df207d3, 0x534727de, 0x7bc1f318, 0x0574d315, 0x2acc5a94, 0x54797a99,
107         0x7cffae5f, 0x024a8e52, 0x06852279, 0x78300274, 0x50b6d6b2, 0x2e03f6bf,
108         0x01bb7f3e, 0x7f0e5f33, 0x57888bf5, 0x293dabf8, 0x08f998f7, 0x764cb8fa,
109         0x5eca6c3c, 0x207f4c31, 0x0fc7c5b0, 0x7172e5bd, 0x59f4317b, 0x27411176,
110         0x1a7c5765, 0x64c97768, 0x4c4fa3ae, 0x32fa83a3, 0x1d420a22, 0x63f72a2f,
111         0x4b71fee9, 0x35c4dee4, 0x1400edeb, 0x6ab5cde6, 0x42331920, 0x3c86392d,
112         0x133eb0ac, 0x6d8b90a1, 0x450d4467, 0x3bb8646a
113 };
115 struct index_entry {
116         const unsigned char *ptr;
117         unsigned int val;
118         struct index_entry *next;
119 };
121 struct delta_index {
122         unsigned long memsize;
123         const void *src_buf;
124         unsigned long src_size;
125         unsigned int hash_mask;
126         struct index_entry *hash[FLEX_ARRAY];
127 };
129 struct delta_index * create_delta_index(const void *buf, unsigned long bufsize)
131         unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
132         const unsigned char *data, *buffer = buf;
133         struct delta_index *index;
134         struct index_entry *entry, **hash;
135         void *mem;
136         unsigned long memsize;
138         if (!buf || !bufsize)
139                 return NULL;
141         /* Determine index hash size.  Note that indexing skips the
142            first byte to allow for optimizing the Rabin's polynomial
143            initialization in create_delta(). */
144         entries = (bufsize - 1)  / RABIN_WINDOW;
145         hsize = entries / 4;
146         for (i = 4; (1u << i) < hsize && i < 31; i++);
147         hsize = 1 << i;
148         hmask = hsize - 1;
150         /* allocate lookup index */
151         memsize = sizeof(*index) +
152                   sizeof(*hash) * hsize +
153                   sizeof(*entry) * entries;
154         mem = malloc(memsize);
155         if (!mem)
156                 return NULL;
157         index = mem;
158         mem = index + 1;
159         hash = mem;
160         mem = hash + hsize;
161         entry = mem;
163         index->memsize = memsize;
164         index->src_buf = buf;
165         index->src_size = bufsize;
166         index->hash_mask = hmask;
167         memset(hash, 0, hsize * sizeof(*hash));
169         /* allocate an array to count hash entries */
170         hash_count = calloc(hsize, sizeof(*hash_count));
171         if (!hash_count) {
172                 free(index);
173                 return NULL;
174         }
176         /* then populate the index */
177         prev_val = ~0;
178         for (data = buffer + entries * RABIN_WINDOW - RABIN_WINDOW;
179              data >= buffer;
180              data -= RABIN_WINDOW) {
181                 unsigned int val = 0;
182                 for (i = 1; i <= RABIN_WINDOW; i++)
183                         val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
184                 if (val == prev_val) {
185                         /* keep the lowest of consecutive identical blocks */
186                         entry[-1].ptr = data + RABIN_WINDOW;
187                 } else {
188                         prev_val = val;
189                         i = val & hmask;
190                         entry->ptr = data + RABIN_WINDOW;
191                         entry->val = val;
192                         entry->next = hash[i];
193                         hash[i] = entry++;
194                         hash_count[i]++;
195                 }
196         }
198         /*
199          * Determine a limit on the number of entries in the same hash
200          * bucket.  This guards us against pathological data sets causing
201          * really bad hash distribution with most entries in the same hash
202          * bucket that would bring us to O(m*n) computing costs (m and n
203          * corresponding to reference and target buffer sizes).
204          *
205          * Make sure none of the hash buckets has more entries than
206          * we're willing to test.  Otherwise we cull the entry list
207          * uniformly to still preserve a good repartition across
208          * the reference buffer.
209          */
210         for (i = 0; i < hsize; i++) {
211                 if (hash_count[i] < HASH_LIMIT)
212                         continue;
213                 entry = hash[i];
214                 do {
215                         struct index_entry *keep = entry;
216                         int skip = hash_count[i] / HASH_LIMIT / 2;
217                         do {
218                                 entry = entry->next;
219                         } while(--skip && entry);
220                         keep->next = entry;
221                 } while(entry);
222         }
223         free(hash_count);
225         return index;
228 void free_delta_index(struct delta_index *index)
230         free(index);
233 unsigned long sizeof_delta_index(struct delta_index *index)
235         if (index)
236                 return index->memsize;
237         else
238                 return 0;
241 /*
242  * The maximum size for any opcode sequence, including the initial header
243  * plus Rabin window plus biggest copy.
244  */
245 #define MAX_OP_SIZE     (5 + 5 + 1 + RABIN_WINDOW + 7)
247 void *
248 create_delta(const struct delta_index *index,
249              const void *trg_buf, unsigned long trg_size,
250              unsigned long *delta_size, unsigned long max_size)
252         unsigned int i, outpos, outsize, moff, msize, val;
253         int inscnt;
254         const unsigned char *ref_data, *ref_top, *data, *top;
255         unsigned char *out;
257         if (!trg_buf || !trg_size)
258                 return NULL;
260         outpos = 0;
261         outsize = 8192;
262         if (max_size && outsize >= max_size)
263                 outsize = max_size + MAX_OP_SIZE + 1;
264         out = malloc(outsize);
265         if (!out)
266                 return NULL;
268         /* store reference buffer size */
269         i = index->src_size;
270         while (i >= 0x80) {
271                 out[outpos++] = i | 0x80;
272                 i >>= 7;
273         }
274         out[outpos++] = i;
276         /* store target buffer size */
277         i = trg_size;
278         while (i >= 0x80) {
279                 out[outpos++] = i | 0x80;
280                 i >>= 7;
281         }
282         out[outpos++] = i;
284         ref_data = index->src_buf;
285         ref_top = ref_data + index->src_size;
286         data = trg_buf;
287         top = (const unsigned char *) trg_buf + trg_size;
289         outpos++;
290         val = 0;
291         for (i = 0; i < RABIN_WINDOW && data < top; i++, data++) {
292                 out[outpos++] = *data;
293                 val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
294         }
295         inscnt = i;
297         moff = 0;
298         msize = 0;
299         while (data < top) {
300                 if (msize < 4096) {
301                         struct index_entry *entry;
302                         val ^= U[data[-RABIN_WINDOW]];
303                         val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
304                         i = val & index->hash_mask;
305                         for (entry = index->hash[i]; entry; entry = entry->next) {
306                                 const unsigned char *ref = entry->ptr;
307                                 const unsigned char *src = data;
308                                 unsigned int ref_size = ref_top - ref;
309                                 if (entry->val != val)
310                                         continue;
311                                 if (ref_size > top - src)
312                                         ref_size = top - src;
313                                 if (ref_size <= msize)
314                                         break;
315                                 while (ref_size-- && *src++ == *ref)
316                                         ref++;
317                                 if (msize < ref - entry->ptr) {
318                                         /* this is our best match so far */
319                                         msize = ref - entry->ptr;
320                                         moff = entry->ptr - ref_data;
321                                         if (msize >= 4096) /* good enough */
322                                                 break;
323                                 }
324                         }
325                 }
327                 if (msize < 4) {
328                         if (!inscnt)
329                                 outpos++;
330                         out[outpos++] = *data++;
331                         inscnt++;
332                         if (inscnt == 0x7f) {
333                                 out[outpos - inscnt - 1] = inscnt;
334                                 inscnt = 0;
335                         }
336                         msize = 0;
337                 } else {
338                         unsigned int left;
339                         unsigned char *op;
341                         if (inscnt) {
342                                 while (moff && ref_data[moff-1] == data[-1]) {
343                                         /* we can match one byte back */
344                                         msize++;
345                                         moff--;
346                                         data--;
347                                         outpos--;
348                                         if (--inscnt)
349                                                 continue;
350                                         outpos--;  /* remove count slot */
351                                         inscnt--;  /* make it -1 */
352                                         break;
353                                 }
354                                 out[outpos - inscnt - 1] = inscnt;
355                                 inscnt = 0;
356                         }
358                         /* A copy op is currently limited to 64KB (pack v2) */
359                         left = (msize < 0x10000) ? 0 : (msize - 0x10000);
360                         msize -= left;
362                         op = out + outpos++;
363                         i = 0x80;
365                         if (moff & 0x000000ff)
366                                 out[outpos++] = moff >> 0,  i |= 0x01;
367                         if (moff & 0x0000ff00)
368                                 out[outpos++] = moff >> 8,  i |= 0x02;
369                         if (moff & 0x00ff0000)
370                                 out[outpos++] = moff >> 16, i |= 0x04;
371                         if (moff & 0xff000000)
372                                 out[outpos++] = moff >> 24, i |= 0x08;
374                         if (msize & 0x00ff)
375                                 out[outpos++] = msize >> 0, i |= 0x10;
376                         if (msize & 0xff00)
377                                 out[outpos++] = msize >> 8, i |= 0x20;
379                         *op = i;
381                         data += msize;
382                         moff += msize;
383                         msize = left;
385                         if (msize < 4096) {
386                                 int j;
387                                 val = 0;
388                                 for (j = -RABIN_WINDOW; j < 0; j++)
389                                         val = ((val << 8) | data[j])
390                                               ^ T[val >> RABIN_SHIFT];
391                         }
392                 }
394                 if (outpos >= outsize - MAX_OP_SIZE) {
395                         void *tmp = out;
396                         outsize = outsize * 3 / 2;
397                         if (max_size && outsize >= max_size)
398                                 outsize = max_size + MAX_OP_SIZE + 1;
399                         if (max_size && outpos > max_size)
400                                 break;
401                         out = realloc(out, outsize);
402                         if (!out) {
403                                 free(tmp);
404                                 return NULL;
405                         }
406                 }
407         }
409         if (inscnt)
410                 out[outpos - inscnt - 1] = inscnt;
412         if (max_size && outpos > max_size) {
413                 free(out);
414                 return NULL;
415         }
417         *delta_size = outpos;
418         return out;