comparison mercurial/changegroup.py @ 38897:bd64b8b8f0dd

changegroup: pass function to build delta header into constructor Previously, the delta header struct format was defined on each class and each class had a separate function for building the delta header. We replace both of these with an argument to __init__ containing a callable that can format a delta header given a revisiondelta instance. Differential Revision: https://phab.mercurial-scm.org/D4079
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 02 Aug 2018 17:44:56 -0700
parents 271854adc3a6
children 67f37e8a5490
comparison
equal deleted inserted replaced
38896:271854adc3a6 38897:bd64b8b8f0dd
518 flags = attr.ib() 518 flags = attr.ib()
519 # Iterable of chunks holding raw delta data. 519 # Iterable of chunks holding raw delta data.
520 deltachunks = attr.ib() 520 deltachunks = attr.ib()
521 521
522 class cg1packer(object): 522 class cg1packer(object):
523 deltaheader = _CHANGEGROUPV1_DELTA_HEADER 523 def __init__(self, repo, filematcher, version, builddeltaheader,
524 524 bundlecaps=None):
525 def __init__(self, repo, filematcher, version, bundlecaps=None):
526 """Given a source repo, construct a bundler. 525 """Given a source repo, construct a bundler.
527 526
528 filematcher is a matcher that matches on files to include in the 527 filematcher is a matcher that matches on files to include in the
529 changegroup. Used to facilitate sparse changegroups. 528 changegroup. Used to facilitate sparse changegroups.
529
530 builddeltaheader is a callable that constructs the header for a group
531 delta.
530 532
531 bundlecaps is optional and can be used to specify the set of 533 bundlecaps is optional and can be used to specify the set of
532 capabilities which can be used to build the bundle. While bundlecaps is 534 capabilities which can be used to build the bundle. While bundlecaps is
533 unused in core Mercurial, extensions rely on this feature to communicate 535 unused in core Mercurial, extensions rely on this feature to communicate
534 capabilities to customize the changegroup packer. 536 capabilities to customize the changegroup packer.
535 """ 537 """
536 assert filematcher 538 assert filematcher
537 self._filematcher = filematcher 539 self._filematcher = filematcher
538 540
539 self.version = version 541 self.version = version
542 self._builddeltaheader = builddeltaheader
540 543
541 # Set of capabilities we can use to build the bundle. 544 # Set of capabilities we can use to build the bundle.
542 if bundlecaps is None: 545 if bundlecaps is None:
543 bundlecaps = set() 546 bundlecaps = set()
544 self._bundlecaps = bundlecaps 547 self._bundlecaps = bundlecaps
931 934
932 delta = fn(store, rev, prev, linknode) 935 delta = fn(store, rev, prev, linknode)
933 if not delta: 936 if not delta:
934 return 937 return
935 938
936 meta = self.builddeltaheader(delta.node, delta.p1node, delta.p2node, 939 meta = self._builddeltaheader(delta)
937 delta.basenode, delta.linknode,
938 delta.flags)
939 l = len(meta) + sum(len(x) for x in delta.deltachunks) 940 l = len(meta) + sum(len(x) for x in delta.deltachunks)
940 941
941 yield chunkheader(l) 942 yield chunkheader(l)
942 yield meta 943 yield meta
943 for x in delta.deltachunks: 944 for x in delta.deltachunks:
1094 linknode=linknode, 1095 linknode=linknode,
1095 flags=flags, 1096 flags=flags,
1096 deltachunks=(diffheader, data), 1097 deltachunks=(diffheader, data),
1097 ) 1098 )
1098 1099
1099 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
1100 # do nothing with basenode, it is implicitly the previous one in HG10
1101 # do nothing with flags, it is implicitly 0 for cg1 and cg2
1102 return self.deltaheader.pack(node, p1n, p2n, linknode)
1103
1104 class cg2packer(cg1packer): 1100 class cg2packer(cg1packer):
1105 deltaheader = _CHANGEGROUPV2_DELTA_HEADER 1101 def __init__(self, repo, filematcher, version, builddeltaheader,
1106 1102 bundlecaps=None):
1107 def __init__(self, repo, filematcher, version, bundlecaps=None):
1108 super(cg2packer, self).__init__(repo, filematcher, version, 1103 super(cg2packer, self).__init__(repo, filematcher, version,
1104 builddeltaheader,
1109 bundlecaps=bundlecaps) 1105 bundlecaps=bundlecaps)
1110 1106
1111 if self._reorder is None: 1107 if self._reorder is None:
1112 # Since generaldelta is directly supported by cg2, reordering 1108 # Since generaldelta is directly supported by cg2, reordering
1113 # generally doesn't help, so we disable it by default (treating 1109 # generally doesn't help, so we disable it by default (treating
1151 base = dp 1147 base = dp
1152 if base != nullrev and not store.candelta(base, rev): 1148 if base != nullrev and not store.candelta(base, rev):
1153 base = nullrev 1149 base = nullrev
1154 return base 1150 return base
1155 1151
1156 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
1157 # Do nothing with flags, it is implicitly 0 in cg1 and cg2
1158 return self.deltaheader.pack(node, p1n, p2n, basenode, linknode)
1159
1160 class cg3packer(cg2packer): 1152 class cg3packer(cg2packer):
1161 deltaheader = _CHANGEGROUPV3_DELTA_HEADER
1162
1163 def _packmanifests(self, dir, mfnodes, lookuplinknode): 1153 def _packmanifests(self, dir, mfnodes, lookuplinknode):
1164 if dir: 1154 if dir:
1165 yield self.fileheader(dir) 1155 yield self.fileheader(dir)
1166 1156
1167 dirlog = self._repo.manifestlog._revlog.dirlog(dir) 1157 dirlog = self._repo.manifestlog._revlog.dirlog(dir)
1170 yield chunk 1160 yield chunk
1171 1161
1172 def _manifestsdone(self): 1162 def _manifestsdone(self):
1173 return self.close() 1163 return self.close()
1174 1164
1175 def builddeltaheader(self, node, p1n, p2n, basenode, linknode, flags):
1176 return self.deltaheader.pack(node, p1n, p2n, basenode, linknode, flags)
1177
1178 def _makecg1packer(repo, filematcher, bundlecaps): 1165 def _makecg1packer(repo, filematcher, bundlecaps):
1179 return cg1packer(repo, filematcher, b'01', bundlecaps=bundlecaps) 1166 builddeltaheader = lambda d: _CHANGEGROUPV1_DELTA_HEADER.pack(
1167 d.node, d.p1node, d.p2node, d.linknode)
1168
1169 return cg1packer(repo, filematcher, b'01', builddeltaheader,
1170 bundlecaps=bundlecaps)
1180 1171
1181 def _makecg2packer(repo, filematcher, bundlecaps): 1172 def _makecg2packer(repo, filematcher, bundlecaps):
1182 return cg2packer(repo, filematcher, b'02', bundlecaps=bundlecaps) 1173 builddeltaheader = lambda d: _CHANGEGROUPV2_DELTA_HEADER.pack(
1174 d.node, d.p1node, d.p2node, d.basenode, d.linknode)
1175
1176 return cg2packer(repo, filematcher, b'02', builddeltaheader,
1177 bundlecaps=bundlecaps)
1183 1178
1184 def _makecg3packer(repo, filematcher, bundlecaps): 1179 def _makecg3packer(repo, filematcher, bundlecaps):
1185 return cg3packer(repo, filematcher, b'03', bundlecaps=bundlecaps) 1180 builddeltaheader = lambda d: _CHANGEGROUPV3_DELTA_HEADER.pack(
1181 d.node, d.p1node, d.p2node, d.basenode, d.linknode, d.flags)
1182
1183 return cg3packer(repo, filematcher, b'03', builddeltaheader,
1184 bundlecaps=bundlecaps)
1186 1185
1187 _packermap = {'01': (_makecg1packer, cg1unpacker), 1186 _packermap = {'01': (_makecg1packer, cg1unpacker),
1188 # cg2 adds support for exchanging generaldelta 1187 # cg2 adds support for exchanging generaldelta
1189 '02': (_makecg2packer, cg2unpacker), 1188 '02': (_makecg2packer, cg2unpacker),
1190 # cg3 adds support for exchanging revlog flags and treemanifests 1189 # cg3 adds support for exchanging revlog flags and treemanifests