comparison mercurial/changegroup.py @ 28228:abf120262683

changegroup: make _packmanifests() dumber The next few patches will rewrite the manifest generation code to work with merges. We will then walk dirlogs recursively. This prepares for that by moving much of the treemanifest code out of _packmanifests() and into generatemanifests(). For this to work, it also adds _manifestsdone() method that returns the "end of manifests" close chunk for cg3 and an empty string for cg1 and cg2.
author Martin von Zweigbergk <martinvonz@google.com>
date Fri, 12 Feb 2016 15:18:56 -0800
parents 1c36cc8e7870
children 8e13b2379407
comparison
equal deleted inserted replaced
28227:1c36cc8e7870 28228:abf120262683
657 # filter any nodes that claim to be part of the known set 657 # filter any nodes that claim to be part of the known set
658 def prune(self, revlog, missing, commonrevs): 658 def prune(self, revlog, missing, commonrevs):
659 rr, rl = revlog.rev, revlog.linkrev 659 rr, rl = revlog.rev, revlog.linkrev
660 return [n for n in missing if rl(rr(n)) not in commonrevs] 660 return [n for n in missing if rl(rr(n)) not in commonrevs]
661 661
662 def _packmanifests(self, mfnodes, tmfnodes, lookuplinknode): 662 def _packmanifests(self, dir, mfnodes, lookuplinknode):
663 """Pack flat manifests into a changegroup stream.""" 663 """Pack flat manifests into a changegroup stream."""
664 ml = self._repo.manifest 664 assert not dir
665 size = 0 665 for chunk in self.group(mfnodes, self._repo.manifest,
666 for chunk in self.group( 666 lookuplinknode, units=_('manifests')):
667 mfnodes, ml, lookuplinknode, units=_('manifests')):
668 size += len(chunk)
669 yield chunk 667 yield chunk
670 self._verbosenote(_('%8.i (manifests)\n') % size) 668
671 # It looks odd to assert this here, but tmfnodes doesn't get 669 def _manifestsdone(self):
672 # filled in until after we've called lookuplinknode for 670 return ''
673 # sending root manifests, so the only way to tell the streams
674 # got crossed is to check after we've done all the work.
675 assert not tmfnodes
676 671
677 def generate(self, commonrevs, clnodes, fastpathlinkrev, source): 672 def generate(self, commonrevs, clnodes, fastpathlinkrev, source):
678 '''yield a sequence of changegroup chunks (strings)''' 673 '''yield a sequence of changegroup chunks (strings)'''
679 repo = self._repo 674 repo = self._repo
680 cl = repo.changelog 675 cl = repo.changelog
823 if clrevorder[clnode] < clrevorder[tmfclnode]: 818 if clrevorder[clnode] < clrevorder[tmfclnode]:
824 tmfclnodes[n] = clnode 819 tmfclnodes[n] = clnode
825 return clnode 820 return clnode
826 821
827 mfnodes = self.prune(ml, mfs, commonrevs) 822 mfnodes = self.prune(ml, mfs, commonrevs)
828 for x in self._packmanifests( 823 size = 0
829 mfnodes, tmfnodes, lookupmflinknode): 824 for x in self._packmanifests('', mfnodes, lookupmflinknode):
825 size += len(x)
830 yield x 826 yield x
827 self._verbosenote(_('%8.i (manifests)\n') % size)
828 for dir, nodes in tmfnodes.iteritems():
829 for x in self._packmanifests(dir, nodes, nodes.get):
830 yield x
831 yield self._manifestsdone()
831 832
832 # The 'source' parameter is useful for extensions 833 # The 'source' parameter is useful for extensions
833 def generatefiles(self, changedfiles, linknodes, commonrevs, source): 834 def generatefiles(self, changedfiles, linknodes, commonrevs, source):
834 repo = self._repo 835 repo = self._repo
835 progress = self._progress 836 progress = self._progress
926 927
927 class cg3packer(cg2packer): 928 class cg3packer(cg2packer):
928 version = '03' 929 version = '03'
929 deltaheader = _CHANGEGROUPV3_DELTA_HEADER 930 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
930 931
931 def _packmanifests(self, mfnodes, tmfnodes, lookuplinknode): 932 def _packmanifests(self, dir, mfnodes, lookuplinknode):
932 # Note that debug prints are super confusing in this code, as 933 if dir:
933 # tmfnodes gets populated by the calls to lookuplinknode in 934 yield self.fileheader(dir)
934 # the superclass's manifest packer. In the future we should 935 for chunk in self.group(mfnodes, self._repo.manifest.dirlog(dir),
935 # probably see if we can refactor this somehow to be less 936 lookuplinknode, units=_('manifests')):
936 # confusing. 937 yield chunk
937 for x in super(cg3packer, self)._packmanifests( 938
938 mfnodes, {}, lookuplinknode): 939 def _manifestsdone(self):
939 yield x 940 return self.close()
940 dirlog = self._repo.manifest.dirlog
941 for name, nodes in tmfnodes.iteritems():
942 # For now, directory headers are simply file headers with
943 # a trailing '/' on the path (already in the name).
944 yield self.fileheader(name)
945 for chunk in self.group(nodes, dirlog(name), nodes.get):
946 yield chunk
947 yield self.close()
948 941
949 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags): 942 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
950 return struct.pack( 943 return struct.pack(
951 self.deltaheader, node, p1n, p2n, basenode, linknode, flags) 944 self.deltaheader, node, p1n, p2n, basenode, linknode, flags)
952 945