# HG changeset patch # User Boris Feld <boris.f...@octobus.net> # Date 1536254177 14400 # Thu Sep 06 13:16:17 2018 -0400 # Node ID a4c3eb6c1a36cbbf64fa8930b173154b2e77ef2b # Parent 9a18509c522deeb62a7b244dcf4c7b79a8dc1132 # EXP-Topic copy-perf # Available At https://bitbucket.org/octobus/mercurial-devel/ # hg pull https://bitbucket.org/octobus/mercurial-devel/ -r a4c3eb6c1a36 context: fix introrev to avoid computation as initially intended
The `filerev.introrev()` method has various logic be as efficient as possible. In particular, it tries to restrict the range covered by the `ctx._adjustlinkrev(...)` call. However, it does so using the value returned by `ctx.rev()`. In some case (eg: copy tracing), that `ctx.rev()` call would do an `_adjustlinkrev(...)` call on its own, defeating the optimization purpose and doing the computation twice. We are about to improve graph traversal associated with copy tracing using code based on `ctx.introrev()`, so we need this fixed before proceeding further. diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -829,6 +829,23 @@ class basefilectx(object): # result is crash somewhere else at to some point. return lkr + def _lazyrev(self): + """return self.rev() if it is available without computation, + + If finding the rev would trigger a possibly expensive computation, we + return None.""" + attrs = vars(self) + if r'_changeid' in attrs: + # We have a cached value already + return self.rev() + elif r'_changectx' in attrs: + # We know which changelog entry we are coming from + return self.rev() + elif r'_descendantrev' not in attrs: + # we have no context, so linkrev will be used + return self.rev() + return None + def introrev(self): """return the rev of the changeset which introduced this file revision @@ -839,11 +856,14 @@ class basefilectx(object): changesets. """ lkr = self.linkrev() - attrs = vars(self) - noctx = not (r'_changeid' in attrs or r'_changectx' in attrs) - if noctx or self.rev() == lkr: - return self.linkrev() - return self._adjustlinkrev(self.rev(), inclusive=True) + lazyrev = self._lazyrev() + if lazyrev is not None: + if lazyrev == lkr: + return lazyrev + else: + return self._adjustlinkrev(lazyrev, inclusive=True) + else: + return self.rev() def introfilectx(self): """Return filectx having identical contents, but pointing to the _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel