diff -r b8b4a2417fbd -r 05deba16c5d5 mercurial/util.py --- a/mercurial/util.py Wed Aug 04 13:21:11 2010 -0500 +++ b/mercurial/util.py Fri Aug 06 12:59:13 2010 -0500 @@ -925,30 +925,36 @@ else: yield chunk self.iter = splitbig(in_iter) - self.buf = '' + self._queue = [] def read(self, l): """Read L bytes of data from the iterator of chunks of data. Returns less than L bytes if the iterator runs dry.""" - if l > len(self.buf) and self.iter: - # Clamp to a multiple of 2**16 - targetsize = max(l, 2**16) - collector = [str(self.buf)] - collected = len(self.buf) - for chunk in self.iter: - collector.append(chunk) - collected += len(chunk) - if collected >= targetsize: + left = l + buf = '' + queue = self._queue + while left > 0: + # refill the queue + if not queue: + target = 2**18 + for chunk in self.iter: + queue.append(chunk) + target -= len(chunk) + if target <= 0: + break + if not queue: break + + chunk = queue.pop(0) + left -= len(chunk) + if left < 0: + queue.insert(0, chunk[left:]) + buf += chunk[:left] else: - self.iter = False - self.buf = ''.join(collector) - if len(self.buf) == l: - s, self.buf = str(self.buf), '' - else: - s, self.buf = self.buf[:l], buffer(self.buf, l) - return s + buf += chunk + return buf + def filechunkiter(f, size=65536, limit=None): """Create a generator that produces the data in the file size (default 65536) bytes at a time, up to optional limit (default is