Mercurial > hg
diff mercurial/httpclient/_readers.py @ 19037:1fde25ad9396
http2: make read use pushchunk/popchunk, eschew itertools
The itertools approach was showing up high in the profile output.
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Fri, 01 Feb 2013 14:41:35 -0800 |
parents | 19d1cc30e7a3 |
children | 36733ab7fa05 |
line wrap: on
line diff
--- a/mercurial/httpclient/_readers.py Fri Feb 01 14:41:33 2013 -0800 +++ b/mercurial/httpclient/_readers.py Fri Feb 01 14:41:35 2013 -0800 @@ -79,22 +79,21 @@ def read(self, amt): if self.available_data < amt and not self._finished: raise ReadNotReady() - need = [amt] - def pred(s): - needed = need[0] > 0 - need[0] -= len(s) - return needed - blocks = list(itertools.takewhile(pred, self._done_chunks)) - self._done_chunks = self._done_chunks[len(blocks):] - over_read = sum(map(len, blocks)) - amt - if over_read > 0 and blocks: - logger.debug('need to reinsert %d data into done chunks', over_read) - last = blocks[-1] - blocks[-1], reinsert = last[:-over_read], last[-over_read:] - self._done_chunks.insert(0, reinsert) + blocks = [] + need = amt + while self._done_chunks: + b = self.popchunk() + if len(b) > need: + nb = b[:need] + self.pushchunk(b[need:]) + b = nb + blocks.append(b) + need -= len(b) + if need == 0: + break result = ''.join(blocks) assert len(result) == amt or (self._finished and len(result) < amt) - self.available_data -= amt + return result def _load(self, data): # pragma: no cover