/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/bzr/diff-delta.c

  • Committer: Jelmer Vernooij
  • Date: 2020-07-18 23:14:00 UTC
  • mfrom: (7490.40.62 work)
  • mto: This revision was merged to the branch mainline in revision 7519.
  • Revision ID: jelmer@jelmer.uk-20200718231400-jaes9qltn8oi8xss
Merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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@fluxnic.net>, (C) 2005-2007
 
8
 * Adapted for Bazaar by John Arbash Meinel <john@arbash-meinel.com> (C) 2009
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License as published by
 
12
 * the Free Software Foundation; either version 2 of the License, or
 
13
 * (at your option) any later version.
 
14
 *
 
15
 * NB: The version in GIT is 'version 2 of the Licence only', however Nicolas
 
16
 * has granted permission for use under 'version 2 or later' in private email
 
17
 * to Robert Collins and Karl Fogel on the 6th April 2009.
 
18
 */
 
19
 
 
20
#include <stdio.h>
 
21
 
 
22
#include "delta.h"
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <assert.h>
 
26
 
 
27
/* maximum hash entry list for the same hash bucket */
 
28
#define HASH_LIMIT 64
 
29
 
 
30
#define RABIN_SHIFT 23
 
31
#define RABIN_WINDOW 16
 
32
 
 
33
/* The hash map is sized to put 4 entries per bucket, this gives us ~even room
 
34
 * for more data. Tweaking this number above 4 doesn't seem to help much,
 
35
 * anyway.
 
36
 */
 
37
#define EXTRA_NULLS 4
 
38
 
 
39
static const unsigned int T[256] = {
 
40
    0x00000000, 0xab59b4d1, 0x56b369a2, 0xfdeadd73, 0x063f6795, 0xad66d344,
 
41
    0x508c0e37, 0xfbd5bae6, 0x0c7ecf2a, 0xa7277bfb, 0x5acda688, 0xf1941259,
 
42
    0x0a41a8bf, 0xa1181c6e, 0x5cf2c11d, 0xf7ab75cc, 0x18fd9e54, 0xb3a42a85,
 
43
    0x4e4ef7f6, 0xe5174327, 0x1ec2f9c1, 0xb59b4d10, 0x48719063, 0xe32824b2,
 
44
    0x1483517e, 0xbfdae5af, 0x423038dc, 0xe9698c0d, 0x12bc36eb, 0xb9e5823a,
 
45
    0x440f5f49, 0xef56eb98, 0x31fb3ca8, 0x9aa28879, 0x6748550a, 0xcc11e1db,
 
46
    0x37c45b3d, 0x9c9defec, 0x6177329f, 0xca2e864e, 0x3d85f382, 0x96dc4753,
 
47
    0x6b369a20, 0xc06f2ef1, 0x3bba9417, 0x90e320c6, 0x6d09fdb5, 0xc6504964,
 
48
    0x2906a2fc, 0x825f162d, 0x7fb5cb5e, 0xd4ec7f8f, 0x2f39c569, 0x846071b8,
 
49
    0x798aaccb, 0xd2d3181a, 0x25786dd6, 0x8e21d907, 0x73cb0474, 0xd892b0a5,
 
50
    0x23470a43, 0x881ebe92, 0x75f463e1, 0xdeadd730, 0x63f67950, 0xc8afcd81,
 
51
    0x354510f2, 0x9e1ca423, 0x65c91ec5, 0xce90aa14, 0x337a7767, 0x9823c3b6,
 
52
    0x6f88b67a, 0xc4d102ab, 0x393bdfd8, 0x92626b09, 0x69b7d1ef, 0xc2ee653e,
 
53
    0x3f04b84d, 0x945d0c9c, 0x7b0be704, 0xd05253d5, 0x2db88ea6, 0x86e13a77,
 
54
    0x7d348091, 0xd66d3440, 0x2b87e933, 0x80de5de2, 0x7775282e, 0xdc2c9cff,
 
55
    0x21c6418c, 0x8a9ff55d, 0x714a4fbb, 0xda13fb6a, 0x27f92619, 0x8ca092c8,
 
56
    0x520d45f8, 0xf954f129, 0x04be2c5a, 0xafe7988b, 0x5432226d, 0xff6b96bc,
 
57
    0x02814bcf, 0xa9d8ff1e, 0x5e738ad2, 0xf52a3e03, 0x08c0e370, 0xa39957a1,
 
58
    0x584ced47, 0xf3155996, 0x0eff84e5, 0xa5a63034, 0x4af0dbac, 0xe1a96f7d,
 
59
    0x1c43b20e, 0xb71a06df, 0x4ccfbc39, 0xe79608e8, 0x1a7cd59b, 0xb125614a,
 
60
    0x468e1486, 0xedd7a057, 0x103d7d24, 0xbb64c9f5, 0x40b17313, 0xebe8c7c2,
 
61
    0x16021ab1, 0xbd5bae60, 0x6cb54671, 0xc7ecf2a0, 0x3a062fd3, 0x915f9b02,
 
62
    0x6a8a21e4, 0xc1d39535, 0x3c394846, 0x9760fc97, 0x60cb895b, 0xcb923d8a,
 
63
    0x3678e0f9, 0x9d215428, 0x66f4eece, 0xcdad5a1f, 0x3047876c, 0x9b1e33bd,
 
64
    0x7448d825, 0xdf116cf4, 0x22fbb187, 0x89a20556, 0x7277bfb0, 0xd92e0b61,
 
65
    0x24c4d612, 0x8f9d62c3, 0x7836170f, 0xd36fa3de, 0x2e857ead, 0x85dcca7c,
 
66
    0x7e09709a, 0xd550c44b, 0x28ba1938, 0x83e3ade9, 0x5d4e7ad9, 0xf617ce08,
 
67
    0x0bfd137b, 0xa0a4a7aa, 0x5b711d4c, 0xf028a99d, 0x0dc274ee, 0xa69bc03f,
 
68
    0x5130b5f3, 0xfa690122, 0x0783dc51, 0xacda6880, 0x570fd266, 0xfc5666b7,
 
69
    0x01bcbbc4, 0xaae50f15, 0x45b3e48d, 0xeeea505c, 0x13008d2f, 0xb85939fe,
 
70
    0x438c8318, 0xe8d537c9, 0x153feaba, 0xbe665e6b, 0x49cd2ba7, 0xe2949f76,
 
71
    0x1f7e4205, 0xb427f6d4, 0x4ff24c32, 0xe4abf8e3, 0x19412590, 0xb2189141,
 
72
    0x0f433f21, 0xa41a8bf0, 0x59f05683, 0xf2a9e252, 0x097c58b4, 0xa225ec65,
 
73
    0x5fcf3116, 0xf49685c7, 0x033df00b, 0xa86444da, 0x558e99a9, 0xfed72d78,
 
74
    0x0502979e, 0xae5b234f, 0x53b1fe3c, 0xf8e84aed, 0x17bea175, 0xbce715a4,
 
75
    0x410dc8d7, 0xea547c06, 0x1181c6e0, 0xbad87231, 0x4732af42, 0xec6b1b93,
 
76
    0x1bc06e5f, 0xb099da8e, 0x4d7307fd, 0xe62ab32c, 0x1dff09ca, 0xb6a6bd1b,
 
77
    0x4b4c6068, 0xe015d4b9, 0x3eb80389, 0x95e1b758, 0x680b6a2b, 0xc352defa,
 
78
    0x3887641c, 0x93ded0cd, 0x6e340dbe, 0xc56db96f, 0x32c6cca3, 0x999f7872,
 
79
    0x6475a501, 0xcf2c11d0, 0x34f9ab36, 0x9fa01fe7, 0x624ac294, 0xc9137645,
 
80
    0x26459ddd, 0x8d1c290c, 0x70f6f47f, 0xdbaf40ae, 0x207afa48, 0x8b234e99,
 
81
    0x76c993ea, 0xdd90273b, 0x2a3b52f7, 0x8162e626, 0x7c883b55, 0xd7d18f84,
 
82
    0x2c043562, 0x875d81b3, 0x7ab75cc0, 0xd1eee811
 
83
};
 
84
 
 
85
static const unsigned int U[256] = {
 
86
    0x00000000, 0x7eb5200d, 0x5633f4cb, 0x2886d4c6, 0x073e5d47, 0x798b7d4a,
 
87
    0x510da98c, 0x2fb88981, 0x0e7cba8e, 0x70c99a83, 0x584f4e45, 0x26fa6e48,
 
88
    0x0942e7c9, 0x77f7c7c4, 0x5f711302, 0x21c4330f, 0x1cf9751c, 0x624c5511,
 
89
    0x4aca81d7, 0x347fa1da, 0x1bc7285b, 0x65720856, 0x4df4dc90, 0x3341fc9d,
 
90
    0x1285cf92, 0x6c30ef9f, 0x44b63b59, 0x3a031b54, 0x15bb92d5, 0x6b0eb2d8,
 
91
    0x4388661e, 0x3d3d4613, 0x39f2ea38, 0x4747ca35, 0x6fc11ef3, 0x11743efe,
 
92
    0x3eccb77f, 0x40799772, 0x68ff43b4, 0x164a63b9, 0x378e50b6, 0x493b70bb,
 
93
    0x61bda47d, 0x1f088470, 0x30b00df1, 0x4e052dfc, 0x6683f93a, 0x1836d937,
 
94
    0x250b9f24, 0x5bbebf29, 0x73386bef, 0x0d8d4be2, 0x2235c263, 0x5c80e26e,
 
95
    0x740636a8, 0x0ab316a5, 0x2b7725aa, 0x55c205a7, 0x7d44d161, 0x03f1f16c,
 
96
    0x2c4978ed, 0x52fc58e0, 0x7a7a8c26, 0x04cfac2b, 0x73e5d470, 0x0d50f47d,
 
97
    0x25d620bb, 0x5b6300b6, 0x74db8937, 0x0a6ea93a, 0x22e87dfc, 0x5c5d5df1,
 
98
    0x7d996efe, 0x032c4ef3, 0x2baa9a35, 0x551fba38, 0x7aa733b9, 0x041213b4,
 
99
    0x2c94c772, 0x5221e77f, 0x6f1ca16c, 0x11a98161, 0x392f55a7, 0x479a75aa,
 
100
    0x6822fc2b, 0x1697dc26, 0x3e1108e0, 0x40a428ed, 0x61601be2, 0x1fd53bef,
 
101
    0x3753ef29, 0x49e6cf24, 0x665e46a5, 0x18eb66a8, 0x306db26e, 0x4ed89263,
 
102
    0x4a173e48, 0x34a21e45, 0x1c24ca83, 0x6291ea8e, 0x4d29630f, 0x339c4302,
 
103
    0x1b1a97c4, 0x65afb7c9, 0x446b84c6, 0x3adea4cb, 0x1258700d, 0x6ced5000,
 
104
    0x4355d981, 0x3de0f98c, 0x15662d4a, 0x6bd30d47, 0x56ee4b54, 0x285b6b59,
 
105
    0x00ddbf9f, 0x7e689f92, 0x51d01613, 0x2f65361e, 0x07e3e2d8, 0x7956c2d5,
 
106
    0x5892f1da, 0x2627d1d7, 0x0ea10511, 0x7014251c, 0x5facac9d, 0x21198c90,
 
107
    0x099f5856, 0x772a785b, 0x4c921c31, 0x32273c3c, 0x1aa1e8fa, 0x6414c8f7,
 
108
    0x4bac4176, 0x3519617b, 0x1d9fb5bd, 0x632a95b0, 0x42eea6bf, 0x3c5b86b2,
 
109
    0x14dd5274, 0x6a687279, 0x45d0fbf8, 0x3b65dbf5, 0x13e30f33, 0x6d562f3e,
 
110
    0x506b692d, 0x2ede4920, 0x06589de6, 0x78edbdeb, 0x5755346a, 0x29e01467,
 
111
    0x0166c0a1, 0x7fd3e0ac, 0x5e17d3a3, 0x20a2f3ae, 0x08242768, 0x76910765,
 
112
    0x59298ee4, 0x279caee9, 0x0f1a7a2f, 0x71af5a22, 0x7560f609, 0x0bd5d604,
 
113
    0x235302c2, 0x5de622cf, 0x725eab4e, 0x0ceb8b43, 0x246d5f85, 0x5ad87f88,
 
114
    0x7b1c4c87, 0x05a96c8a, 0x2d2fb84c, 0x539a9841, 0x7c2211c0, 0x029731cd,
 
115
    0x2a11e50b, 0x54a4c506, 0x69998315, 0x172ca318, 0x3faa77de, 0x411f57d3,
 
116
    0x6ea7de52, 0x1012fe5f, 0x38942a99, 0x46210a94, 0x67e5399b, 0x19501996,
 
117
    0x31d6cd50, 0x4f63ed5d, 0x60db64dc, 0x1e6e44d1, 0x36e89017, 0x485db01a,
 
118
    0x3f77c841, 0x41c2e84c, 0x69443c8a, 0x17f11c87, 0x38499506, 0x46fcb50b,
 
119
    0x6e7a61cd, 0x10cf41c0, 0x310b72cf, 0x4fbe52c2, 0x67388604, 0x198da609,
 
120
    0x36352f88, 0x48800f85, 0x6006db43, 0x1eb3fb4e, 0x238ebd5d, 0x5d3b9d50,
 
121
    0x75bd4996, 0x0b08699b, 0x24b0e01a, 0x5a05c017, 0x728314d1, 0x0c3634dc,
 
122
    0x2df207d3, 0x534727de, 0x7bc1f318, 0x0574d315, 0x2acc5a94, 0x54797a99,
 
123
    0x7cffae5f, 0x024a8e52, 0x06852279, 0x78300274, 0x50b6d6b2, 0x2e03f6bf,
 
124
    0x01bb7f3e, 0x7f0e5f33, 0x57888bf5, 0x293dabf8, 0x08f998f7, 0x764cb8fa,
 
125
    0x5eca6c3c, 0x207f4c31, 0x0fc7c5b0, 0x7172e5bd, 0x59f4317b, 0x27411176,
 
126
    0x1a7c5765, 0x64c97768, 0x4c4fa3ae, 0x32fa83a3, 0x1d420a22, 0x63f72a2f,
 
127
    0x4b71fee9, 0x35c4dee4, 0x1400edeb, 0x6ab5cde6, 0x42331920, 0x3c86392d,
 
128
    0x133eb0ac, 0x6d8b90a1, 0x450d4467, 0x3bb8646a
 
129
};
 
130
 
 
131
struct index_entry {
 
132
    const unsigned char *ptr;
 
133
    const struct source_info *src;
 
134
    unsigned int val;
 
135
};
 
136
 
 
137
struct index_entry_linked_list {
 
138
    struct index_entry *p_entry;
 
139
    struct index_entry_linked_list *next;
 
140
};
 
141
 
 
142
struct unpacked_index_entry {
 
143
    struct index_entry entry;
 
144
    struct unpacked_index_entry *next;
 
145
};
 
146
 
 
147
struct delta_index {
 
148
    unsigned long memsize; /* Total bytes pointed to by this index */
 
149
    const struct source_info *last_src; /* Information about the referenced source */
 
150
    unsigned int hash_mask; /* val & hash_mask gives the hash index for a given
 
151
                               entry */
 
152
    unsigned int num_entries; /* The total number of entries in this index */
 
153
    struct index_entry *last_entry; /* Pointer to the last valid entry */
 
154
    struct index_entry *hash[];
 
155
};
 
156
 
 
157
static unsigned int
 
158
limit_hash_buckets(struct unpacked_index_entry **hash,
 
159
                   unsigned int *hash_count, unsigned int hsize,
 
160
                   unsigned int entries)
 
161
{
 
162
    struct unpacked_index_entry *entry;
 
163
    unsigned int i;
 
164
    /*
 
165
     * Determine a limit on the number of entries in the same hash
 
166
     * bucket.  This guards us against pathological data sets causing
 
167
     * really bad hash distribution with most entries in the same hash
 
168
     * bucket that would bring us to O(m*n) computing costs (m and n
 
169
     * corresponding to reference and target buffer sizes).
 
170
     *
 
171
     * Make sure none of the hash buckets has more entries than
 
172
     * we're willing to test.  Otherwise we cull the entry list
 
173
     * uniformly to still preserve a good repartition across
 
174
     * the reference buffer.
 
175
     */
 
176
    for (i = 0; i < hsize; i++) {
 
177
        int acc;
 
178
 
 
179
        if (hash_count[i] <= HASH_LIMIT)
 
180
            continue;
 
181
 
 
182
        /* We leave exactly HASH_LIMIT entries in the bucket */
 
183
        entries -= hash_count[i] - HASH_LIMIT;
 
184
 
 
185
        entry = hash[i];
 
186
        acc = 0;
 
187
 
 
188
        /*
 
189
         * Assume that this loop is gone through exactly
 
190
         * HASH_LIMIT times and is entered and left with
 
191
         * acc==0.  So the first statement in the loop
 
192
         * contributes (hash_count[i]-HASH_LIMIT)*HASH_LIMIT
 
193
         * to the accumulator, and the inner loop consequently
 
194
         * is run (hash_count[i]-HASH_LIMIT) times, removing
 
195
         * one element from the list each time.  Since acc
 
196
         * balances out to 0 at the final run, the inner loop
 
197
         * body can't be left with entry==NULL.  So we indeed
 
198
         * encounter entry==NULL in the outer loop only.
 
199
         */
 
200
        do {
 
201
            acc += hash_count[i] - HASH_LIMIT;
 
202
            if (acc > 0) {
 
203
                struct unpacked_index_entry *keep = entry;
 
204
                do {
 
205
                    entry = entry->next;
 
206
                    acc -= HASH_LIMIT;
 
207
                } while (acc > 0);
 
208
                keep->next = entry->next;
 
209
            }
 
210
            entry = entry->next;
 
211
        } while (entry);
 
212
    }
 
213
    return entries;
 
214
}
 
215
 
 
216
static struct delta_index *
 
217
pack_delta_index(struct unpacked_index_entry **hash, unsigned int hsize,
 
218
                 unsigned int num_entries, struct delta_index *old_index)
 
219
{
 
220
    unsigned int i, j, hmask, memsize, fit_in_old, copied_count;
 
221
    struct unpacked_index_entry *entry;
 
222
    struct delta_index *index;
 
223
    struct index_entry *packed_entry, **packed_hash, *old_entry;
 
224
    struct index_entry null_entry = {0};
 
225
    void *mem;
 
226
 
 
227
    hmask = hsize - 1;
 
228
 
 
229
    // if (old_index) {
 
230
    //     fprintf(stderr, "Packing %d entries into %d for total of %d entries"
 
231
    //                     " %x => %x\n",
 
232
    //                     num_entries - old_index->num_entries,
 
233
    //                     old_index->num_entries, num_entries,
 
234
    //                     old_index->hash_mask, hmask);
 
235
    // } else {
 
236
    //     fprintf(stderr, "Packing %d entries into a new index\n",
 
237
    //                     num_entries);
 
238
    // }
 
239
    /* First, see if we can squeeze the new items into the existing structure.
 
240
     */
 
241
    fit_in_old = 0;
 
242
    copied_count = 0;
 
243
    if (old_index && old_index->hash_mask == hmask) {
 
244
        fit_in_old = 1;
 
245
        for (i = 0; i < hsize; ++i) {
 
246
            packed_entry = NULL;
 
247
            for (entry = hash[i]; entry; entry = entry->next) {
 
248
                if (packed_entry == NULL) {
 
249
                    /* Find the last open spot */
 
250
                    packed_entry = old_index->hash[i + 1];
 
251
                    --packed_entry;
 
252
                    while (packed_entry >= old_index->hash[i]
 
253
                           && packed_entry->ptr == NULL) {
 
254
                        --packed_entry;
 
255
                    }
 
256
                    ++packed_entry;
 
257
                }
 
258
                if (packed_entry >= old_index->hash[i+1]
 
259
                    || packed_entry->ptr != NULL) {
 
260
                    /* There are no free spots here :( */
 
261
                    fit_in_old = 0;
 
262
                    break;
 
263
                }
 
264
                /* We found an empty spot to put this entry
 
265
                 * Copy it over, and remove it from the linked list, just in
 
266
                 * case we end up running out of room later.
 
267
                 */
 
268
                *packed_entry++ = entry->entry;
 
269
                assert(entry == hash[i]);
 
270
                hash[i] = entry->next;
 
271
                copied_count += 1;
 
272
                old_index->num_entries++;
 
273
            }
 
274
            if (!fit_in_old) {
 
275
                break;
 
276
            }
 
277
        }
 
278
    }
 
279
    if (old_index) {
 
280
        if (fit_in_old) {
 
281
            // fprintf(stderr, "Fit all %d entries into old index\n",
 
282
            //                 copied_count);
 
283
            /*
 
284
             * No need to allocate a new buffer, but return old_index ptr so
 
285
             * callers can distinguish this from an OOM failure.
 
286
             */
 
287
            return old_index;
 
288
        } else {
 
289
            // fprintf(stderr, "Fit only %d entries into old index,"
 
290
            //                 " reallocating\n", copied_count);
 
291
        }
 
292
    }
 
293
    /*
 
294
     * Now create the packed index in array form
 
295
     * rather than linked lists.
 
296
     * Leave a 2-entry gap for inserting more entries between the groups
 
297
     */
 
298
    memsize = sizeof(*index)
 
299
        + sizeof(*packed_hash) * (hsize+1)
 
300
        + sizeof(*packed_entry) * (num_entries + hsize * EXTRA_NULLS);
 
301
    mem = malloc(memsize);
 
302
    if (!mem) {
 
303
        return NULL;
 
304
    }
 
305
 
 
306
    index = mem;
 
307
    index->memsize = memsize;
 
308
    index->hash_mask = hmask;
 
309
    index->num_entries = num_entries;
 
310
    if (old_index) {
 
311
        if (hmask < old_index->hash_mask) {
 
312
            fprintf(stderr, "hash mask was shrunk %x => %x\n",
 
313
                            old_index->hash_mask, hmask);
 
314
        }
 
315
        assert(hmask >= old_index->hash_mask);
 
316
    }
 
317
 
 
318
    mem = index->hash;
 
319
    packed_hash = mem;
 
320
    mem = packed_hash + (hsize+1);
 
321
    packed_entry = mem;
 
322
 
 
323
    for (i = 0; i < hsize; i++) {
 
324
        /*
 
325
         * Coalesce all entries belonging to one linked list
 
326
         * into consecutive array entries.
 
327
         */
 
328
        packed_hash[i] = packed_entry;
 
329
        /* Old comes earlier as a source, so it always comes first in a given
 
330
         * hash bucket.
 
331
         */
 
332
        if (old_index) {
 
333
            /* Could we optimize this to use memcpy when hmask ==
 
334
             * old_index->hash_mask? Would it make any real difference?
 
335
             */
 
336
            j = i & old_index->hash_mask;
 
337
            for (old_entry = old_index->hash[j];
 
338
                 old_entry < old_index->hash[j + 1] && old_entry->ptr != NULL;
 
339
                 old_entry++) {
 
340
                if ((old_entry->val & hmask) == i) {
 
341
                    *packed_entry++ = *old_entry;
 
342
                }
 
343
            }
 
344
        }
 
345
        for (entry = hash[i]; entry; entry = entry->next) {
 
346
            *packed_entry++ = entry->entry;
 
347
        }
 
348
        /* TODO: At this point packed_entry - packed_hash[i] is the number of
 
349
         *       records that we have inserted into this hash bucket.
 
350
         *       We should *really* consider doing some limiting along the
 
351
         *       lines of limit_hash_buckets() to avoid pathological behavior.
 
352
         */
 
353
        /* Now add extra 'NULL' entries that we can use for future expansion. */
 
354
        for (j = 0; j < EXTRA_NULLS; ++j ) {
 
355
            *packed_entry++ = null_entry;
 
356
        }
 
357
    }
 
358
 
 
359
    /* Sentinel value to indicate the length of the last hash bucket */
 
360
    packed_hash[hsize] = packed_entry;
 
361
 
 
362
    if (packed_entry - (struct index_entry *)mem
 
363
        != num_entries + hsize*EXTRA_NULLS) {
 
364
        fprintf(stderr, "We expected %d entries, but created %d\n",
 
365
                num_entries + hsize*EXTRA_NULLS,
 
366
                (int)(packed_entry - (struct index_entry*)mem));
 
367
    }
 
368
    assert(packed_entry - (struct index_entry *)mem
 
369
            == num_entries + hsize*EXTRA_NULLS);
 
370
    index->last_entry = (packed_entry - 1);
 
371
    return index;
 
372
}
 
373
 
 
374
 
 
375
delta_result
 
376
create_delta_index(const struct source_info *src,
 
377
                   struct delta_index *old,
 
378
                   struct delta_index **fresh,
 
379
                   int max_bytes_to_index)
 
380
{
 
381
    unsigned int i, hsize, hmask, num_entries, prev_val, *hash_count;
 
382
    unsigned int total_num_entries, stride, max_entries;
 
383
    const unsigned char *data, *buffer;
 
384
    struct delta_index *index;
 
385
    struct unpacked_index_entry *entry, **hash;
 
386
    void *mem;
 
387
    unsigned long memsize;
 
388
 
 
389
    if (!src->buf || !src->size)
 
390
        return DELTA_SOURCE_EMPTY;
 
391
    buffer = src->buf;
 
392
 
 
393
    /* Determine index hash size.  Note that indexing skips the
 
394
       first byte so we subtract 1 to get the edge cases right.
 
395
     */
 
396
    stride = RABIN_WINDOW;
 
397
    num_entries = (src->size - 1)  / RABIN_WINDOW;
 
398
    if (max_bytes_to_index > 0) {
 
399
        max_entries = (unsigned int) (max_bytes_to_index / RABIN_WINDOW);
 
400
        if (num_entries > max_entries) {
 
401
            /* Limit the max number of matching entries. This reduces the 'best'
 
402
             * possible match, but means we don't consume all of ram.
 
403
             */
 
404
            num_entries = max_entries;
 
405
            stride = (src->size - 1) / num_entries;
 
406
        }
 
407
    }
 
408
    if (old != NULL)
 
409
        total_num_entries = num_entries + old->num_entries;
 
410
    else
 
411
        total_num_entries = num_entries;
 
412
    hsize = total_num_entries / 4;
 
413
    for (i = 4; (1u << i) < hsize && i < 31; i++);
 
414
    hsize = 1 << i;
 
415
    hmask = hsize - 1;
 
416
    if (old && old->hash_mask > hmask) {
 
417
        hmask = old->hash_mask;
 
418
        hsize = hmask + 1;
 
419
    }
 
420
 
 
421
    /* allocate lookup index */
 
422
    memsize = sizeof(*hash) * hsize +
 
423
          sizeof(*entry) * total_num_entries;
 
424
    mem = malloc(memsize);
 
425
    if (!mem)
 
426
        return DELTA_OUT_OF_MEMORY;
 
427
    hash = mem;
 
428
    mem = hash + hsize;
 
429
    entry = mem;
 
430
 
 
431
    memset(hash, 0, hsize * sizeof(*hash));
 
432
 
 
433
    /* allocate an array to count hash num_entries */
 
434
    hash_count = calloc(hsize, sizeof(*hash_count));
 
435
    if (!hash_count) {
 
436
        free(hash);
 
437
        return DELTA_OUT_OF_MEMORY;
 
438
    }
 
439
 
 
440
    /* then populate the index for the new data */
 
441
    prev_val = ~0;
 
442
    for (data = buffer + num_entries * stride - RABIN_WINDOW;
 
443
         data >= buffer;
 
444
         data -= stride) {
 
445
        unsigned int val = 0;
 
446
        for (i = 1; i <= RABIN_WINDOW; i++)
 
447
            val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
 
448
        if (val == prev_val) {
 
449
            /* keep the lowest of consecutive identical blocks */
 
450
            entry[-1].entry.ptr = data + RABIN_WINDOW;
 
451
            --num_entries;
 
452
            --total_num_entries;
 
453
        } else {
 
454
            prev_val = val;
 
455
            i = val & hmask;
 
456
            entry->entry.ptr = data + RABIN_WINDOW;
 
457
            entry->entry.val = val;
 
458
            entry->entry.src = src;
 
459
            entry->next = hash[i];
 
460
            hash[i] = entry++;
 
461
            hash_count[i]++;
 
462
        }
 
463
    }
 
464
    /* TODO: It would be nice to limit_hash_buckets at a better time. */
 
465
    total_num_entries = limit_hash_buckets(hash, hash_count, hsize,
 
466
                                           total_num_entries);
 
467
    free(hash_count);
 
468
    index = pack_delta_index(hash, hsize, total_num_entries, old);
 
469
    free(hash);
 
470
    /* pack_delta_index only returns NULL on malloc failure */
 
471
    if (!index) {
 
472
        return DELTA_OUT_OF_MEMORY;
 
473
    }
 
474
    index->last_src = src;
 
475
    *fresh = index;
 
476
    return DELTA_OK;
 
477
}
 
478
 
 
479
/* Take some entries, and put them into a custom hash.
 
480
 * @param entries   A list of entries, sorted by position in file
 
481
 * @param num_entries   Length of entries
 
482
 * @param out_hsize     The maximum size of the hash, the final size will be
 
483
 *                      returned here
 
484
 */
 
485
struct index_entry_linked_list **
 
486
_put_entries_into_hash(struct index_entry *entries, unsigned int num_entries,
 
487
                       unsigned int hsize)
 
488
{
 
489
    unsigned int hash_offset, hmask, memsize;
 
490
    struct index_entry *entry;
 
491
    struct index_entry_linked_list *out_entry, **hash;
 
492
    void *mem;
 
493
 
 
494
    hmask = hsize - 1;
 
495
 
 
496
    memsize = sizeof(*hash) * hsize +
 
497
          sizeof(*out_entry) * num_entries;
 
498
    mem = malloc(memsize);
 
499
    if (!mem)
 
500
        return NULL;
 
501
    hash = mem;
 
502
    mem = hash + hsize;
 
503
    out_entry = mem;
 
504
 
 
505
    memset(hash, 0, sizeof(*hash)*(hsize+1));
 
506
 
 
507
    /* We know that entries are in the order we want in the output, but they
 
508
     * aren't "grouped" by hash bucket yet.
 
509
     */
 
510
    for (entry = entries + num_entries - 1; entry >= entries; --entry) {
 
511
        hash_offset = entry->val & hmask;
 
512
        out_entry->p_entry = entry;
 
513
        out_entry->next = hash[hash_offset];
 
514
        /* TODO: Remove entries that have identical vals, or at least filter
 
515
         *       the map a little bit.
 
516
         * if (hash[i] != NULL) {
 
517
         * }
 
518
         */
 
519
        hash[hash_offset] = out_entry;
 
520
        ++out_entry;
 
521
    }
 
522
    return hash;
 
523
}
 
524
 
 
525
 
 
526
struct delta_index *
 
527
create_index_from_old_and_new_entries(const struct delta_index *old_index,
 
528
                                      struct index_entry *entries,
 
529
                                      unsigned int num_entries)
 
530
{
 
531
    unsigned int i, j, hsize, hmask, total_num_entries;
 
532
    struct delta_index *index;
 
533
    struct index_entry *entry, *packed_entry, **packed_hash;
 
534
    struct index_entry null_entry = {0};
 
535
    void *mem;
 
536
    unsigned long memsize;
 
537
    struct index_entry_linked_list *unpacked_entry, **mini_hash;
 
538
 
 
539
    /* Determine index hash size.  Note that indexing skips the
 
540
       first byte to allow for optimizing the Rabin's polynomial
 
541
       initialization in create_delta(). */
 
542
    total_num_entries = num_entries + old_index->num_entries;
 
543
    hsize = total_num_entries / 4;
 
544
    for (i = 4; (1u << i) < hsize && i < 31; i++);
 
545
    hsize = 1 << i;
 
546
    if (hsize < old_index->hash_mask) {
 
547
        /* For some reason, there was a code path that would actually *shrink*
 
548
         * the hash size. This screws with some later code, and in general, I
 
549
         * think it better to make the hash bigger, rather than smaller. So
 
550
         * we'll just force the size here.
 
551
         * Possibly done by create_delta_index running into a
 
552
         * limit_hash_buckets call, that ended up transitioning across a
 
553
         * power-of-2. The cause isn't 100% clear, though.
 
554
         */
 
555
        hsize = old_index->hash_mask + 1;
 
556
    }
 
557
    hmask = hsize - 1;
 
558
    // fprintf(stderr, "resizing index to insert %d entries into array"
 
559
    //                 " with %d entries: %x => %x\n",
 
560
    //         num_entries, old_index->num_entries, old_index->hash_mask, hmask);
 
561
 
 
562
    memsize = sizeof(*index)
 
563
        + sizeof(*packed_hash) * (hsize+1)
 
564
        + sizeof(*packed_entry) * (total_num_entries + hsize*EXTRA_NULLS);
 
565
    mem = malloc(memsize);
 
566
    if (!mem) {
 
567
        return NULL;
 
568
    }
 
569
    index = mem;
 
570
    index->memsize = memsize;
 
571
    index->hash_mask = hmask;
 
572
    index->num_entries = total_num_entries;
 
573
    index->last_src = old_index->last_src;
 
574
 
 
575
    mem = index->hash;
 
576
    packed_hash = mem;
 
577
    mem = packed_hash + (hsize+1);
 
578
    packed_entry = mem;
 
579
 
 
580
    mini_hash = _put_entries_into_hash(entries, num_entries, hsize);
 
581
    if (mini_hash == NULL) {
 
582
        free(index);
 
583
        return NULL;
 
584
    }
 
585
    for (i = 0; i < hsize; i++) {
 
586
        /*
 
587
         * Coalesce all entries belonging in one hash bucket
 
588
         * into consecutive array entries.
 
589
         * The entries in old_index all come before 'entries'.
 
590
         */
 
591
        packed_hash[i] = packed_entry;
 
592
        /* Copy any of the old entries across */
 
593
        /* Would we rather use memcpy? */
 
594
        if (hmask == old_index->hash_mask) {
 
595
            for (entry = old_index->hash[i];
 
596
                 entry < old_index->hash[i+1] && entry->ptr != NULL;
 
597
                 ++entry) {
 
598
                assert((entry->val & hmask) == i);
 
599
                *packed_entry++ = *entry;
 
600
            }
 
601
        } else {
 
602
            /* If we resized the index from this action, all of the old values
 
603
             * will be found in the previous location, but they will end up
 
604
             * spread across the new locations.
 
605
             */
 
606
            j = i & old_index->hash_mask;
 
607
            for (entry = old_index->hash[j];
 
608
                 entry < old_index->hash[j+1] && entry->ptr != NULL;
 
609
                 ++entry) {
 
610
                assert((entry->val & old_index->hash_mask) == j);
 
611
                if ((entry->val & hmask) == i) {
 
612
                    /* Any entries not picked up here will be picked up on the
 
613
                     * next pass.
 
614
                     */
 
615
                    *packed_entry++ = *entry;
 
616
                }
 
617
            }
 
618
        }
 
619
        /* Now see if we need to insert any of the new entries.
 
620
         * Note that loop ends up O(hsize*num_entries), so we expect that
 
621
         * num_entries is always small.
 
622
         * We also help a little bit by collapsing the entry range when the
 
623
         * endpoints are inserted. However, an alternative would be to build a
 
624
         * quick hash lookup for just the new entries.
 
625
         * Testing shows that this list can easily get up to about 100
 
626
         * entries, the tradeoff is a malloc, 1 pass over the entries, copying
 
627
         * them into a sorted buffer, and a free() when done,
 
628
         */
 
629
        for (unpacked_entry = mini_hash[i];
 
630
             unpacked_entry;
 
631
             unpacked_entry = unpacked_entry->next) {
 
632
            assert((unpacked_entry->p_entry->val & hmask) == i);
 
633
            *packed_entry++ = *(unpacked_entry->p_entry);
 
634
        }
 
635
        /* Now insert some extra nulls */
 
636
        for (j = 0; j < EXTRA_NULLS; ++j) {
 
637
            *packed_entry++ = null_entry;
 
638
        }
 
639
    }
 
640
    free(mini_hash);
 
641
 
 
642
    /* Sentinel value to indicate the length of the last hash bucket */
 
643
    packed_hash[hsize] = packed_entry;
 
644
 
 
645
    if ((packed_entry - (struct index_entry *)mem)
 
646
        != (total_num_entries + hsize*EXTRA_NULLS)) {
 
647
        fprintf(stderr, "We expected %d entries, but created %d\n",
 
648
                total_num_entries + hsize*EXTRA_NULLS,
 
649
                (int)(packed_entry - (struct index_entry*)mem));
 
650
        fflush(stderr);
 
651
    }
 
652
    assert((packed_entry - (struct index_entry *)mem)
 
653
           == (total_num_entries + hsize * EXTRA_NULLS));
 
654
    index->last_entry = (packed_entry - 1);
 
655
    return index;
 
656
}
 
657
 
 
658
 
 
659
void
 
660
get_text(char buff[128], const unsigned char *ptr)
 
661
{
 
662
    unsigned int i;
 
663
    const unsigned char *start;
 
664
    unsigned char cmd;
 
665
    start = (ptr-RABIN_WINDOW-1);
 
666
    cmd = *(start);
 
667
    if (cmd < 0x80) {// This is likely to be an insert instruction
 
668
        if (cmd < RABIN_WINDOW) {
 
669
            cmd = RABIN_WINDOW;
 
670
        }
 
671
    } else {
 
672
        /* This was either a copy [should never be] or it
 
673
         * was a longer insert so the insert start happened at 16 more
 
674
         * bytes back.
 
675
         */
 
676
        cmd = RABIN_WINDOW + 1;
 
677
    }
 
678
    if (cmd > 60) {
 
679
        cmd = 60; /* Be friendly to 80char terms */
 
680
    }
 
681
    /* Copy the 1 byte command, and 4 bytes after the insert */
 
682
    cmd += 5;
 
683
    memcpy(buff, start, cmd);
 
684
    buff[cmd] = 0;
 
685
    for (i = 0; i < cmd; ++i) {
 
686
        if (buff[i] == '\n') {
 
687
            buff[i] = 'N';
 
688
        } else if (buff[i] == '\t') {
 
689
            buff[i] = 'T';
 
690
        }
 
691
    }
 
692
}
 
693
 
 
694
delta_result
 
695
create_delta_index_from_delta(const struct source_info *src,
 
696
                              struct delta_index *old_index,
 
697
                              struct delta_index **fresh)
 
698
{
 
699
    unsigned int i, num_entries, max_num_entries, prev_val, num_inserted;
 
700
    unsigned int hash_offset;
 
701
    const unsigned char *data, *buffer, *top;
 
702
    unsigned char cmd;
 
703
    struct delta_index *new_index;
 
704
    struct index_entry *entry, *entries;
 
705
 
 
706
    if (!old_index)
 
707
        return DELTA_INDEX_NEEDED;
 
708
    if (!src->buf || !src->size)
 
709
        return DELTA_SOURCE_EMPTY;
 
710
    buffer = src->buf;
 
711
    top = buffer + src->size;
 
712
 
 
713
    /* Determine index hash size.  Note that indexing skips the
 
714
       first byte to allow for optimizing the Rabin's polynomial
 
715
       initialization in create_delta().
 
716
       This computes the maximum number of entries that could be held. The
 
717
       actual number will be recomputed during processing.
 
718
       */
 
719
 
 
720
    max_num_entries = (src->size - 1)  / RABIN_WINDOW;
 
721
 
 
722
    if (!max_num_entries) {
 
723
        *fresh = old_index;
 
724
        return DELTA_OK;
 
725
    }
 
726
 
 
727
    /* allocate an array to hold whatever entries we find */
 
728
    entries = malloc(sizeof(*entry) * max_num_entries);
 
729
    if (!entries) /* malloc failure */
 
730
        return DELTA_OUT_OF_MEMORY;
 
731
 
 
732
    /* then populate the index for the new data */
 
733
    prev_val = ~0;
 
734
    data = buffer;
 
735
    /* target size */
 
736
    /* get_delta_hdr_size doesn't mutate the content, just moves the
 
737
     * start-of-data pointer, so it is safe to do the cast.
 
738
     */
 
739
    get_delta_hdr_size((unsigned char**)&data, top);
 
740
    entry = entries; /* start at the first slot */
 
741
    num_entries = 0; /* calculate the real number of entries */
 
742
    while (data < top) {
 
743
        cmd = *data++;
 
744
        if (cmd & 0x80) {
 
745
            /* Copy instruction, skip it */
 
746
            if (cmd & 0x01) data++;
 
747
            if (cmd & 0x02) data++;
 
748
            if (cmd & 0x04) data++;
 
749
            if (cmd & 0x08) data++;
 
750
            if (cmd & 0x10) data++;
 
751
            if (cmd & 0x20) data++;
 
752
            if (cmd & 0x40) data++;
 
753
        } else if (cmd) {
 
754
            /* Insert instruction, we want to index these bytes */
 
755
            if (data + cmd > top) {
 
756
                /* Invalid insert, not enough bytes in the delta */
 
757
                break;
 
758
            }
 
759
            /* The create_delta code requires a match at least 4 characters
 
760
             * (including only the last char of the RABIN_WINDOW) before it
 
761
             * will consider it something worth copying rather than inserting.
 
762
             * So we don't want to index anything that we know won't ever be a
 
763
             * match.
 
764
             */
 
765
            for (; cmd > RABIN_WINDOW + 3; cmd -= RABIN_WINDOW,
 
766
                                       data += RABIN_WINDOW) {
 
767
                unsigned int val = 0;
 
768
                for (i = 1; i <= RABIN_WINDOW; i++)
 
769
                    val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
 
770
                if (val != prev_val) {
 
771
                    /* Only keep the first of consecutive data */
 
772
                    prev_val = val;
 
773
                    num_entries++;
 
774
                    entry->ptr = data + RABIN_WINDOW;
 
775
                    entry->val = val;
 
776
                    entry->src = src;
 
777
                    entry++;
 
778
                    if (num_entries > max_num_entries) {
 
779
                        /* We ran out of entry room, something is really wrong
 
780
                         */
 
781
                        break;
 
782
                    }
 
783
                }
 
784
            }
 
785
            /* Move the data pointer by whatever remainder is left */
 
786
            data += cmd;
 
787
        } else {
 
788
            /*
 
789
             * cmd == 0 is reserved for future encoding
 
790
             * extensions. In the mean time we must fail when
 
791
             * encountering them (might be data corruption).
 
792
             */
 
793
            break;
 
794
        }
 
795
    }
 
796
    if (data != top) {
 
797
        /* The source_info data passed was corrupted or otherwise invalid */
 
798
        free(entries);
 
799
        return DELTA_SOURCE_BAD;
 
800
    }
 
801
    if (num_entries == 0) {
 
802
        /** Nothing to index **/
 
803
        free(entries);
 
804
        *fresh = old_index;
 
805
        return DELTA_OK;
 
806
    }
 
807
    old_index->last_src = src;
 
808
    /* See if we can fill in these values into the holes in the array */
 
809
    entry = entries;
 
810
    num_inserted = 0;
 
811
    for (; num_entries > 0; --num_entries, ++entry) {
 
812
        struct index_entry *next_bucket_entry, *cur_entry, *bucket_first_entry;
 
813
        hash_offset = (entry->val & old_index->hash_mask);
 
814
        /* The basic structure is a hash => packed_entries that fit in that
 
815
         * hash bucket. Things are structured such that the hash-pointers are
 
816
         * strictly ordered. So we start by pointing to the next pointer, and
 
817
         * walk back until we stop getting NULL targets, and then go back
 
818
         * forward. If there are no NULL targets, then we know because
 
819
         * entry->ptr will not be NULL.
 
820
         */
 
821
        // The start of the next bucket, this may point past the end of the
 
822
        // entry table if hash_offset is the last bucket.
 
823
        next_bucket_entry = old_index->hash[hash_offset + 1];
 
824
        // First entry in this bucket
 
825
        bucket_first_entry = old_index->hash[hash_offset];
 
826
        cur_entry = next_bucket_entry - 1;
 
827
        while (cur_entry->ptr == NULL && cur_entry >= bucket_first_entry) {
 
828
            cur_entry--;
 
829
        }
 
830
        // cur_entry now either points at the first NULL, or it points to
 
831
        // next_bucket_entry if there were no blank spots.
 
832
        cur_entry++;
 
833
        if (cur_entry >= next_bucket_entry || cur_entry->ptr != NULL) {
 
834
            /* There is no room for this entry, we have to resize */
 
835
            // char buff[128];
 
836
            // get_text(buff, entry->ptr);
 
837
            // fprintf(stderr, "Failed to find an opening @%x for %8x:\n '%s'\n",
 
838
            //         hash_offset, entry->val, buff);
 
839
            // for (old_entry = old_index->hash[hash_offset];
 
840
            //      old_entry < old_index->hash[hash_offset+1];
 
841
            //      ++old_entry) {
 
842
            //     get_text(buff, old_entry->ptr);
 
843
            //     fprintf(stderr, "  [%2d] %8x %8x: '%s'\n",
 
844
            //             (int)(old_entry - old_index->hash[hash_offset]),
 
845
            //             old_entry->val, old_entry->ptr, buff);
 
846
            // }
 
847
            break;
 
848
        }
 
849
        num_inserted++;
 
850
        *cur_entry = *entry;
 
851
        /* For entries which we *do* manage to insert into old_index, we don't
 
852
         * want them double copied into the final output.
 
853
         */
 
854
        old_index->num_entries++;
 
855
    }
 
856
    if (num_entries > 0) {
 
857
        /* We couldn't fit the new entries into the old index, so allocate a
 
858
         * new one, and fill it with stuff.
 
859
         */
 
860
        // fprintf(stderr, "inserted %d before resize\n", num_inserted);
 
861
        new_index = create_index_from_old_and_new_entries(old_index,
 
862
            entry, num_entries);
 
863
    } else {
 
864
        new_index = old_index;
 
865
        // fprintf(stderr, "inserted %d without resizing\n", num_inserted);
 
866
    }
 
867
    free(entries);
 
868
    /* create_index_from_old_and_new_entries returns NULL on malloc failure */
 
869
    if (!new_index)
 
870
        return DELTA_OUT_OF_MEMORY;
 
871
    *fresh = new_index;
 
872
    return DELTA_OK;
 
873
}
 
874
 
 
875
void free_delta_index(struct delta_index *index)
 
876
{
 
877
    free(index);
 
878
}
 
879
 
 
880
unsigned long
 
881
sizeof_delta_index(struct delta_index *index)
 
882
{
 
883
    if (index)
 
884
        return index->memsize;
 
885
    else
 
886
        return 0;
 
887
}
 
888
 
 
889
/*
 
890
 * The maximum size for any opcode sequence, including the initial header
 
891
 * plus Rabin window plus biggest copy.
 
892
 */
 
893
#define MAX_OP_SIZE (5 + 5 + 1 + RABIN_WINDOW + 7)
 
894
 
 
895
delta_result
 
896
create_delta(const struct delta_index *index,
 
897
             const void *trg_buf, unsigned long trg_size,
 
898
             unsigned long *delta_size, unsigned long max_size,
 
899
             void **delta_data)
 
900
{
 
901
    unsigned int i, outpos, outsize, moff, val;
 
902
    int msize;
 
903
    const struct source_info *msource;
 
904
    int inscnt;
 
905
    const unsigned char *ref_data, *ref_top, *data, *top;
 
906
    unsigned char *out;
 
907
 
 
908
    if (!trg_buf || !trg_size)
 
909
        return DELTA_BUFFER_EMPTY;
 
910
    if (index == NULL)
 
911
        return DELTA_INDEX_NEEDED;
 
912
 
 
913
    outpos = 0;
 
914
    outsize = 8192;
 
915
    if (max_size && outsize >= max_size)
 
916
        outsize = max_size + MAX_OP_SIZE + 1;
 
917
    out = malloc(outsize);
 
918
    if (!out)
 
919
        return DELTA_OUT_OF_MEMORY;
 
920
 
 
921
    /* store target buffer size */
 
922
    i = trg_size;
 
923
    while (i >= 0x80) {
 
924
        out[outpos++] = i | 0x80;
 
925
        i >>= 7;
 
926
    }
 
927
    out[outpos++] = i;
 
928
 
 
929
    data = trg_buf;
 
930
    top = (const unsigned char *) trg_buf + trg_size;
 
931
 
 
932
    /* Start the matching by filling out with a simple 'insert' instruction, of
 
933
     * the first RABIN_WINDOW bytes of the input.
 
934
     */
 
935
    outpos++; /* leave a byte for the insert command */
 
936
    val = 0;
 
937
    for (i = 0; i < RABIN_WINDOW && data < top; i++, data++) {
 
938
        out[outpos++] = *data;
 
939
        val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
 
940
    }
 
941
    /* we are now setup with an insert of 'i' bytes and val contains the RABIN
 
942
     * hash for those bytes, and data points to the RABIN_WINDOW+1 byte of
 
943
     * input.
 
944
     */
 
945
    inscnt = i;
 
946
 
 
947
    moff = 0;
 
948
    msize = 0;
 
949
    msource = NULL;
 
950
    while (data < top) {
 
951
        if (msize < 4096) {
 
952
            /* we don't have a 'worthy enough' match yet, so let's look for
 
953
             * one.
 
954
             */
 
955
            struct index_entry *entry;
 
956
            /* Shift the window by one byte. */
 
957
            val ^= U[data[-RABIN_WINDOW]];
 
958
            val = ((val << 8) | *data) ^ T[val >> RABIN_SHIFT];
 
959
            i = val & index->hash_mask;
 
960
            /* TODO: When using multiple indexes like this, the hash tables
 
961
             *       mapping val => index_entry become less efficient.
 
962
             *       You end up getting a lot more collisions in the hash,
 
963
             *       which doesn't actually lead to a entry->val match.
 
964
             */
 
965
            for (entry = index->hash[i];
 
966
                 entry < index->hash[i+1] && entry->src != NULL;
 
967
                 entry++) {
 
968
                const unsigned char *ref;
 
969
                const unsigned char *src;
 
970
                int ref_size;
 
971
                if (entry->val != val)
 
972
                    continue;
 
973
                ref = entry->ptr;
 
974
                src = data;
 
975
                ref_data = entry->src->buf;
 
976
                ref_top = ref_data + entry->src->size;
 
977
                ref_size = ref_top - ref;
 
978
                /* ref_size is the longest possible match that we could make
 
979
                 * here. If ref_size <= msize, then we know that we cannot
 
980
                 * match more bytes with this location that we have already
 
981
                 * matched.
 
982
                 */
 
983
                if (ref_size > (top - src))
 
984
                    ref_size = top - src;
 
985
                if (ref_size <= msize)
 
986
                    break;
 
987
                /* See how many bytes actually match at this location. */
 
988
                while (ref_size-- && *src++ == *ref)
 
989
                    ref++;
 
990
                if (msize < (ref - entry->ptr)) {
 
991
                    /* this is our best match so far */
 
992
                    msize = ref - entry->ptr;
 
993
                    msource = entry->src;
 
994
                    moff = entry->ptr - ref_data;
 
995
                    if (msize >= 4096) /* good enough */
 
996
                        break;
 
997
                }
 
998
            }
 
999
        }
 
1000
 
 
1001
        if (msize < 4) {
 
1002
            /* The best match right now is less than 4 bytes long. So just add
 
1003
             * the current byte to the insert instruction. Increment the insert
 
1004
             * counter, and copy the byte of data into the output buffer.
 
1005
             */
 
1006
            if (!inscnt)
 
1007
                outpos++;
 
1008
            out[outpos++] = *data++;
 
1009
            inscnt++;
 
1010
            if (inscnt == 0x7f) {
 
1011
                /* We have a max length insert instruction, finalize it in the
 
1012
                 * output.
 
1013
                 */
 
1014
                out[outpos - inscnt - 1] = inscnt;
 
1015
                inscnt = 0;
 
1016
            }
 
1017
            msize = 0;
 
1018
        } else {
 
1019
            unsigned int left;
 
1020
            unsigned char *op;
 
1021
 
 
1022
            if (inscnt) {
 
1023
                ref_data = msource->buf;
 
1024
                while (moff && ref_data[moff-1] == data[-1]) {
 
1025
                    /* we can match one byte back */
 
1026
                    msize++;
 
1027
                    moff--;
 
1028
                    data--;
 
1029
                    outpos--;
 
1030
                    if (--inscnt)
 
1031
                        continue;
 
1032
                    outpos--;  /* remove count slot */
 
1033
                    inscnt--;  /* make it -1 */
 
1034
                    break;
 
1035
                }
 
1036
                out[outpos - inscnt - 1] = inscnt;
 
1037
                inscnt = 0;
 
1038
            }
 
1039
 
 
1040
            /* A copy op is currently limited to 64KB (pack v2) */
 
1041
            left = (msize < 0x10000) ? 0 : (msize - 0x10000);
 
1042
            msize -= left;
 
1043
 
 
1044
            op = out + outpos++;
 
1045
            i = 0x80;
 
1046
 
 
1047
            /* moff is the offset in the local structure, for encoding, we need
 
1048
             * to push it into the global offset
 
1049
             */
 
1050
            assert(moff < msource->size);
 
1051
            moff += msource->agg_offset;
 
1052
            assert(moff + msize
 
1053
                <= index->last_src->size + index->last_src->agg_offset);
 
1054
            if (moff & 0x000000ff)
 
1055
                out[outpos++] = moff >> 0,  i |= 0x01;
 
1056
            if (moff & 0x0000ff00)
 
1057
                out[outpos++] = moff >> 8,  i |= 0x02;
 
1058
            if (moff & 0x00ff0000)
 
1059
                out[outpos++] = moff >> 16, i |= 0x04;
 
1060
            if (moff & 0xff000000)
 
1061
                out[outpos++] = moff >> 24, i |= 0x08;
 
1062
            /* Put it back into local coordinates, in case we have multiple
 
1063
             * copies in a row.
 
1064
             */
 
1065
            moff -= msource->agg_offset;
 
1066
 
 
1067
            if (msize & 0x00ff)
 
1068
                out[outpos++] = msize >> 0, i |= 0x10;
 
1069
            if (msize & 0xff00)
 
1070
                out[outpos++] = msize >> 8, i |= 0x20;
 
1071
 
 
1072
            *op = i;
 
1073
 
 
1074
            data += msize;
 
1075
            moff += msize;
 
1076
            msize = left;
 
1077
 
 
1078
            if (msize < 4096) {
 
1079
                int j;
 
1080
                val = 0;
 
1081
                for (j = -RABIN_WINDOW; j < 0; j++)
 
1082
                    val = ((val << 8) | data[j])
 
1083
                          ^ T[val >> RABIN_SHIFT];
 
1084
            }
 
1085
        }
 
1086
 
 
1087
        if (outpos >= outsize - MAX_OP_SIZE) {
 
1088
            void *tmp = out;
 
1089
            outsize = outsize * 3 / 2;
 
1090
            if (max_size && outsize >= max_size)
 
1091
                outsize = max_size + MAX_OP_SIZE + 1;
 
1092
            if (max_size && outpos > max_size)
 
1093
                break;
 
1094
            out = realloc(out, outsize);
 
1095
            if (!out) {
 
1096
                free(tmp);
 
1097
                return DELTA_OUT_OF_MEMORY;
 
1098
            }
 
1099
        }
 
1100
    }
 
1101
 
 
1102
    if (inscnt)
 
1103
        out[outpos - inscnt - 1] = inscnt;
 
1104
 
 
1105
    if (max_size && outpos > max_size) {
 
1106
        free(out);
 
1107
        return DELTA_SIZE_TOO_BIG;
 
1108
    }
 
1109
 
 
1110
    *delta_size = outpos;
 
1111
    *delta_data = out;
 
1112
    return DELTA_OK;
 
1113
}
 
1114
 
 
1115
 
 
1116
int
 
1117
get_entry_summary(const struct delta_index *index, int pos,
 
1118
                  unsigned int *text_offset, unsigned int *hash_val)
 
1119
{
 
1120
    int hsize;
 
1121
    const struct index_entry *entry;
 
1122
    const struct index_entry *start_of_entries;
 
1123
    unsigned int offset;
 
1124
    if (pos < 0 || text_offset == NULL || hash_val == NULL
 
1125
        || index == NULL)
 
1126
    {
 
1127
        return 0;
 
1128
    }
 
1129
    hsize = index->hash_mask + 1;
 
1130
    start_of_entries = (struct index_entry *)(((struct index_entry **)index->hash) + (hsize + 1));
 
1131
    entry = start_of_entries + pos;
 
1132
    if (entry > index->last_entry) {
 
1133
        return 0;
 
1134
    }
 
1135
    if (entry->ptr == NULL) {
 
1136
        *text_offset = 0;
 
1137
        *hash_val = 0;
 
1138
    } else {
 
1139
        offset = entry->src->agg_offset;
 
1140
        offset += (entry->ptr - ((unsigned char *)entry->src->buf));
 
1141
        *text_offset = offset;
 
1142
        *hash_val = entry->val;
 
1143
    }
 
1144
    return 1;
 
1145
}
 
1146
 
 
1147
 
 
1148
int
 
1149
get_hash_offset(const struct delta_index *index, int pos,
 
1150
                unsigned int *entry_offset)
 
1151
{
 
1152
    int hsize;
 
1153
    const struct index_entry *entry;
 
1154
    const struct index_entry *start_of_entries;
 
1155
    if (pos < 0 || index == NULL || entry_offset == NULL)
 
1156
    {
 
1157
        return 0;
 
1158
    }
 
1159
    hsize = index->hash_mask + 1;
 
1160
    start_of_entries = (struct index_entry *)(((struct index_entry **)index->hash) + (hsize + 1));
 
1161
    if (pos >= hsize) {
 
1162
        return 0;
 
1163
    }
 
1164
    entry = index->hash[pos];
 
1165
    if (entry == NULL) {
 
1166
        *entry_offset = -1;
 
1167
    } else {
 
1168
        *entry_offset = (entry - start_of_entries);
 
1169
    }
 
1170
    return 1;
 
1171
}
 
1172
 
 
1173
 
 
1174
unsigned int
 
1175
rabin_hash(const unsigned char *data)
 
1176
{
 
1177
    int i;
 
1178
    unsigned int val = 0;
 
1179
    for (i = 0; i < RABIN_WINDOW; i++)
 
1180
        val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
 
1181
    return val;
 
1182
}
 
1183
 
 
1184
/* vim: et ts=4 sw=4 sts=4
 
1185
 */