797 break |
797 break |
798 |
798 |
799 yield None |
799 yield None |
800 |
800 |
801 |
801 |
802 def _findsnapshots(revlog, cache, start_rev): |
|
803 """find snapshot from start_rev to tip""" |
|
804 if util.safehasattr(revlog.index, b'findsnapshots'): |
|
805 revlog.index.findsnapshots(cache, start_rev) |
|
806 else: |
|
807 deltaparent = revlog.deltaparent |
|
808 issnapshot = revlog.issnapshot |
|
809 for rev in revlog.revs(start_rev): |
|
810 if issnapshot(rev): |
|
811 cache[deltaparent(rev)].append(rev) |
|
812 |
|
813 |
|
814 def _refinedgroups(revlog, p1, p2, cachedelta): |
802 def _refinedgroups(revlog, p1, p2, cachedelta): |
815 good = None |
803 good = None |
816 # First we try to reuse a the delta contained in the bundle. |
804 # First we try to reuse a the delta contained in the bundle. |
817 # (or from the source revlog) |
805 # (or from the source revlog) |
818 # |
806 # |
859 base = revlog.deltaparent(good) |
847 base = revlog.deltaparent(good) |
860 if base == nullrev: |
848 if base == nullrev: |
861 break |
849 break |
862 good = yield (base,) |
850 good = yield (base,) |
863 # refine snapshot up |
851 # refine snapshot up |
864 if not snapshots: |
852 if not snapshot_cache.snapshots: |
865 _findsnapshots(revlog, snapshots, good + 1) |
853 snapshot_cache.update(revlog, good + 1) |
866 previous = None |
854 previous = None |
867 while good != previous: |
855 while good != previous: |
868 previous = good |
856 previous = good |
869 children = tuple(sorted(c for c in snapshots[good])) |
857 children = tuple(sorted(c for c in snapshot_cache.snapshots[good])) |
870 good = yield children |
858 good = yield children |
871 |
859 |
872 if debug_info is not None: |
860 if debug_info is not None: |
873 if good is None: |
861 if good is None: |
874 debug_info['no-solution'] += 1 |
862 debug_info['no-solution'] += 1 |
875 |
863 |
876 yield None |
864 yield None |
877 |
865 |
878 |
866 |
879 def _rawgroups(revlog, p1, p2, cachedelta, snapshots=None): |
867 def _rawgroups(revlog, p1, p2, cachedelta, snapshot_cache=None): |
880 """Provides group of revision to be tested as delta base |
868 """Provides group of revision to be tested as delta base |
881 |
869 |
882 This lower level function focus on emitting delta theorically interresting |
870 This lower level function focus on emitting delta theorically interresting |
883 without looking it any practical details. |
871 without looking it any practical details. |
884 |
872 |
905 elif len(parents) > 0: |
893 elif len(parents) > 0: |
906 # Test all parents (1 or 2), and keep the best candidate |
894 # Test all parents (1 or 2), and keep the best candidate |
907 yield parents |
895 yield parents |
908 |
896 |
909 if sparse and parents: |
897 if sparse and parents: |
910 if snapshots is None: |
898 if snapshot_cache is None: |
911 # map: base-rev: [snapshot-revs] |
899 # map: base-rev: [snapshot-revs] |
912 snapshots = collections.defaultdict(list) |
900 snapshot_cache = SnapshotCache() |
913 # See if we can use an existing snapshot in the parent chains to use as |
901 # See if we can use an existing snapshot in the parent chains to use as |
914 # a base for a new intermediate-snapshot |
902 # a base for a new intermediate-snapshot |
915 # |
903 # |
916 # search for snapshot in parents delta chain |
904 # search for snapshot in parents delta chain |
917 # map: snapshot-level: snapshot-rev |
905 # map: snapshot-level: snapshot-rev |
921 for idx, s in enumerate(chain): |
909 for idx, s in enumerate(chain): |
922 if not revlog.issnapshot(s): |
910 if not revlog.issnapshot(s): |
923 break |
911 break |
924 parents_snaps[idx].add(s) |
912 parents_snaps[idx].add(s) |
925 snapfloor = min(parents_snaps[0]) + 1 |
913 snapfloor = min(parents_snaps[0]) + 1 |
926 _findsnapshots(revlog, snapshots, snapfloor) |
914 snapshot_cache.update(revlog, snapfloor) |
927 # search for the highest "unrelated" revision |
915 # search for the highest "unrelated" revision |
928 # |
916 # |
929 # Adding snapshots used by "unrelated" revision increase the odd we |
917 # Adding snapshots used by "unrelated" revision increase the odd we |
930 # reuse an independant, yet better snapshot chain. |
918 # reuse an independant, yet better snapshot chain. |
931 # |
919 # |
959 # likely to result in small delta |
947 # likely to result in small delta |
960 floor = None |
948 floor = None |
961 for idx, snaps in sorted(parents_snaps.items(), reverse=True): |
949 for idx, snaps in sorted(parents_snaps.items(), reverse=True): |
962 siblings = set() |
950 siblings = set() |
963 for s in snaps: |
951 for s in snaps: |
964 siblings.update(snapshots[s]) |
952 siblings.update(snapshot_cache.snapshots[s]) |
965 # Before considering making a new intermediate snapshot, we check |
953 # Before considering making a new intermediate snapshot, we check |
966 # if an existing snapshot, children of base we consider, would be |
954 # if an existing snapshot, children of base we consider, would be |
967 # suitable. |
955 # suitable. |
968 # |
956 # |
969 # It give a change to reuse a delta chain "unrelated" to the |
957 # It give a change to reuse a delta chain "unrelated" to the |
987 # |
975 # |
988 # It give a chance to reuse a delta chain unrelated to the current |
976 # It give a chance to reuse a delta chain unrelated to the current |
989 # revisions instead of starting our own. Without such re-use, |
977 # revisions instead of starting our own. Without such re-use, |
990 # topological branches would keep reopening new full chains. Creating |
978 # topological branches would keep reopening new full chains. Creating |
991 # more and more snapshot as the repository grow. |
979 # more and more snapshot as the repository grow. |
992 yield tuple(snapshots[nullrev]) |
980 yield tuple(snapshot_cache.snapshots[nullrev]) |
993 |
981 |
994 if not sparse: |
982 if not sparse: |
995 # other approach failed try against prev to hopefully save us a |
983 # other approach failed try against prev to hopefully save us a |
996 # fulltext. |
984 # fulltext. |
997 yield (prev,) |
985 yield (prev,) |
|
986 |
|
987 |
|
988 class SnapshotCache: |
|
989 __slots__ = ('snapshots', '_start_rev', '_end_rev') |
|
990 |
|
991 def __init__(self): |
|
992 # XXX should probably be a set ? |
|
993 self.snapshots = collections.defaultdict(list) |
|
994 self._start_rev = None |
|
995 self._end_rev = None |
|
996 |
|
997 def update(self, revlog, start_rev=0): |
|
998 """find snapshots from start_rev to tip""" |
|
999 nb_revs = len(revlog) |
|
1000 end_rev = nb_revs - 1 |
|
1001 if start_rev > end_rev: |
|
1002 return # range is empty |
|
1003 |
|
1004 if self._start_rev is None: |
|
1005 assert self._end_rev is None |
|
1006 self._update(revlog, start_rev, end_rev) |
|
1007 elif not (self._start_rev <= start_rev and end_rev <= self._end_rev): |
|
1008 if start_rev < self._start_rev: |
|
1009 self._update(revlog, start_rev, self._start_rev - 1) |
|
1010 if self._end_rev < end_rev: |
|
1011 self._update(revlog, self._end_rev + 1, end_rev) |
|
1012 |
|
1013 if self._start_rev is None: |
|
1014 assert self._end_rev is None |
|
1015 self._end_rev = end_rev |
|
1016 self._start_rev = start_rev |
|
1017 else: |
|
1018 self._start_rev = min(self._start_rev, start_rev) |
|
1019 self._end_rev = max(self._end_rev, end_rev) |
|
1020 assert self._start_rev <= self._end_rev, ( |
|
1021 self._start_rev, |
|
1022 self._end_rev, |
|
1023 ) |
|
1024 |
|
1025 def _update(self, revlog, start_rev, end_rev): |
|
1026 """internal method that actually do update content""" |
|
1027 assert self._start_rev is None or ( |
|
1028 start_rev < self._start_rev or start_rev > self._end_rev |
|
1029 ), (self._start_rev, self._end_rev, start_rev, end_rev) |
|
1030 assert self._start_rev is None or ( |
|
1031 end_rev < self._start_rev or end_rev > self._end_rev |
|
1032 ), (self._start_rev, self._end_rev, start_rev, end_rev) |
|
1033 cache = self.snapshots |
|
1034 if util.safehasattr(revlog.index, b'findsnapshots'): |
|
1035 revlog.index.findsnapshots(cache, start_rev, end_rev) |
|
1036 else: |
|
1037 deltaparent = revlog.deltaparent |
|
1038 issnapshot = revlog.issnapshot |
|
1039 for rev in revlog.revs(start_rev, end_rev): |
|
1040 if issnapshot(rev): |
|
1041 cache[deltaparent(rev)].append(rev) |
998 |
1042 |
999 |
1043 |
1000 class deltacomputer: |
1044 class deltacomputer: |
1001 def __init__( |
1045 def __init__( |
1002 self, |
1046 self, |