[Top][All Lists]
[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;
}
- Optimal buffer size for copy, neillm, 2003/11/04
- Re: Optimal buffer size for copy, Paul Eggert, 2003/11/04
- Re: Optimal buffer size for copy, neillm, 2003/11/06
- Re: Optimal buffer size for copy, Paul Eggert, 2003/11/05
- Re: Optimal buffer size for copy, neillm, 2003/11/06
- Re: Optimal buffer size for copy, Paul Eggert, 2003/11/06
- Re: Optimal buffer size for copy, neillm, 2003/11/07
- Re: Optimal buffer size for copy, Paul Eggert, 2003/11/06
- Re: Optimal buffer size for copy,
neillm <=
- Re: Optimal buffer size for copy, neillm, 2003/11/25