aboutsummaryrefslogtreecommitdiffstats
path: root/match.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2004-07-16 20:06:24 +0000
committerWayne Davison <wayned@samba.org>2004-07-16 20:06:24 +0000
commita3221d2ac14255c31109a617c4d62b949cd910de (patch)
tree772859b7d2bfc494a1abbf8c43ff0cc94de9acc3 /match.c
parent2c713fcdfa04eb7d58c67a4a51d4cbdc37f78536 (diff)
downloadandroid_external_rsync-a3221d2ac14255c31109a617c4d62b949cd910de.tar.gz
android_external_rsync-a3221d2ac14255c31109a617c4d62b949cd910de.tar.bz2
android_external_rsync-a3221d2ac14255c31109a617c4d62b949cd910de.zip
My version of Mark Curtis's --inplace option.
Diffstat (limited to 'match.c')
-rw-r--r--match.c33
1 files changed, 33 insertions, 0 deletions
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);