# HG changeset patch # User Pierre-Yves David # Date 1422633748 0 # Node ID c1ce5442453ff6fe63e7da0f8804db1845ecaf98 # Parent 087603b508897684b1ef929e7b4c395500101353 _adjustlinkrev: reuse ancestors set during rename detection (issue4514) The new linkrev adjustement mechanism makes rename detection very slow, because each file rewalks the ancestor dag. To mitigate the issue in Mercurial 3.3, we introduce a simplistic way to share the ancestors computation for the linkrev validation phase. We can reuse the ancestors in that case because we do not care about sub-branching in the ancestors graph. The cached set will be use to check if the linkrev is valid in the search context. This is the vast majority of the ancestors usage during copies search since the uncached one will only be used when linkrev is invalid, which is hopefully rare. diff -r 087603b50889 -r c1ce5442453f mercurial/context.py --- a/mercurial/context.py Fri Jan 30 14:39:03 2015 +0000 +++ b/mercurial/context.py Fri Jan 30 16:02:28 2015 +0000 @@ -766,10 +766,17 @@ # fetch the linkrev fr = filelog.rev(fnode) lkr = filelog.linkrev(fr) + # hack to reuse ancestor computation when searching for renames + memberanc = getattr(self, '_ancestrycontext', None) + iteranc = None + if memberanc is None: + memberanc = iteranc = cl.ancestors([srcrev], lkr, + inclusive=inclusive) # check if this linkrev is an ancestor of srcrev - anc = cl.ancestors([srcrev], lkr, inclusive=inclusive) - if lkr not in anc: - for a in anc: + if lkr not in memberanc: + if iteranc is None: + iteranc = cl.ancestors([srcrev], lkr, inclusive=inclusive) + for a in iteranc: ac = cl.read(a) # get changeset data (we avoid object creation) if path in ac[3]: # checking the 'files' field. # The file has been touched, check if the content is @@ -826,6 +833,8 @@ rev = self._adjustlinkrev(path, l, fnode, self.rev()) fctx = filectx(self._repo, path, fileid=fnode, filelog=l, changeid=rev) + fctx._ancestrycontext = getattr(self, '_ancestrycontext', None) + else: fctx = filectx(self._repo, path, fileid=fnode, filelog=l) ret.append(fctx) diff -r 087603b50889 -r c1ce5442453f mercurial/copies.py --- a/mercurial/copies.py Fri Jan 30 14:39:03 2015 +0000 +++ b/mercurial/copies.py Fri Jan 30 16:02:28 2015 +0000 @@ -170,8 +170,11 @@ missing = set(b.manifest().iterkeys()) missing.difference_update(a.manifest().iterkeys()) + ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True) for f in missing: - ofctx = _tracefile(b[f], am, limit) + fctx = b[f] + fctx._ancestrycontext = ancestrycontext + ofctx = _tracefile(fctx, am, limit) if ofctx: cm[f] = ofctx.path()