129
129
unsigned int hash_mask; /* val & hash_mask gives the hash index for a given
131
131
unsigned int num_entries; /* The total number of entries in this index */
132
struct index_entry *last_entry; /* Pointer to the last valid entry */
132
133
struct index_entry *hash[];
194
195
static struct delta_index *
195
196
pack_delta_index(struct unpacked_index_entry **hash, unsigned int hsize,
196
unsigned int entries)
197
unsigned int num_entries)
198
199
unsigned int i, memsize;
199
200
struct unpacked_index_entry *entry;
235
236
/* Sentinel value to indicate the length of the last hash bucket */
236
237
packed_hash[hsize] = packed_entry;
238
assert(packed_entry - (struct index_entry *)mem == entries);
239
assert(packed_entry - (struct index_entry *)mem == num_entries);
240
index->last_entry = (packed_entry - 1);
243
struct delta_index * create_delta_index(const struct source_info *src)
245
unsigned int i, hsize, hmask, entries, prev_val, *hash_count;
244
void include_entries_from_index(struct unpacked_index_entry **hash,
245
unsigned int *hash_count,
247
struct unpacked_index_entry *entry,
248
const struct delta_index *old)
250
unsigned int i, hmask, masked_val;
251
struct index_entry *old_entry;
254
/* Iterate backwards through the existing entries
255
* This is so that matches early in the file end up being the first pointer
256
* in the linked list.
258
for (old_entry = old->last_entry, i = 0; i < old->num_entries;
260
masked_val = old_entry->val & hmask;
261
entry->entry = *old_entry;
262
entry->next = hash[masked_val];
263
hash[masked_val] = entry++;
264
hash_count[masked_val]++;
269
struct delta_index * create_delta_index(const struct source_info *src,
270
const struct delta_index *old)
272
unsigned int i, hsize, hmask, num_entries, prev_val, *hash_count;
273
unsigned int total_num_entries;
246
274
const unsigned char *data, *buffer;
247
275
struct delta_index *index;
248
276
struct unpacked_index_entry *entry, **hash;
256
284
/* Determine index hash size. Note that indexing skips the
257
285
first byte to allow for optimizing the Rabin's polynomial
258
286
initialization in create_delta(). */
259
entries = (src->size - 1) / RABIN_WINDOW;
287
num_entries = (src->size - 1) / RABIN_WINDOW;
289
total_num_entries = num_entries + old->num_entries;
291
total_num_entries = num_entries;
292
hsize = total_num_entries / 4;
261
293
for (i = 4; (1u << i) < hsize && i < 31; i++);
263
295
hmask = hsize - 1;
265
297
/* allocate lookup index */
266
298
memsize = sizeof(*hash) * hsize +
267
sizeof(*entry) * entries;
299
sizeof(*entry) * total_num_entries;
268
300
mem = malloc(memsize);
275
307
memset(hash, 0, hsize * sizeof(*hash));
277
/* allocate an array to count hash entries */
309
/* allocate an array to count hash num_entries */
278
310
hash_count = calloc(hsize, sizeof(*hash_count));
279
311
if (!hash_count) {
284
/* then populate the index */
316
/* then populate the index for the new data */
286
for (data = buffer + entries * RABIN_WINDOW - RABIN_WINDOW;
318
for (data = buffer + num_entries * RABIN_WINDOW - RABIN_WINDOW;
288
320
data -= RABIN_WINDOW) {
289
321
unsigned int val = 0;
340
/* If we have an existing delta_index, we want to bring its info into the
341
* new structure. We assume that the existing structure's objects all occur
342
* before the new source, so they get first precedence in the index.
345
include_entries_from_index(hash, hash_count, hsize, entry, old);
308
entries = limit_hash_buckets(hash, hash_count, hsize, entries);
347
total_num_entries = limit_hash_buckets(hash, hash_count, hsize,
309
349
free(hash_count);
310
index = pack_delta_index(hash, hsize, entries);
350
index = pack_delta_index(hash, hsize, total_num_entries);
311
351
index->src = src;
348
388
const unsigned char *ref_data, *ref_top, *data, *top;
349
389
unsigned char *out;
390
unsigned long source_size;
351
392
if (!trg_buf || !trg_size)
507
549
/* moff is the offset in the local structure, for encoding, we need
508
550
* to push it into the global offset
552
assert(moff < msource->size);
510
553
moff += msource->agg_offset;
554
assert(moff + msize <= source_size);
511
555
if (moff & 0x000000ff)
512
556
out[outpos++] = moff >> 0, i |= 0x01;
513
557
if (moff & 0x0000ff00)