4
4
* This code was greatly inspired by parts of LibXDiff from Davide Libenzi
5
5
* http://www.xmailserver.org/xdiff-lib.html
7
* Rewritten for GIT by Nicolas Pitre <nico@fluxnic.net>, (C) 2005-2007
7
* Rewritten for GIT by Nicolas Pitre <nico@cam.org>, (C) 2005-2007
8
8
* Adapted for Bazaar by John Arbash Meinel <john@arbash-meinel.com> (C) 2009
10
10
* This program is free software; you can redistribute it and/or modify
280
280
if (fit_in_old) {
281
281
// fprintf(stderr, "Fit all %d entries into old index\n",
282
282
// copied_count);
284
* No need to allocate a new buffer, but return old_index ptr so
285
* callers can distinguish this from an OOM failure.
283
/* No need to allocate a new buffer */
289
286
// fprintf(stderr, "Fit only %d entries into old index,"
290
287
// " reallocating\n", copied_count);
377
374
create_delta_index(const struct source_info *src,
378
struct delta_index *old,
379
struct delta_index **fresh,
380
int max_bytes_to_index)
375
struct delta_index *old)
382
377
unsigned int i, hsize, hmask, num_entries, prev_val, *hash_count;
383
unsigned int total_num_entries, stride, max_entries;
378
unsigned int total_num_entries;
384
379
const unsigned char *data, *buffer;
385
380
struct delta_index *index;
386
381
struct unpacked_index_entry *entry, **hash;
388
383
unsigned long memsize;
390
385
if (!src->buf || !src->size)
391
return DELTA_SOURCE_EMPTY;
392
387
buffer = src->buf;
394
389
/* Determine index hash size. Note that indexing skips the
395
first byte so we subtract 1 to get the edge cases right.
397
stride = RABIN_WINDOW;
390
first byte to allow for optimizing the Rabin's polynomial
391
initialization in create_delta(). */
398
392
num_entries = (src->size - 1) / RABIN_WINDOW;
399
if (max_bytes_to_index > 0) {
400
max_entries = (unsigned int) (max_bytes_to_index / RABIN_WINDOW);
401
if (num_entries > max_entries) {
402
/* Limit the max number of matching entries. This reduces the 'best'
403
* possible match, but means we don't consume all of ram.
405
num_entries = max_entries;
406
stride = (src->size - 1) / num_entries;
410
394
total_num_entries = num_entries + old->num_entries;
435
419
hash_count = calloc(hsize, sizeof(*hash_count));
436
420
if (!hash_count) {
438
return DELTA_OUT_OF_MEMORY;
441
425
/* then populate the index for the new data */
443
for (data = buffer + num_entries * stride - RABIN_WINDOW;
427
for (data = buffer + num_entries * RABIN_WINDOW - RABIN_WINDOW;
429
data -= RABIN_WINDOW) {
446
430
unsigned int val = 0;
447
431
for (i = 1; i <= RABIN_WINDOW; i++)
448
432
val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
466
450
total_num_entries = limit_hash_buckets(hash, hash_count, hsize,
467
451
total_num_entries);
468
452
free(hash_count);
469
456
index = pack_delta_index(hash, hsize, total_num_entries, old);
471
/* pack_delta_index only returns NULL on malloc failure */
473
return DELTA_OUT_OF_MEMORY;
475
461
index->last_src = src;
480
465
/* Take some entries, and put them into a custom hash.
488
473
unsigned int hsize)
490
475
unsigned int hash_offset, hmask, memsize;
491
struct index_entry *entry;
476
struct index_entry *entry, *last_entry;
492
477
struct index_entry_linked_list *out_entry, **hash;
508
493
/* We know that entries are in the order we want in the output, but they
509
494
* aren't "grouped" by hash bucket yet.
496
last_entry = entries + num_entries;
511
497
for (entry = entries + num_entries - 1; entry >= entries; --entry) {
512
498
hash_offset = entry->val & hmask;
513
499
out_entry->p_entry = entry;
532
518
unsigned int i, j, hsize, hmask, total_num_entries;
533
519
struct delta_index *index;
534
520
struct index_entry *entry, *packed_entry, **packed_hash;
535
struct index_entry null_entry = {0};
521
struct index_entry *last_entry, null_entry = {0};
537
523
unsigned long memsize;
538
524
struct index_entry_linked_list *unpacked_entry, **mini_hash;
696
683
create_delta_index_from_delta(const struct source_info *src,
697
struct delta_index *old_index,
698
struct delta_index **fresh)
684
struct delta_index *old_index)
700
686
unsigned int i, num_entries, max_num_entries, prev_val, num_inserted;
701
687
unsigned int hash_offset;
704
690
struct delta_index *new_index;
705
691
struct index_entry *entry, *entries;
708
return DELTA_INDEX_NEEDED;
709
693
if (!src->buf || !src->size)
710
return DELTA_SOURCE_EMPTY;
711
695
buffer = src->buf;
712
696
top = buffer + src->size;
723
707
/* allocate an array to hold whatever entries we find */
724
708
entries = malloc(sizeof(*entry) * max_num_entries);
725
709
if (!entries) /* malloc failure */
726
return DELTA_OUT_OF_MEMORY;
728
712
/* then populate the index for the new data */
792
776
if (data != top) {
793
/* The source_info data passed was corrupted or otherwise invalid */
777
/* Something was wrong with this delta */
795
return DELTA_SOURCE_BAD;
797
781
if (num_entries == 0) {
798
782
/** Nothing to index **/
786
assert(old_index != NULL);
803
787
old_index->last_src = src;
804
788
/* See if we can fill in these values into the holes in the array */
857
841
new_index = create_index_from_old_and_new_entries(old_index,
858
842
entry, num_entries);
860
new_index = old_index;
861
845
// fprintf(stderr, "inserted %d without resizing\n", num_inserted);
864
/* create_index_from_old_and_new_entries returns NULL on malloc failure */
866
return DELTA_OUT_OF_MEMORY;
871
851
void free_delta_index(struct delta_index *index)
889
869
#define MAX_OP_SIZE (5 + 5 + 1 + RABIN_WINDOW + 7)
892
872
create_delta(const struct delta_index *index,
893
873
const void *trg_buf, unsigned long trg_size,
894
unsigned long *delta_size, unsigned long max_size,
874
unsigned long *delta_size, unsigned long max_size)
897
876
unsigned int i, outpos, outsize, moff, val;
1103
1082
if (max_size && outpos > max_size) {
1105
return DELTA_SIZE_TOO_BIG;
1108
1087
*delta_size = outpos;
1115
get_entry_summary(const struct delta_index *index, int pos,
1116
unsigned int *text_offset, unsigned int *hash_val)
1119
const struct index_entry *entry;
1120
const struct index_entry *start_of_entries;
1121
unsigned int offset;
1122
if (pos < 0 || text_offset == NULL || hash_val == NULL
1127
hsize = index->hash_mask + 1;
1128
start_of_entries = (struct index_entry *)(((struct index_entry **)index->hash) + (hsize + 1));
1129
entry = start_of_entries + pos;
1130
if (entry > index->last_entry) {
1133
if (entry->ptr == NULL) {
1137
offset = entry->src->agg_offset;
1138
offset += (entry->ptr - ((unsigned char *)entry->src->buf));
1139
*text_offset = offset;
1140
*hash_val = entry->val;
1147
get_hash_offset(const struct delta_index *index, int pos,
1148
unsigned int *entry_offset)
1151
const struct index_entry *entry;
1152
const struct index_entry *start_of_entries;
1153
if (pos < 0 || index == NULL || entry_offset == NULL)
1157
hsize = index->hash_mask + 1;
1158
start_of_entries = (struct index_entry *)(((struct index_entry **)index->hash) + (hsize + 1));
1162
entry = index->hash[pos];
1163
if (entry == NULL) {
1166
*entry_offset = (entry - start_of_entries);
1173
rabin_hash(const unsigned char *data)
1176
unsigned int val = 0;
1177
for (i = 0; i < RABIN_WINDOW; i++)
1178
val = ((val << 8) | data[i]) ^ T[val >> RABIN_SHIFT];
1182
1091
/* vim: et ts=4 sw=4 sts=4