Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlogutils/deltas.py @ 39522:c6b8eab5db19
snapshot: also consider the snapshot chain of one unrelated revision
To maximize the chance of good delta chain reuse, we inject an unrelated delta
chain into our search. To do so, we search for the highest revision unrelated
to the parents of the current revision and use its snapshot chain too.
Adding this extra snapshot into the mix can have a performance impact. We'll
deal with performance impact in a later series.
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Fri, 07 Sep 2018 11:18:45 -0400 |
parents | 05a165dc4f55 |
children | bdb41eaa8b59 |
comparison
equal
deleted
inserted
replaced
39521:05a165dc4f55 | 39522:c6b8eab5db19 |
---|---|
717 if not revlog.issnapshot(s): | 717 if not revlog.issnapshot(s): |
718 break | 718 break |
719 parents_snaps[idx].add(s) | 719 parents_snaps[idx].add(s) |
720 snapfloor = min(parents_snaps[0]) + 1 | 720 snapfloor = min(parents_snaps[0]) + 1 |
721 _findsnapshots(revlog, snapshots, snapfloor) | 721 _findsnapshots(revlog, snapshots, snapfloor) |
722 # search for the highest "unrelated" revision | |
723 # | |
724 # Adding snapshots used by "unrelated" revision increase the odd we | |
725 # reuse an independant, yet better snapshot chain. | |
726 # | |
727 # XXX instead of building a set of revisions, we could lazily enumerate | |
728 # over the chains. That would be more efficient, however we stick to | |
729 # simple code for now. | |
730 all_revs = set() | |
731 for chain in candidate_chains: | |
732 all_revs.update(chain) | |
733 other = None | |
734 for r in revlog.revs(prev, snapfloor): | |
735 if r not in all_revs: | |
736 other = r | |
737 break | |
738 if other is not None: | |
739 # To avoid unfair competition, we won't use unrelated intermediate | |
740 # snapshot that are deeper than the ones from the parent delta | |
741 # chain. | |
742 max_depth = max(parents_snaps.keys()) | |
743 chain = deltachain(other) | |
744 for idx, s in enumerate(chain): | |
745 if s < snapfloor: | |
746 continue | |
747 if max_depth < idx: | |
748 break | |
749 if not revlog.issnapshot(s): | |
750 break | |
751 parents_snaps[idx].add(s) | |
722 # Test them as possible intermediate snapshot base | 752 # Test them as possible intermediate snapshot base |
723 # We test them from highest to lowest level. High level one are more | 753 # We test them from highest to lowest level. High level one are more |
724 # likely to result in small delta | 754 # likely to result in small delta |
725 floor = None | 755 floor = None |
726 for idx, snaps in sorted(parents_snaps.items(), reverse=True): | 756 for idx, snaps in sorted(parents_snaps.items(), reverse=True): |
754 # revisions instead of starting our own. Without such re-use, | 784 # revisions instead of starting our own. Without such re-use, |
755 # topological branches would keep reopening new full chains. Creating | 785 # topological branches would keep reopening new full chains. Creating |
756 # more and more snapshot as the repository grow. | 786 # more and more snapshot as the repository grow. |
757 yield tuple(snapshots[nullrev]) | 787 yield tuple(snapshots[nullrev]) |
758 | 788 |
759 # other approach failed try against prev to hopefully save us a | 789 if not sparse: |
760 # fulltext. | 790 # other approach failed try against prev to hopefully save us a |
761 yield (prev,) | 791 # fulltext. |
792 yield (prev,) | |
762 | 793 |
763 class deltacomputer(object): | 794 class deltacomputer(object): |
764 def __init__(self, revlog): | 795 def __init__(self, revlog): |
765 self.revlog = revlog | 796 self.revlog = revlog |
766 | 797 |