##// END OF EJS Templates
changegroup: introduce requests to define delta generation...
Gregory Szorc -
r39054:e793e11e default
parent child Browse files
Show More
@@ -502,6 +502,32 b' class headerlessfixup(object):'
502 502 return readexactly(self._fh, n)
503 503
504 504 @attr.s(slots=True, frozen=True)
505 class revisiondeltarequest(object):
506 """Describes a request to construct a revision delta.
507
508 Instances are converted into ``revisiondelta`` later.
509 """
510 # Revision whose delta will be generated.
511 node = attr.ib()
512
513 # Linknode value.
514 linknode = attr.ib()
515
516 # Parent revisions to record in ``revisiondelta`` instance.
517 p1node = attr.ib()
518 p2node = attr.ib()
519
520 # Base revision that delta should be generated against. If nullrev,
521 # the full revision data should be populated. If None, the delta
522 # may be generated against any base revision that is an ancestor of
523 # this revision. If any other numeric value, the delta should be
524 # produced against that revision.
525 baserev = attr.ib()
526
527 # Whether this should be marked as an ellipsis revision.
528 ellipsis = attr.ib(default=False)
529
530 @attr.s(slots=True, frozen=True)
505 531 class revisiondelta(object):
506 532 """Describes a delta entry in a changegroup.
507 533
@@ -587,14 +613,21 b' def _sortnodesellipsis(store, nodes, cl,'
587 613 key = lambda n: cl.rev(lookup(n))
588 614 return [store.rev(n) for n in sorted(nodes, key=key)]
589 615
590 def _revisiondeltanormal(store, rev, prev, linknode, forcedeltaparentprev):
591 """Construct a revision delta for non-ellipses changegroup generation."""
592 node = store.node(rev)
616 def _handlerevisiondeltarequest(store, request, prev):
617 """Obtain a revisiondelta from a revisiondeltarequest"""
618
619 node = request.node
620 rev = store.rev(node)
621
622 # Requesting a full revision.
623 if request.baserev == nullrev:
624 base = nullrev
625 # Requesting an explicit revision.
626 elif request.baserev is not None:
627 base = request.baserev
628 # Allowing us to choose.
629 else:
593 630 p1, p2 = store.parentrevs(rev)
594
595 if forcedeltaparentprev:
596 base = prev
597 else:
598 631 dp = store.deltaparent(rev)
599 632
600 633 if dp == nullrev and store.storedeltachains:
@@ -637,21 +670,21 b' def _revisiondeltanormal(store, rev, pre'
637 670 else:
638 671 delta = store.revdiff(base, rev)
639 672
640 p1n, p2n = store.parents(node)
673 extraflags = revlog.REVIDX_ELLIPSIS if request.ellipsis else 0
641 674
642 675 return revisiondelta(
643 676 node=node,
644 p1node=p1n,
645 p2node=p2n,
677 p1node=request.p1node,
678 p2node=request.p2node,
679 linknode=request.linknode,
646 680 basenode=store.node(base),
647 linknode=linknode,
648 flags=store.flags(rev),
681 flags=store.flags(rev) | extraflags,
649 682 baserevisionsize=baserevisionsize,
650 683 revision=revision,
651 684 delta=delta,
652 685 )
653 686
654 def _revisiondeltanarrow(cl, store, ischangelog, rev, linkrev,
687 def _makenarrowdeltarequest(cl, store, ischangelog, rev, node, linkrev,
655 688 linknode, clrevtolocalrev, fullclnodes,
656 689 precomputedellipsis):
657 690 linkparents = precomputedellipsis[linkrev]
@@ -726,23 +759,16 b' def _revisiondeltanarrow(cl, store, isch'
726 759 else:
727 760 p1, p2 = sorted(local(p) for p in linkparents)
728 761
729 n = store.node(rev)
730 p1n, p2n = store.node(p1), store.node(p2)
731 flags = store.flags(rev)
732 flags |= revlog.REVIDX_ELLIPSIS
762 p1node, p2node = store.node(p1), store.node(p2)
733 763
734 764 # TODO: try and actually send deltas for ellipsis data blocks
735
736 return revisiondelta(
737 node=n,
738 p1node=p1n,
739 p2node=p2n,
740 basenode=nullid,
765 return revisiondeltarequest(
766 node=node,
767 p1node=p1node,
768 p2node=p2node,
741 769 linknode=linknode,
742 flags=flags,
743 baserevisionsize=None,
744 revision=store.revision(n),
745 delta=None,
770 baserev=nullrev,
771 ellipsis=True,
746 772 )
747 773
748 774 def deltagroup(repo, revs, store, ischangelog, lookup, forcedeltaparentprev,
@@ -759,25 +785,32 b' def deltagroup(repo, revs, store, ischan'
759 785 if not revs:
760 786 return
761 787
788 # We perform two passes over the revisions whose data we will emit.
789 #
790 # In the first pass, we obtain information about the deltas that will
791 # be generated. This involves computing linknodes and adjusting the
792 # request to take shallow fetching into account. The end result of
793 # this pass is a list of "request" objects stating which deltas
794 # to obtain.
795 #
796 # The second pass is simply resolving the requested deltas.
797
762 798 cl = repo.changelog
763 799
800 # In the first pass, collect info about the deltas we'll be
801 # generating.
802 requests = []
803
764 804 # Add the parent of the first rev.
765 805 revs.insert(0, store.parentrevs(revs[0])[0])
766 806
767 # build deltas
768 progress = None
769 if units is not None:
770 progress = repo.ui.makeprogress(_('bundling'), unit=units,
771 total=(len(revs) - 1))
772
773 807 for i in pycompat.xrange(len(revs) - 1):
774 if progress:
775 progress.update(i + 1)
776
777 808 prev = revs[i]
778 809 curr = revs[i + 1]
779 810
780 linknode = lookup(store.node(curr))
811 node = store.node(curr)
812 linknode = lookup(node)
813 p1node, p2node = store.parents(node)
781 814
782 815 if ellipses:
783 816 linkrev = cl.rev(linknode)
@@ -786,22 +819,48 b' def deltagroup(repo, revs, store, ischan'
786 819 # This is a node to send in full, because the changeset it
787 820 # corresponds to was a full changeset.
788 821 if linknode in fullclnodes:
789 delta = _revisiondeltanormal(store, curr, prev, linknode,
790 forcedeltaparentprev)
822 requests.append(revisiondeltarequest(
823 node=node,
824 p1node=p1node,
825 p2node=p2node,
826 linknode=linknode,
827 baserev=None,
828 ))
829
791 830 elif linkrev not in precomputedellipsis:
792 delta = None
831 pass
793 832 else:
794 delta = _revisiondeltanarrow(
795 cl, store, ischangelog, curr, linkrev, linknode,
833 requests.append(_makenarrowdeltarequest(
834 cl, store, ischangelog, curr, node, linkrev, linknode,
796 835 clrevtolocalrev, fullclnodes,
797 precomputedellipsis)
836 precomputedellipsis))
798 837 else:
799 delta = _revisiondeltanormal(store, curr, prev, linknode,
800 forcedeltaparentprev)
838 requests.append(revisiondeltarequest(
839 node=node,
840 p1node=p1node,
841 p2node=p2node,
842 linknode=linknode,
843 baserev=prev if forcedeltaparentprev else None,
844 ))
801 845
802 if delta:
846 # We expect the first pass to be fast, so we only engage the progress
847 # meter for constructing the revision deltas.
848 progress = None
849 if units is not None:
850 progress = repo.ui.makeprogress(_('bundling'), unit=units,
851 total=len(requests))
852
853 prevrev = revs[0]
854 for i, request in enumerate(requests):
855 if progress:
856 progress.update(i + 1)
857
858 delta = _handlerevisiondeltarequest(store, request, prevrev)
859
803 860 yield delta
804 861
862 prevrev = store.rev(request.node)
863
805 864 if progress:
806 865 progress.complete()
807 866
General Comments 0
You need to be logged in to leave comments. Login now