##// END OF EJS Templates
util.chunkbuffer: avoid extra mutations when reading partial chunks...
Gregory Szorc -
r26480:6ae14d1c default
parent child Browse files
Show More
@@ -1286,6 +1286,7 class chunkbuffer(object):
1286 1286 yield chunk
1287 1287 self.iter = splitbig(in_iter)
1288 1288 self._queue = collections.deque()
1289 self._chunkoffset = 0
1289 1290
1290 1291 def read(self, l=None):
1291 1292 """Read L bytes of data from the iterator of chunks of data.
@@ -1310,20 +1311,40 class chunkbuffer(object):
1310 1311 if not queue:
1311 1312 break
1312 1313
1314 # The easy way to do this would be to queue.popleft(), modify the
1315 # chunk (if necessary), then queue.appendleft(). However, for cases
1316 # where we read partial chunk content, this incurs 2 dequeue
1317 # mutations and creates a new str for the remaining chunk in the
1318 # queue. Our code below avoids this overhead.
1319
1313 1320 chunk = queue[0]
1314 1321 chunkl = len(chunk)
1322 offset = self._chunkoffset
1315 1323
1316 1324 # Use full chunk.
1317 if left >= chunkl:
1325 if offset == 0 and left >= chunkl:
1318 1326 left -= chunkl
1319 1327 queue.popleft()
1320 1328 buf.append(chunk)
1329 # self._chunkoffset remains at 0.
1330 continue
1331
1332 chunkremaining = chunkl - offset
1333
1334 # Use all of unconsumed part of chunk.
1335 if left >= chunkremaining:
1336 left -= chunkremaining
1337 queue.popleft()
1338 # offset == 0 is enabled by block above, so this won't merely
1339 # copy via ``chunk[0:]``.
1340 buf.append(chunk[offset:])
1341 self._chunkoffset = 0
1342
1321 1343 # Partial chunk needed.
1322 1344 else:
1323 left -= chunkl
1324 queue.popleft()
1325 queue.appendleft(chunk[left:])
1326 buf.append(chunk[:left])
1345 buf.append(chunk[offset:offset + left])
1346 self._chunkoffset += left
1347 left -= chunkremaining
1327 1348
1328 1349 return ''.join(buf)
1329 1350
General Comments 0
You need to be logged in to leave comments. Login now