comparison mercurial/changegroup.py @ 38906:0548f696795b

changegroup: move revision maps to cgpacker And remove the underscores so the variables conform to our naming convention. The logic in _close() should be the only thing warranting scrutiny during review. Differential Revision: https://phab.mercurial-scm.org/D4088
author Gregory Szorc <gregory.szorc@gmail.com>
date Fri, 03 Aug 2018 13:11:13 -0700
parents 379d90327861
children ad4c4cc9a5ac
comparison
equal deleted inserted replaced
38905:379d90327861 38906:0548f696795b
581 581
582 # TODO the functionality keyed off of this should probably be 582 # TODO the functionality keyed off of this should probably be
583 # controlled via arguments to group() that influence behavior. 583 # controlled via arguments to group() that influence behavior.
584 self._changelogdone = False 584 self._changelogdone = False
585 585
586 # Maps CL revs to per-revlog revisions. Cleared in close() at
587 # the end of each group.
588 self._clrevtolocalrev = {}
589 self._nextclrevtolocalrev = {}
590
591 # Maps changelog nodes to changelog revs. Filled in once
592 # during changelog stage and then left unmodified.
593 self._clnodetorev = {}
594
586 def _close(self): 595 def _close(self):
587 # Ellipses serving mode. 596 # Ellipses serving mode.
588 getattr(self, '_clrev_to_localrev', {}).clear() 597 self._clrevtolocalrev.clear()
589 if getattr(self, '_next_clrev_to_localrev', {}): 598 if self._nextclrevtolocalrev:
590 self._clrev_to_localrev = self._next_clrev_to_localrev 599 self.clrevtolocalrev = self._nextclrevtolocalrev
591 del self._next_clrev_to_localrev 600 self._nextclrevtolocalrev.clear()
592 self._changelogdone = True 601 self._changelogdone = True
593 602
594 return closechunk() 603 return closechunk()
595 604
596 def _fileheader(self, fname): 605 def _fileheader(self, fname):
613 # The one invariant we *know* holds is that the new (potentially 622 # The one invariant we *know* holds is that the new (potentially
614 # bogus) DAG shape will be valid if we order the nodes in the 623 # bogus) DAG shape will be valid if we order the nodes in the
615 # order that they're introduced in dramatis personae by the 624 # order that they're introduced in dramatis personae by the
616 # changelog, so what we do is we sort the non-changelog histories 625 # changelog, so what we do is we sort the non-changelog histories
617 # by the order in which they are used by the changelog. 626 # by the order in which they are used by the changelog.
618 if util.safehasattr(self, '_full_nodes') and self._clnode_to_rev: 627 if util.safehasattr(self, '_full_nodes') and self._clnodetorev:
619 key = lambda n: self._clnode_to_rev[lookup(n)] 628 key = lambda n: self._clnodetorev[lookup(n)]
620 return [store.rev(n) for n in sorted(nodelist, key=key)] 629 return [store.rev(n) for n in sorted(nodelist, key=key)]
621 630
622 # for generaldelta revlogs, we linearize the revs; this will both be 631 # for generaldelta revlogs, we linearize the revs; this will both be
623 # much quicker and generate a much smaller bundle 632 # much quicker and generate a much smaller bundle
624 if (store._generaldelta and self._reorder is None) or self._reorder: 633 if (store._generaldelta and self._reorder is None) or self._reorder:
738 mfs.setdefault(n, x) 747 mfs.setdefault(n, x)
739 # Set this narrow-specific dict so we have the lowest 748 # Set this narrow-specific dict so we have the lowest
740 # manifest revnum to look up for this cl revnum. (Part of 749 # manifest revnum to look up for this cl revnum. (Part of
741 # mapping changelog ellipsis parents to manifest ellipsis 750 # mapping changelog ellipsis parents to manifest ellipsis
742 # parents) 751 # parents)
743 self._next_clrev_to_localrev.setdefault(cl.rev(x), 752 self._nextclrevtolocalrev.setdefault(cl.rev(x),
744 mfrevlog.rev(n)) 753 mfrevlog.rev(n))
745 # We can't trust the changed files list in the changeset if the 754 # We can't trust the changed files list in the changeset if the
746 # client requested a shallow clone. 755 # client requested a shallow clone.
747 if self._isshallow: 756 if self._isshallow:
748 changedfiles.update(mfl[c[0]].read().keys()) 757 changedfiles.update(mfl[c[0]].read().keys())
749 else: 758 else:
916 # TODO have caller pass in appropriate function. 925 # TODO have caller pass in appropriate function.
917 def linknodes(flog, fname): 926 def linknodes(flog, fname):
918 for c in commonctxs: 927 for c in commonctxs:
919 try: 928 try:
920 fnode = c.filenode(fname) 929 fnode = c.filenode(fname)
921 self._clrev_to_localrev[c.rev()] = flog.rev(fnode) 930 self._clrevtolocalrev[c.rev()] = flog.rev(fnode)
922 except error.ManifestLookupError: 931 except error.ManifestLookupError:
923 pass 932 pass
924 links = oldlinknodes(flog, fname) 933 links = oldlinknodes(flog, fname)
925 if len(links) != len(mfdicts): 934 if len(links) != len(mfdicts):
926 for mf, lr in mfdicts: 935 for mf, lr in mfdicts:
1061 1070
1062 def _revisiondeltanarrow(self, store, rev, prev, linknode): 1071 def _revisiondeltanarrow(self, store, rev, prev, linknode):
1063 # build up some mapping information that's useful later. See 1072 # build up some mapping information that's useful later. See
1064 # the local() nested function below. 1073 # the local() nested function below.
1065 if not self._changelogdone: 1074 if not self._changelogdone:
1066 self._clnode_to_rev[linknode] = rev 1075 self._clnodetorev[linknode] = rev
1067 linkrev = rev 1076 linkrev = rev
1068 self._clrev_to_localrev[linkrev] = rev 1077 self._clrevtolocalrev[linkrev] = rev
1069 else: 1078 else:
1070 linkrev = self._clnode_to_rev[linknode] 1079 linkrev = self._clnodetorev[linknode]
1071 self._clrev_to_localrev[linkrev] = rev 1080 self._clrevtolocalrev[linkrev] = rev
1072 1081
1073 # This is a node to send in full, because the changeset it 1082 # This is a node to send in full, because the changeset it
1074 # corresponds to was a full changeset. 1083 # corresponds to was a full changeset.
1075 if linknode in self._full_nodes: 1084 if linknode in self._full_nodes:
1076 return self._revisiondeltanormal(store, rev, prev, linknode) 1085 return self._revisiondeltanormal(store, rev, prev, linknode)
1098 # If we're doing the changelog, it's possible that we 1107 # If we're doing the changelog, it's possible that we
1099 # have a parent that is already on the client, and we 1108 # have a parent that is already on the client, and we
1100 # need to store some extra mapping information so that 1109 # need to store some extra mapping information so that
1101 # our contained ellipsis nodes will be able to resolve 1110 # our contained ellipsis nodes will be able to resolve
1102 # their parents. 1111 # their parents.
1103 if clrev not in self._clrev_to_localrev: 1112 if clrev not in self._clrevtolocalrev:
1104 clnode = store.node(clrev) 1113 clnode = store.node(clrev)
1105 self._clnode_to_rev[clnode] = clrev 1114 self._clnodetorev[clnode] = clrev
1106 return clrev 1115 return clrev
1107 1116
1108 # Walk the ellipsis-ized changelog breadth-first looking for a 1117 # Walk the ellipsis-ized changelog breadth-first looking for a
1109 # change that has been linked from the current revlog. 1118 # change that has been linked from the current revlog.
1110 # 1119 #
1117 # nodes even after ellipsis-izing. 1126 # nodes even after ellipsis-izing.
1118 walk = [clrev] 1127 walk = [clrev]
1119 while walk: 1128 while walk:
1120 p = walk[0] 1129 p = walk[0]
1121 walk = walk[1:] 1130 walk = walk[1:]
1122 if p in self._clrev_to_localrev: 1131 if p in self._clrevtolocalrev:
1123 return self._clrev_to_localrev[p] 1132 return self._clrevtolocalrev[p]
1124 elif p in self._full_nodes: 1133 elif p in self._full_nodes:
1125 walk.extend([pp for pp in self._repo.changelog.parentrevs(p) 1134 walk.extend([pp for pp in self._repo.changelog.parentrevs(p)
1126 if pp != nullrev]) 1135 if pp != nullrev])
1127 elif p in self._precomputed_ellipsis: 1136 elif p in self._precomputed_ellipsis:
1128 walk.extend([pp for pp in self._precomputed_ellipsis[p] 1137 walk.extend([pp for pp in self._precomputed_ellipsis[p]
1398 # that should be an ellipsis because for very large histories 1407 # that should be an ellipsis because for very large histories
1399 # we expect this to be significantly smaller. 1408 # we expect this to be significantly smaller.
1400 packer._full_nodes = relevant_nodes 1409 packer._full_nodes = relevant_nodes
1401 # Maps ellipsis revs to their roots at the changelog level. 1410 # Maps ellipsis revs to their roots at the changelog level.
1402 packer._precomputed_ellipsis = ellipsisroots 1411 packer._precomputed_ellipsis = ellipsisroots
1403 # Maps CL revs to per-revlog revisions. Cleared in close() at
1404 # the end of each group.
1405 packer._clrev_to_localrev = {}
1406 packer._next_clrev_to_localrev = {}
1407 # Maps changelog nodes to changelog revs. Filled in once
1408 # during changelog stage and then left unmodified.
1409 packer._clnode_to_rev = {}
1410 1412
1411 return packer.generate(common, visitnodes, False, source) 1413 return packer.generate(common, visitnodes, False, source)