##// END OF EJS Templates
changegroup: make _revisiondeltanarrow() a standalone function...
Gregory Szorc -
r39040:e11d07cc default
parent child Browse files
Show More
@@ -588,6 +588,100 b' def _revisiondeltanormal(store, rev, pre'
588 588 deltachunks=(prefix, delta),
589 589 )
590 590
591 def _revisiondeltanarrow(cl, store, ischangelog, rev, linkrev,
592 linknode, clrevtolocalrev, fullclnodes,
593 precomputedellipsis):
594 linkparents = precomputedellipsis[linkrev]
595 def local(clrev):
596 """Turn a changelog revnum into a local revnum.
597
598 The ellipsis dag is stored as revnums on the changelog,
599 but when we're producing ellipsis entries for
600 non-changelog revlogs, we need to turn those numbers into
601 something local. This does that for us, and during the
602 changelog sending phase will also expand the stored
603 mappings as needed.
604 """
605 if clrev == nullrev:
606 return nullrev
607
608 if ischangelog:
609 return clrev
610
611 # Walk the ellipsis-ized changelog breadth-first looking for a
612 # change that has been linked from the current revlog.
613 #
614 # For a flat manifest revlog only a single step should be necessary
615 # as all relevant changelog entries are relevant to the flat
616 # manifest.
617 #
618 # For a filelog or tree manifest dirlog however not every changelog
619 # entry will have been relevant, so we need to skip some changelog
620 # nodes even after ellipsis-izing.
621 walk = [clrev]
622 while walk:
623 p = walk[0]
624 walk = walk[1:]
625 if p in clrevtolocalrev:
626 return clrevtolocalrev[p]
627 elif p in fullclnodes:
628 walk.extend([pp for pp in cl.parentrevs(p)
629 if pp != nullrev])
630 elif p in precomputedellipsis:
631 walk.extend([pp for pp in precomputedellipsis[p]
632 if pp != nullrev])
633 else:
634 # In this case, we've got an ellipsis with parents
635 # outside the current bundle (likely an
636 # incremental pull). We "know" that we can use the
637 # value of this same revlog at whatever revision
638 # is pointed to by linknode. "Know" is in scare
639 # quotes because I haven't done enough examination
640 # of edge cases to convince myself this is really
641 # a fact - it works for all the (admittedly
642 # thorough) cases in our testsuite, but I would be
643 # somewhat unsurprised to find a case in the wild
644 # where this breaks down a bit. That said, I don't
645 # know if it would hurt anything.
646 for i in pycompat.xrange(rev, 0, -1):
647 if store.linkrev(i) == clrev:
648 return i
649 # We failed to resolve a parent for this node, so
650 # we crash the changegroup construction.
651 raise error.Abort(
652 'unable to resolve parent while packing %r %r'
653 ' for changeset %r' % (store.indexfile, rev, clrev))
654
655 return nullrev
656
657 if not linkparents or (
658 store.parentrevs(rev) == (nullrev, nullrev)):
659 p1, p2 = nullrev, nullrev
660 elif len(linkparents) == 1:
661 p1, = sorted(local(p) for p in linkparents)
662 p2 = nullrev
663 else:
664 p1, p2 = sorted(local(p) for p in linkparents)
665
666 n = store.node(rev)
667 p1n, p2n = store.node(p1), store.node(p2)
668 flags = store.flags(rev)
669 flags |= revlog.REVIDX_ELLIPSIS
670
671 # TODO: try and actually send deltas for ellipsis data blocks
672 data = store.revision(n)
673 diffheader = mdiff.trivialdiffheader(len(data))
674
675 return revisiondelta(
676 node=n,
677 p1node=p1n,
678 p2node=p2n,
679 basenode=nullid,
680 linknode=linknode,
681 flags=flags,
682 deltachunks=(diffheader, data),
683 )
684
591 685 class cgpacker(object):
592 686 def __init__(self, repo, filematcher, version, allowreorder,
593 687 deltaparentfn, builddeltaheader, manifestsend,
@@ -707,7 +801,7 b' class cgpacker(object):'
707 801 elif linkrev not in self._precomputedellipsis:
708 802 delta = None
709 803 else:
710 delta = self._revisiondeltanarrow(
804 delta = _revisiondeltanarrow(
711 805 cl, store, ischangelog, curr, linkrev, linknode,
712 806 clrevtolocalrev, self._fullclnodes,
713 807 self._precomputedellipsis)
@@ -1058,100 +1152,6 b' class cgpacker(object):'
1058 1152 self._verbosenote(_('%8.i %s\n') % (size, fname))
1059 1153 progress.complete()
1060 1154
1061 def _revisiondeltanarrow(self, cl, store, ischangelog, rev, linkrev,
1062 linknode, clrevtolocalrev, fullclnodes,
1063 precomputedellipsis):
1064 linkparents = precomputedellipsis[linkrev]
1065 def local(clrev):
1066 """Turn a changelog revnum into a local revnum.
1067
1068 The ellipsis dag is stored as revnums on the changelog,
1069 but when we're producing ellipsis entries for
1070 non-changelog revlogs, we need to turn those numbers into
1071 something local. This does that for us, and during the
1072 changelog sending phase will also expand the stored
1073 mappings as needed.
1074 """
1075 if clrev == nullrev:
1076 return nullrev
1077
1078 if ischangelog:
1079 return clrev
1080
1081 # Walk the ellipsis-ized changelog breadth-first looking for a
1082 # change that has been linked from the current revlog.
1083 #
1084 # For a flat manifest revlog only a single step should be necessary
1085 # as all relevant changelog entries are relevant to the flat
1086 # manifest.
1087 #
1088 # For a filelog or tree manifest dirlog however not every changelog
1089 # entry will have been relevant, so we need to skip some changelog
1090 # nodes even after ellipsis-izing.
1091 walk = [clrev]
1092 while walk:
1093 p = walk[0]
1094 walk = walk[1:]
1095 if p in clrevtolocalrev:
1096 return clrevtolocalrev[p]
1097 elif p in fullclnodes:
1098 walk.extend([pp for pp in cl.parentrevs(p)
1099 if pp != nullrev])
1100 elif p in precomputedellipsis:
1101 walk.extend([pp for pp in precomputedellipsis[p]
1102 if pp != nullrev])
1103 else:
1104 # In this case, we've got an ellipsis with parents
1105 # outside the current bundle (likely an
1106 # incremental pull). We "know" that we can use the
1107 # value of this same revlog at whatever revision
1108 # is pointed to by linknode. "Know" is in scare
1109 # quotes because I haven't done enough examination
1110 # of edge cases to convince myself this is really
1111 # a fact - it works for all the (admittedly
1112 # thorough) cases in our testsuite, but I would be
1113 # somewhat unsurprised to find a case in the wild
1114 # where this breaks down a bit. That said, I don't
1115 # know if it would hurt anything.
1116 for i in pycompat.xrange(rev, 0, -1):
1117 if store.linkrev(i) == clrev:
1118 return i
1119 # We failed to resolve a parent for this node, so
1120 # we crash the changegroup construction.
1121 raise error.Abort(
1122 'unable to resolve parent while packing %r %r'
1123 ' for changeset %r' % (store.indexfile, rev, clrev))
1124
1125 return nullrev
1126
1127 if not linkparents or (
1128 store.parentrevs(rev) == (nullrev, nullrev)):
1129 p1, p2 = nullrev, nullrev
1130 elif len(linkparents) == 1:
1131 p1, = sorted(local(p) for p in linkparents)
1132 p2 = nullrev
1133 else:
1134 p1, p2 = sorted(local(p) for p in linkparents)
1135
1136 n = store.node(rev)
1137 p1n, p2n = store.node(p1), store.node(p2)
1138 flags = store.flags(rev)
1139 flags |= revlog.REVIDX_ELLIPSIS
1140
1141 # TODO: try and actually send deltas for ellipsis data blocks
1142 data = store.revision(n)
1143 diffheader = mdiff.trivialdiffheader(len(data))
1144
1145 return revisiondelta(
1146 node=n,
1147 p1node=p1n,
1148 p2node=p2n,
1149 basenode=nullid,
1150 linknode=linknode,
1151 flags=flags,
1152 deltachunks=(diffheader, data),
1153 )
1154
1155 1155 def _deltaparentprev(store, rev, p1, p2, prev):
1156 1156 """Resolve a delta parent to the previous revision.
1157 1157
General Comments 0
You need to be logged in to leave comments. Login now