Mercurial > public > mercurial-scm > hg
comparison mercurial/context.py @ 23980:c1ce5442453f stable
_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.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Fri, 30 Jan 2015 16:02:28 +0000 |
parents | 087603b50889 |
children | 24b57c3899f8 |
comparison
equal
deleted
inserted
replaced
23979:087603b50889 | 23980:c1ce5442453f |
---|---|
764 cl = repo.unfiltered().changelog | 764 cl = repo.unfiltered().changelog |
765 ma = repo.manifest | 765 ma = repo.manifest |
766 # fetch the linkrev | 766 # fetch the linkrev |
767 fr = filelog.rev(fnode) | 767 fr = filelog.rev(fnode) |
768 lkr = filelog.linkrev(fr) | 768 lkr = filelog.linkrev(fr) |
769 # hack to reuse ancestor computation when searching for renames | |
770 memberanc = getattr(self, '_ancestrycontext', None) | |
771 iteranc = None | |
772 if memberanc is None: | |
773 memberanc = iteranc = cl.ancestors([srcrev], lkr, | |
774 inclusive=inclusive) | |
769 # check if this linkrev is an ancestor of srcrev | 775 # check if this linkrev is an ancestor of srcrev |
770 anc = cl.ancestors([srcrev], lkr, inclusive=inclusive) | 776 if lkr not in memberanc: |
771 if lkr not in anc: | 777 if iteranc is None: |
772 for a in anc: | 778 iteranc = cl.ancestors([srcrev], lkr, inclusive=inclusive) |
779 for a in iteranc: | |
773 ac = cl.read(a) # get changeset data (we avoid object creation) | 780 ac = cl.read(a) # get changeset data (we avoid object creation) |
774 if path in ac[3]: # checking the 'files' field. | 781 if path in ac[3]: # checking the 'files' field. |
775 # The file has been touched, check if the content is | 782 # The file has been touched, check if the content is |
776 # similar to the one we search for. | 783 # similar to the one we search for. |
777 if fnode == ma.readfast(ac[0]).get(path): | 784 if fnode == ma.readfast(ac[0]).get(path): |
824 # fed), ensure the created filectx is associated with a | 831 # fed), ensure the created filectx is associated with a |
825 # changeset that is an ancestor of self.changectx. | 832 # changeset that is an ancestor of self.changectx. |
826 rev = self._adjustlinkrev(path, l, fnode, self.rev()) | 833 rev = self._adjustlinkrev(path, l, fnode, self.rev()) |
827 fctx = filectx(self._repo, path, fileid=fnode, filelog=l, | 834 fctx = filectx(self._repo, path, fileid=fnode, filelog=l, |
828 changeid=rev) | 835 changeid=rev) |
836 fctx._ancestrycontext = getattr(self, '_ancestrycontext', None) | |
837 | |
829 else: | 838 else: |
830 fctx = filectx(self._repo, path, fileid=fnode, filelog=l) | 839 fctx = filectx(self._repo, path, fileid=fnode, filelog=l) |
831 ret.append(fctx) | 840 ret.append(fctx) |
832 return ret | 841 return ret |
833 | 842 |