bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Optimal buffer size for copy


From: neillm
Subject: Re: Optimal buffer size for copy
Date: Fri, 7 Nov 2003 14:05:37 -0600
User-agent: Mutt/1.5.4i

Hello Paul,

On Thu, Nov 06, 2003 at 04:44:22PM -0800, Paul Eggert wrote:
> Yes, I'd say a new one.  It's more of a pain, but it's the "right way"
> to do it.

Perhaps the following patch is acceptable?


Best regards,
-Neill.



diff -N -P -r -u --exclude='aclocal*' --exclude=Makefile.in --exclude=Makefile 
--exclude='conf*' --exclude='auto*' --exclude='*doc*' --exclude='*man*' 
coreutils-5.0.91/lib/buffer-lcm.c coreutils-5.0.91-patched/lib/buffer-lcm.c
--- coreutils-5.0.91/lib/buffer-lcm.c   1969-12-31 18:00:00.000000000 -0600
+++ coreutils-5.0.91-patched/lib/buffer-lcm.c   2003-11-07 14:01:48.000000000 
-0600
@@ -0,0 +1,48 @@
+/* buffer-lcm.c - an lcm routine used for computing optimal buffer size
+
+   Copyright (C) 1993, 1995, 1998, 2001-2003 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING.
+   If not, write to the Free Software Foundation,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+/* Least common multiple of two buffer sizes A and B.  However, if
+   either A or B is zero, or if the multiple is greater than LCM_MAX,
+   return a reasonable buffer size.
+
+   This method was integrated from diffutils/lib/cmpbuf.c */
+
+#include <sys/types.h>
+
+size_t
+buffer_lcm (size_t a, size_t b, size_t lcm_max)
+{
+    size_t lcm, m, n, q, r;
+
+    /* Yield reasonable values if buffer sizes are zero.  */
+    if (!a)
+        return b ? b : 8 * 1024;
+    if (!b)
+        return a;
+
+    /* n = gcd (a, b) */
+    for (m = a, n = b;  (r = m % n) != 0;  m = n, n = r)
+        continue;
+
+    /* Yield a if there is an overflow.  */
+    q = a / n;
+    lcm = q * b;
+    return lcm <= lcm_max && lcm / b == q ? lcm : a;
+}
diff -N -P -r -u --exclude='aclocal*' --exclude=Makefile.in --exclude=Makefile 
--exclude='conf*' --exclude='auto*' --exclude='*doc*' --exclude='*man*' 
coreutils-5.0.91/lib/buffer-lcm.h coreutils-5.0.91-patched/lib/buffer-lcm.h
--- coreutils-5.0.91/lib/buffer-lcm.h   1969-12-31 18:00:00.000000000 -0600
+++ coreutils-5.0.91-patched/lib/buffer-lcm.h   2003-11-07 11:24:55.000000000 
-0600
@@ -0,0 +1,20 @@
+/* buffer-lcm.h - an lcm routine used for computing optimal buffer size
+
+   Copyright (C) 1993, 1995, 1998, 2001-2003 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; see the file COPYING.
+   If not, write to the Free Software Foundation,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+size_t buffer_lcm (size_t a, size_t b, size_t lcm_max);
diff -N -P -r -u --exclude='aclocal*' --exclude=Makefile.in --exclude=Makefile 
--exclude='conf*' --exclude='auto*' --exclude='*doc*' --exclude='*man*' 
coreutils-5.0.91/lib/Makefile.am coreutils-5.0.91-patched/lib/Makefile.am
--- coreutils-5.0.91/lib/Makefile.am    2003-08-17 02:51:23.000000000 -0500
+++ coreutils-5.0.91-patched/lib/Makefile.am    2003-11-07 11:26:12.000000000 
-0600
@@ -42,6 +42,7 @@
   argmatch.c argmatch.h \
   backupfile.c backupfile.h \
   basename.c \
+  buffer-lcm.c buffer-lcm.h \
   canon-host.c \
   canonicalize.h \
   closeout.c closeout.h \
diff -N -P -r -u --exclude='aclocal*' --exclude=Makefile.in --exclude=Makefile 
--exclude='conf*' --exclude='auto*' --exclude='*doc*' --exclude='*man*' 
coreutils-5.0.91/src/copy.c coreutils-5.0.91-patched/src/copy.c
--- coreutils-5.0.91/src/copy.c 2003-08-30 10:57:32.000000000 -0500
+++ coreutils-5.0.91-patched/src/copy.c 2003-11-07 11:17:43.000000000 -0600
@@ -42,6 +42,7 @@
 #include "same.h"
 #include "utimens.h"
 #include "xreadlink.h"
+#include "buffer-lcm.h"
 
 #define DO_CHOWN(Chown, File, New_uid, New_gid)                                
\
   (Chown (File, New_uid, New_gid)                                      \
@@ -285,7 +286,7 @@
       goto close_src_and_dst_desc;
     }
 
-  buf_size = ST_BLKSIZE (sb);
+  buf_size = buffer_lcm(ST_BLKSIZE (sb), ST_BLKSIZE (src_open_sb), SIZE_MAX);
 
 #if HAVE_STRUCT_STAT_ST_BLOCKS
   if (x->sparse_mode == SPARSE_AUTO && S_ISREG (sb.st_mode))
diff -N -P -r -u --exclude='aclocal*' --exclude=Makefile.in --exclude=Makefile 
--exclude='conf*' --exclude='auto*' --exclude='*doc*' --exclude='*man*' 
coreutils-5.0.91/src/od.c coreutils-5.0.91-patched/src/od.c
--- coreutils-5.0.91/src/od.c   2003-07-23 02:26:48.000000000 -0500
+++ coreutils-5.0.91-patched/src/od.c   2003-11-07 11:17:41.000000000 -0600
@@ -27,6 +27,7 @@
 #include "error.h"
 #include "posixver.h"
 #include "xstrtol.h"
+#include "buffer-lcm.h"
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "od"
@@ -371,33 +372,6 @@
   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
-/* Compute the greatest common denominator of U and V
-   using Euclid's algorithm.  */
-
-static unsigned int
-gcd (unsigned int u, unsigned int v)
-{
-  unsigned int t;
-  while (v != 0)
-    {
-      t = u % v;
-      u = v;
-      v = t;
-    }
-  return u;
-}
-
-/* Compute the least common multiple of U and V.  */
-
-static unsigned int
-lcm (unsigned int u, unsigned int v)
-{
-  unsigned int t = gcd (u, v);
-  if (t == 0)
-    return 0;
-  return u * v / t;
-}
-
 static void
 print_s_char (size_t n_bytes, const char *block, const char *fmt_string)
 {
@@ -1355,7 +1329,7 @@
   int l_c_m = 1;
 
   for (i = 0; i < n_specs; i++)
-    l_c_m = lcm (l_c_m, width_bytes[(int) spec[i].size]);
+    l_c_m = buffer_lcm (l_c_m, width_bytes[(int) spec[i].size], SIZE_MAX);
   return l_c_m;
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]