Added a "chain" item to the struct sum_buf.
[rsync/rsync.git] / match.c
diff --git a/match.c b/match.c
index 55c6d13..eae3d14 100644 (file)
--- a/match.c
+++ b/match.c
 #include "rsync.h"
 
 extern int verbose;
-extern int am_server;
 extern int do_progress;
 extern int checksum_seed;
+extern int append_mode;
 
 int updating_basis_file;
 
 typedef unsigned short tag;
 
 #define TABLESIZE (1<<16)
-#define NULL_TAG ((size_t)-1)
+#define NULL_TAG (-1)
 
 static int false_alarms;
 static int tag_hits;
@@ -44,12 +44,12 @@ extern struct stats stats;
 
 struct target {
        tag t;
-       size_t i;
+       int32 i;
 };
 
 static struct target *targets;
 
-static size_t *tag_table;
+static int32 *tag_table;
 
 #define gettag2(s1,s2) (((s1) + (s2)) & 0xFFFF)
 #define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
@@ -62,10 +62,10 @@ static int compare_targets(struct target *t1,struct target *t2)
 
 static void build_hash_table(struct sum_struct *s)
 {
-       size_t i;
+       int32 i;
 
        if (!tag_table)
-               tag_table = new_array(size_t, TABLESIZE);
+               tag_table = new_array(int32, TABLESIZE);
 
        targets = new_array(struct target, s->count);
        if (!tag_table || !targets)
@@ -102,7 +102,7 @@ static OFF_T last_match;
  * have only literal data.
  **/
 static void matched(int f, struct sum_struct *s, struct map_struct *buf,
-                   OFF_T offset, int i)
+                   OFF_T offset, int32 i)
 {
        int32 n = offset - last_match; /* max value: block_size (int32) */
        int32 j;
@@ -127,18 +127,13 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
                sum_update(map_ptr(buf, last_match + j, n1), n1);
        }
 
-
        if (i >= 0)
                last_match = offset + s->sums[i].len;
        else
                last_match = offset;
 
-       if (buf && do_progress) {
+       if (buf && do_progress)
                show_progress(last_match, buf->file_size);
-
-               if (i == -1)
-                       end_progress(buf->file_size);
-       }
 }
 
 
@@ -146,8 +141,7 @@ static void hash_search(int f,struct sum_struct *s,
                        struct map_struct *buf, OFF_T len)
 {
        OFF_T offset, end, backup;
-       int32 k;
-       size_t want_i;
+       int32 k, want_i;
        char sum2[SUM_LENGTH];
        uint32 s1, s2, sum;
        int more;
@@ -184,7 +178,7 @@ static void hash_search(int f,struct sum_struct *s,
        do {
                tag t = gettag2(s1,s2);
                int done_csum2 = 0;
-               size_t j = tag_table[t];
+               int32 j = tag_table[t];
 
                if (verbose > 4)
                        rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
@@ -195,8 +189,7 @@ static void hash_search(int f,struct sum_struct *s,
                sum = (s1 & 0xffff) | (s2 << 16);
                tag_hits++;
                do {
-                       int32 l;
-                       size_t i = targets[j].i;
+                       int32 l, i = targets[j].i;
 
                        if (sum != s->sums[i].sum1)
                                continue;
@@ -232,7 +225,7 @@ static void hash_search(int f,struct sum_struct *s,
                         * the following want_i optimization. */
                        if (updating_basis_file) {
                                do {
-                                       size_t i2 = targets[j].i;
+                                       int32 i2 = targets[j].i;
                                        if (s->sums[i2].offset != offset)
                                                continue;
                                        if (i2 != i) {
@@ -336,6 +329,25 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
 
        sum_init(checksum_seed);
 
+       if (append_mode) {
+               OFF_T j = 0;
+               for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
+                       if (buf && do_progress)
+                               show_progress(last_match, buf->file_size);
+                       sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
+                                  CHUNK_SIZE);
+                       last_match = j;
+               }
+               if (last_match < s->flength) {
+                       int32 len = s->flength - last_match;
+                       if (buf && do_progress)
+                               show_progress(last_match, buf->file_size);
+                       sum_update(map_ptr(buf, last_match, len), len);
+                       last_match = s->flength;
+               }
+               s->count = 0;
+       }
+
        if (len > 0 && s->count > 0) {
                build_hash_table(s);
 
@@ -349,7 +361,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
        } else {
                OFF_T j;
                /* by doing this in pieces we avoid too many seeks */
-               for (j = CHUNK_SIZE; j < len; j += CHUNK_SIZE)
+               for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
                        matched(f, s, buf, j, -2);
                matched(f, s, buf, len, -1);
        }