]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
Initial version, from diffutils
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 24 Nov 2005 06:48:03 +0000 (06:48 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Thu, 24 Nov 2005 06:48:03 +0000 (06:48 +0000)
lib/buffer-lcm.c [new file with mode: 0644]

diff --git a/lib/buffer-lcm.c b/lib/buffer-lcm.c
new file mode 100644 (file)
index 0000000..c3f6109
--- /dev/null
@@ -0,0 +1,59 @@
+/* buffer-lcm.c - compute a good buffer size for dealing with two files
+
+   Copyright (C) 2002, 2005 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; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/* Written by Paul Eggert.  */
+
+#include "buffer-lcm.h"
+
+/* Return a buffer size suitable for doing I/O with files whose block
+   sizes are A and B.  However, never return a value greater than
+   LCM_MAX.  */
+
+size_t
+buffer_lcm (size_t a, size_t b, size_t lcm_max)
+{
+  size_t size;
+
+  /* Use reasonable values if buffer sizes are zero.  */
+  if (!a)
+    size = b ? b : 8 * 1024;
+  else
+    {
+      if (b)
+       {
+         /* Return lcm (A, B) if it is in range; otherwise, fall back
+            on A.  */
+
+         size_t lcm, m, n, q, r;
+
+         /* N = gcd (A, B).  */
+         for (m = a, n = b;  (r = m % n) != 0;  m = n, n = r)
+           continue;
+
+         /* LCM = lcm (A, B), if in range.  */
+         q = a / n;
+         lcm = q * b;
+         if (lcm <= lcm_max && lcm / b == q)
+           return lcm;
+       }
+
+      size = a;
+    }
+
+  return size <= lcm_max ? size : lcm_max;
+}