comparison mercurial/changegroup.py @ 41448:fa7d61f9c512

changegroup: don't try to build changelog chunks if not required When we extend a narrow clone without ellipsis, we don't download changelog information because that's already present with the client. However we still try to build that chunk stream. Building that chunk stream involves calling a lookup function and store.emitrevisions() API. The lookup function is called len(cl) number of times. On large repositories, where len(cl) is in millions, calling that lookup function is not a good idea. Also it's not required to use the store.emitrevisons() API because we already have nodes present which we can use. This patch short-circuits state building logic if we are processing a non-ellipsis case and changelog is not required. This saves up ~20 seconds on our internal repo for a single extend call. Differential Revision: https://phab.mercurial-scm.org/D5733
author Pulkit Goyal <pulkit@yandex-team.ru>
date Tue, 29 Jan 2019 16:03:52 +0300
parents 73a33fe625bb
children 1db5ae4b0dda
comparison
equal deleted inserted replaced
41445:73a33fe625bb 41448:fa7d61f9c512
815 cl = repo.changelog 815 cl = repo.changelog
816 816
817 self._verbosenote(_('uncompressed size of bundle content:\n')) 817 self._verbosenote(_('uncompressed size of bundle content:\n'))
818 size = 0 818 size = 0
819 819
820 clstate, deltas = self._generatechangelog(cl, clnodes) 820 clstate, deltas = self._generatechangelog(cl, clnodes,
821 generate=changelog)
821 for delta in deltas: 822 for delta in deltas:
822 if changelog: 823 for chunk in _revisiondeltatochunks(delta,
823 for chunk in _revisiondeltatochunks(delta, 824 self._builddeltaheader):
824 self._builddeltaheader): 825 size += len(chunk)
825 size += len(chunk) 826 yield chunk
826 yield chunk
827 827
828 close = closechunk() 828 close = closechunk()
829 size += len(close) 829 size += len(close)
830 yield closechunk() 830 yield closechunk()
831 831
915 yield closechunk() 915 yield closechunk()
916 916
917 if clnodes: 917 if clnodes:
918 repo.hook('outgoing', node=hex(clnodes[0]), source=source) 918 repo.hook('outgoing', node=hex(clnodes[0]), source=source)
919 919
920 def _generatechangelog(self, cl, nodes): 920 def _generatechangelog(self, cl, nodes, generate=True):
921 """Generate data for changelog chunks. 921 """Generate data for changelog chunks.
922 922
923 Returns a 2-tuple of a dict containing state and an iterable of 923 Returns a 2-tuple of a dict containing state and an iterable of
924 byte chunks. The state will not be fully populated until the 924 byte chunks. The state will not be fully populated until the
925 chunk stream has been fully consumed. 925 chunk stream has been fully consumed.
926
927 if generate is False, the state will be fully populated and no chunk
928 stream will be yielded
926 """ 929 """
927 clrevorder = {} 930 clrevorder = {}
928 manifests = {} 931 manifests = {}
929 mfl = self._repo.manifestlog 932 mfl = self._repo.manifestlog
930 changedfiles = set() 933 changedfiles = set()
934 'clrevorder': clrevorder, 937 'clrevorder': clrevorder,
935 'manifests': manifests, 938 'manifests': manifests,
936 'changedfiles': changedfiles, 939 'changedfiles': changedfiles,
937 'clrevtomanifestrev': clrevtomanifestrev, 940 'clrevtomanifestrev': clrevtomanifestrev,
938 } 941 }
942
943 if not (generate or self._ellipses):
944 # sort the nodes in storage order
945 nodes = sorted(nodes, key=cl.rev)
946 for node in nodes:
947 c = cl.changelogrevision(node)
948 clrevorder[node] = len(clrevorder)
949 # record the first changeset introducing this manifest version
950 manifests.setdefault(c.manifest, node)
951 # Record a complete list of potentially-changed files in
952 # this manifest.
953 changedfiles.update(c.files)
954
955 return state, ()
939 956
940 # Callback for the changelog, used to collect changed files and 957 # Callback for the changelog, used to collect changed files and
941 # manifest nodes. 958 # manifest nodes.
942 # Returns the linkrev node (identity in the changelog case). 959 # Returns the linkrev node (identity in the changelog case).
943 def lookupcl(x): 960 def lookupcl(x):