# HG changeset patch # User Denis Laxalde # Date 2017-04-24 16:33:23 # Node ID a457da5296a5ad25c2b5cc22509c3340fd4e48f8 # Parent 51fdedd29b0acca6865ca3128d0e0bf2aa07bf09 context: optimize linkrev adjustment in blockancestors() (issue5538) We set parent._descendantrev = child.rev() when walking parents in blockancestors() so that, when linkrev adjustment is perform for these, it starts from a close descendant instead of possibly topmost introrev. (See `self._adjustlinkrev(self._descendantrev)` in filectx._changeid().) This is similar to changeset c82d88dfaf59, which added a "f._changeid" instruction in annotate() for the same purpose. However, here, we set _descendantrev explicitly instead of relying on the '_changeid' cached property being accessed (with effect to set _changeid attribute) so that, in _parentfilectx() (called from parents()), we go through `if '_changeid' in vars(self) [...]` branch in which instruction `fctx._descendantrev = self.rev()` finally appears and does what we want. With this, we can roughly get a 3x speedup (including in example of issue5538 from mozilla-central repository) on usage of followlines revset (and equivalent hgweb request). diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -1214,6 +1214,10 @@ def blockancestors(fctx, fromline, tolin # introduced in this revision; no need to go futher in this # branch. continue + # Set _descendantrev with 'c' (a known descendant) so that, when + # _adjustlinkrev is called for 'p', it receives this descendant + # (as srcrev) instead possibly topmost introrev. + p._descendantrev = c.rev() visit[p.linkrev(), p.filenode()] = p, linerange1 if inrange: yield c, linerange2