
1: /* buffer-lcm.c - compute a good buffer size for dealing with two files 2: 3: Copyright (C) 2002, 2005 Free Software Foundation, Inc. 4: 5: This program is free software; you can redistribute it and/or modify 6: it under the terms of the GNU General Public License as published by 7: the Free Software Foundation; either version 2, or (at your option) 8: any later version. 9: 10: This program is distributed in the hope that it will be useful, 11: but WITHOUT ANY WARRANTY; without even the implied warranty of 12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13: GNU General Public License for more details. 14: 15: You should have received a copy of the GNU General Public License 16: along with this program; if not, write to the Free Software Foundation, 17: Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18: 19: /* Written by Paul Eggert. */ 20: 21: #include "buffer-lcm.h" 22: 23: /* Return a buffer size suitable for doing I/O with files whose block 24: sizes are A and B. However, never return a value greater than 25: LCM_MAX. */ 26: 27: size_t 28: buffer_lcm (size_t a, size_t b, size_t lcm_max) 29: { 30: size_t size; 31: 32: /* Use reasonable values if buffer sizes are zero. */ 33: if (!a) 34: size = b ? b : 8 * 1024; 35: else 36: { 37: if (b) 38: { 39: /* Return lcm (A, B) if it is in range; otherwise, fall back 40: on A. */ 41: 42: size_t lcm, m, n, q, r; 43: 44: /* N = gcd (A, B). */ 45: for (m = a, n = b; (r = m % n) != 0; m = n, n = r) 46: continue; 47: 48: /* LCM = lcm (A, B), if in range. */ 49: q = a / n; 50: lcm = q * b; 51: if (lcm <= lcm_max && lcm / b == q) 52: return lcm; 53: } 54: 55: size = a; 56: } 57: 58: return size <= lcm_max ? size : lcm_max; 59: }