X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/2c713fcdfa04eb7d58c67a4a51d4cbdc37f78536..a3221d2ac14255c31109a617c4d62b949cd910de:/match.c diff --git a/match.c b/match.c index d731aae7..f3858e5b 100644 --- a/match.c +++ b/match.c @@ -23,6 +23,7 @@ extern int verbose; extern int am_server; extern int do_progress; extern int checksum_seed; +extern int inplace; typedef unsigned short tag; @@ -200,6 +201,12 @@ static void hash_search(int f,struct sum_struct *s, if (l != s->sums[i].len) continue; + /* inplace: ensure chunk's offset is either >= our + * offset or that the data didn't move. */ + if (inplace && s->sums[i].offset < offset + && !(s->sums[i].flags & SUMFLG_SAME_OFFSET)) + continue; + if (verbose > 3) rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n", (double)offset,(double)j,(double)i,sum); @@ -215,15 +222,41 @@ static void hash_search(int f,struct sum_struct *s, continue; } + /* If inplace is enabled, the best possible match is + * one with an identical offset, so we prefer that over + * the following want_i optimization. */ + if (inplace) { + do { + size_t i2 = targets[j].i; + if (s->sums[i2].offset != offset) + continue; + if (i2 != i) { + if (sum != s->sums[i2].sum1) + break; + if (memcmp(sum2, s->sums[i2].sum2, + s->s2length) != 0) + break; + i = i2; + } + /* This chunk was at the same offset on + * both the sender and the receiver. */ + s->sums[i].flags |= SUMFLG_SAME_OFFSET; + goto set_want_i; + } while (++j < s->count && targets[j].t == t); + } + /* we've found a match, but now check to see * if want_i can hint at a better match. */ if (i != want_i && want_i < s->count + && (!inplace || s->sums[want_i].offset >= offset + || s->sums[want_i].flags & SUMFLG_SAME_OFFSET) && sum == s->sums[want_i].sum1 && memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) { /* we've found an adjacent match - the RLL coder * will be happy */ i = want_i; } + set_want_i: want_i = i + 1; matched(f,s,buf,offset,i);