added write buffering during the file list sending. This makes things
authorAndrew Tridgell <tridge@samba.org>
Fri, 15 May 1998 07:34:19 +0000 (07:34 +0000)
committerAndrew Tridgell <tridge@samba.org>
Fri, 15 May 1998 07:34:19 +0000 (07:34 +0000)
a bit more efficient (less system calls)

flist.c
io.c
rsync.h

diff --git a/flist.c b/flist.c
index 4c2e984..d7da6e8 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -573,6 +573,10 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                                                     flist->malloced);
        if (!flist->files) out_of_memory("send_file_list");
 
+       if (f != -1) {
+               io_start_buffering(f);
+       }
+
        for (i=0;i<argc;i++) {
                char fname2[MAXPATHLEN];
                char *fname = fname2;
@@ -658,7 +662,6 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
 
        if (f != -1) {
                send_file_entry(NULL,f,0);
-               write_flush(f);
        }
 
        if (verbose && recurse && !am_server && f != -1)
@@ -677,6 +680,11 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                write_int(f, io_error);
        }
 
+       if (f != -1) {
+               io_end_buffering(f);
+               write_flush(f);
+       }
+
        if (verbose > 2)
                rprintf(FINFO,"send_file_list done\n");
 
diff --git a/io.c b/io.c
index 52c4cb1..1fafaa6 100644 (file)
--- a/io.c
+++ b/io.c
@@ -301,7 +301,7 @@ int write_file(int f,char *buf,int len)
 }
 
 
-static int writefd(int fd,char *buf,int len)
+static int writefd_unbuffered(int fd,char *buf,int len)
 {
   int total = 0;
   fd_set w_fds, r_fds;
@@ -375,6 +375,58 @@ static int writefd(int fd,char *buf,int len)
   return total;
 }
 
+static char *io_buffer;
+static int io_buffer_count;
+
+void io_start_buffering(int fd)
+{
+       io_buffer = (char *)malloc(IO_BUFFER_SIZE);
+       if (!io_buffer) out_of_memory("writefd");
+       io_buffer_count = 0;
+}
+
+void io_end_buffering(int fd)
+{
+       if (io_buffer_count) {
+               if (writefd_unbuffered(fd, io_buffer, 
+                                      io_buffer_count) != 
+                   io_buffer_count) {
+                       rprintf(FERROR,"write failed\n");
+                       exit_cleanup(1);
+               }
+               io_buffer_count = 0;
+       }
+       free(io_buffer);
+       io_buffer = NULL;
+}
+
+static int writefd(int fd,char *buf,int len1)
+{
+       int len = len1;
+
+       if (!io_buffer) return writefd_unbuffered(fd, buf, len);
+
+       while (len) {
+               int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
+               if (n > 0) {
+                       memcpy(io_buffer+io_buffer_count, buf, n);
+                       buf += n;
+                       len -= n;
+                       io_buffer_count += n;
+               }
+               
+               if (io_buffer_count == IO_BUFFER_SIZE) {
+                       if (writefd_unbuffered(fd, io_buffer, 
+                                              io_buffer_count) != 
+                           io_buffer_count) {
+                               return -1;
+                       }
+                       io_buffer_count = 0;
+               }
+       }
+
+       return len1;
+}
 
 
 void write_int(int f,int32 x)
diff --git a/rsync.h b/rsync.h
index 1311670..187ef37 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -51,6 +51,7 @@
 #define WRITE_SIZE (32*1024)
 #define CHUNK_SIZE (32*1024)
 #define MAX_MAP_SIZE (4*1024*1024)
+#define IO_BUFFER_SIZE (4096)
 
 #define MAX_ARGS 1000