]> git.ipfire.org Git - thirdparty/rsync.git/commitdiff
If f_name_cmp() discovers that two directory strings compare to an
authorWayne Davison <wayned@samba.org>
Mon, 14 Feb 2005 01:29:17 +0000 (01:29 +0000)
committerWayne Davison <wayned@samba.org>
Mon, 14 Feb 2005 01:29:17 +0000 (01:29 +0000)
equal value without being equal pointers, substitute one of the
pointers for the other in the file list.  This optimizes future name
comparisons.  Note also that this optimization won't be triggered
very often (because rsync tends to send the names grouped by dir-
name at transmission time), but it's nice to be able to assume that
all files in the same dir have identical dir-name pointers after the
qsort is finished.

flist.c

diff --git a/flist.c b/flist.c
index 731ffee97a97de127d06e61c48007e0140e14304..113592900b8bd820777355b54f584bc78d02cdd8 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -75,7 +75,7 @@ int io_error;
 
 static char empty_sum[MD4_SUM_LENGTH];
 static unsigned int file_struct_len;
-static struct file_list *received_flist;
+static struct file_list *received_flist, *sorting_flist;
 static dev_t filesystem_dev; /* used to implement -x */
 static int deletion_count = 0; /* used to implement --max-delete */
 
@@ -1449,8 +1449,10 @@ static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
        if (!flist || flist->count == 0)
                return;
 
+       sorting_flist = flist;
        qsort(flist->files, flist->count,
            sizeof flist->files[0], (int (*)())file_compare);
+       sorting_flist = NULL;
 
        for (i = no_dups? 0 : flist->count; i < flist->count; i++) {
                if (flist->files[i]->basename) {
@@ -1671,6 +1673,18 @@ int f_name_cmp(struct file_struct *f1, struct file_struct *f2)
                if (!*c2) {
                        switch (state2) {
                        case s_DIR:
+                               if (state1 == s_SLASH && sorting_flist) {
+                                       int j;
+                                       /* Optimize for future comparisons. */
+                                       for (j = 0;
+                                            j < sorting_flist->count;
+                                            j++) {
+                                               struct file_struct *fp
+                                                   = sorting_flist->files[j];
+                                               if (fp->dirname == f2->dirname)
+                                                       fp->dirname = f1->dirname;
+                                       }
+                               }
                                state2 = s_SLASH;
                                c2 = (uchar*)"/";
                                break;