comparison mercurial/revlogutils/deltas.py @ 39505: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
39504:05a165dc4f55 39505: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