Patchwork D4150: linelog: optimize replacelines

login
register
mail settings
Submitter phabricator
Date Aug. 9, 2018, 6:06 p.m.
Message ID <ef72fa7b6e5577b97d2679225a6f16d8@localhost.localdomain>
Download mbox | patch
Permalink /patch/33483/
State Not Applicable
Headers show

Comments

phabricator - Aug. 9, 2018, 6:06 p.m.
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGee97f7a677f3: linelog: optimize replacelines (authored by quark, committed by ).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D4150?vs=10067&id=10135

REVISION DETAIL
  https://phab.mercurial-scm.org/D4150

AFFECTED FILES
  mercurial/linelog.py

CHANGE DETAILS




To: quark, #hg-reviewers, durin42
Cc: durin42, mercurial-devel

Patch

diff --git a/mercurial/linelog.py b/mercurial/linelog.py
--- a/mercurial/linelog.py
+++ b/mercurial/linelog.py
@@ -313,17 +313,22 @@ 
         appendinst = self._program.append
 
         # insert
+        blineinfos = []
+        bappend = blineinfos.append
         if b1 < b2:
             # Determine the jump target for the JGE at the start of
             # the new block.
             tgt = oldproglen + (b2 - b1 + 1)
             # Jump to skip the insert if we're at an older revision.
             appendinst(_jl(rev, tgt))
             for linenum in pycompat.xrange(b1, b2):
                 if _internal_blines is None:
+                    bappend(lineinfo(rev, linenum, programlen()))
                     appendinst(_line(rev, linenum))
                 else:
-                    appendinst(_line(*_internal_blines[linenum]))
+                    newrev, newlinenum = _internal_blines[linenum]
+                    bappend(lineinfo(newrev, newlinenum, programlen()))
+                    appendinst(_line(newrev, newlinenum))
         # delete
         if a1 < a2:
             if a2 > len(ar.lines):
@@ -342,19 +347,26 @@ 
                 endaddr = ar.lines[a2 - 1]._offset + 1
             appendinst(_jge(rev, endaddr))
         # copy instruction from a1
+        a1instpc = programlen()
         appendinst(a1inst)
         # if a1inst isn't a jump or EOF, then we need to add an unconditional
         # jump back into the program here.
         if not isinstance(a1inst, (_jump, _eof)):
             appendinst(_jump(0, a1info._offset + 1))
         # Patch instruction at a1, which makes our patch live.
         self._program[a1info._offset] = _jump(0, oldproglen)
-        # For compat with the C version, re-annotate rev so that
-        # self.annotateresult is cromulent.. We could fix up the
-        # annotateresult in place (which is how the C version works),
-        # but for now we'll pass on that and see if it matters in
-        # practice.
-        self.annotate(max(self._lastannotate.rev, rev))
+
+        # Update self._lastannotate in place. This serves as a cache to avoid
+        # expensive "self.annotate" in this function, when "replacelines" is
+        # used continuously.
+        if len(self._lastannotate.lines) > a1:
+            self._lastannotate.lines[a1]._offset = a1instpc
+        else:
+            assert isinstance(a1inst, _eof)
+            self._lastannotate._eof = a1instpc
+        self._lastannotate.lines[a1:a2] = blineinfos
+        self._lastannotate.rev = max(self._lastannotate.rev, rev)
+
         if rev > self._maxrev:
             self._maxrev = rev