bufferedinputpipe: remove N^2 computation of buffer length (issue4735)
authorPierre-Yves David <pierre-yves.david@fb.com>
Fri, 26 Jun 2015 11:29:50 -0700
changeset 25672 050dc6eabc92
parent 25671 d5ac3bebaf2a
child 25673 fa1f04529775
bufferedinputpipe: remove N^2 computation of buffer length (issue4735) The assumption that dynamically computing the length of the buffer was N^2, but negligible because fast was False. So we drop the dynamic computation and manually keep track of the buffer length.
mercurial/util.py
--- a/mercurial/util.py	Sat Jun 27 11:51:25 2015 -0700
+++ b/mercurial/util.py	Fri Jun 26 11:29:50 2015 -0700
@@ -254,6 +254,7 @@
         self._input = input
         self._buffer = []
         self._eof = False
+        self._lenbuf = 0
 
     @property
     def hasbuffer(self):
@@ -283,6 +284,7 @@
             # this should not happen because both read and readline end with a
             # _frombuffer call that collapse it.
             self._buffer = [''.join(self._buffer)]
+            self._lenbuf = len(self._buffer[0])
         lfi = -1
         if self._buffer:
             lfi = self._buffer[-1].find('\n')
@@ -298,11 +300,6 @@
             size += self._lenbuf - len(self._buffer[-1])
         return self._frombuffer(size)
 
-    @property
-    def _lenbuf(self):
-        """return the current lengh of buffered data"""
-        return sum(len(d) for d in self._buffer)
-
     def _frombuffer(self, size):
         """return at most 'size' data from the buffer
 
@@ -317,8 +314,10 @@
         buf = buf[len(data):]
         if buf:
             self._buffer = [buf]
+            self._lenbuf = len(buf)
         else:
             self._buffer = []
+            self._lenbuf = 0
         return data
 
     def _fillbuffer(self):
@@ -327,6 +326,7 @@
         if not data:
             self._eof = True
         else:
+            self._lenbuf += len(data)
             self._buffer.append(data)
 
 def popen2(cmd, env=None, newlines=False):