##// END OF EJS Templates
delta-find: move `_rawgroups` on the `_DeltaSearch` object...
marmoute -
r52215:a227e061 default
parent child Browse files
Show More
@@ -888,13 +888,7 b' class _DeltaSearch:'
888 888 return
889 889 if self.snapshot_cache is None:
890 890 self.snapshot_cache = SnapshotCache()
891 groups = _rawgroups(
892 self.revlog,
893 self.p1,
894 self.p2,
895 self.cachedelta,
896 self.snapshot_cache,
897 )
891 groups = self._raw_groups()
898 892 for candidates in groups:
899 893 good = yield candidates
900 894 if good is not None:
@@ -937,127 +931,133 b' class _DeltaSearch:'
937 931
938 932 yield None
939 933
934 def _raw_groups(self):
935 """Provides group of revision to be tested as delta base
940 936
941 def _rawgroups(revlog, p1, p2, cachedelta, snapshot_cache=None):
942 """Provides group of revision to be tested as delta base
937 This lower level function focus on emitting delta theorically
938 interresting without looking it any practical details.
943 939
944 This lower level function focus on emitting delta theorically interresting
945 without looking it any practical details.
940 The group order aims at providing fast or small candidates first.
941 """
942 # Why search for delta base if we cannot use a delta base ?
943 assert self.revlog.delta_config.general_delta
944 # also see issue6056
945 sparse = self.revlog.delta_config.sparse_revlog
946 curr = len(self.revlog)
947 prev = curr - 1
948 deltachain = lambda rev: self.revlog._deltachain(rev)[0]
946 949
947 The group order aims at providing fast or small candidates first.
948 """
949 # Why search for delta base if we cannot use a delta base ?
950 assert revlog.delta_config.general_delta
951 # also see issue6056
952 sparse = revlog.delta_config.sparse_revlog
953 curr = len(revlog)
954 prev = curr - 1
955 deltachain = lambda rev: revlog._deltachain(rev)[0]
950 # exclude already lazy tested base if any
951 parents = [p for p in (self.p1, self.p2) if p != nullrev]
956 952
957 # exclude already lazy tested base if any
958 parents = [p for p in (p1, p2) if p != nullrev]
953 if (
954 not self.revlog.delta_config.delta_both_parents
955 and len(parents) == 2
956 ):
957 parents.sort()
958 # To minimize the chance of having to build a fulltext,
959 # pick first whichever parent is closest to us (max rev)
960 yield (parents[1],)
961 # then the other one (min rev) if the first did not fit
962 yield (parents[0],)
963 elif len(parents) > 0:
964 # Test all parents (1 or 2), and keep the best candidate
965 yield parents
959 966
960 if not revlog.delta_config.delta_both_parents and len(parents) == 2:
961 parents.sort()
962 # To minimize the chance of having to build a fulltext,
963 # pick first whichever parent is closest to us (max rev)
964 yield (parents[1],)
965 # then the other one (min rev) if the first did not fit
966 yield (parents[0],)
967 elif len(parents) > 0:
968 # Test all parents (1 or 2), and keep the best candidate
969 yield parents
970
971 if sparse and parents:
972 if snapshot_cache is None:
973 # map: base-rev: [snapshot-revs]
974 snapshot_cache = SnapshotCache()
975 # See if we can use an existing snapshot in the parent chains to use as
976 # a base for a new intermediate-snapshot
977 #
978 # search for snapshot in parents delta chain
979 # map: snapshot-level: snapshot-rev
980 parents_snaps = collections.defaultdict(set)
981 candidate_chains = [deltachain(p) for p in parents]
982 for chain in candidate_chains:
983 for idx, s in enumerate(chain):
984 if not revlog.issnapshot(s):
967 if sparse and parents:
968 if self.snapshot_cache is None:
969 # map: base-rev: [snapshot-revs]
970 self.snapshot_cache = SnapshotCache()
971 # See if we can use an existing snapshot in the parent chains to
972 # use as a base for a new intermediate-snapshot
973 #
974 # search for snapshot in parents delta chain map: snapshot-level:
975 # snapshot-rev
976 parents_snaps = collections.defaultdict(set)
977 candidate_chains = [deltachain(p) for p in parents]
978 for chain in candidate_chains:
979 for idx, s in enumerate(chain):
980 if not self.revlog.issnapshot(s):
981 break
982 parents_snaps[idx].add(s)
983 snapfloor = min(parents_snaps[0]) + 1
984 self.snapshot_cache.update(self.revlog, snapfloor)
985 # search for the highest "unrelated" revision
986 #
987 # Adding snapshots used by "unrelated" revision increase the odd we
988 # reuse an independant, yet better snapshot chain.
989 #
990 # XXX instead of building a set of revisions, we could lazily
991 # enumerate over the chains. That would be more efficient, however
992 # we stick to simple code for now.
993 all_revs = set()
994 for chain in candidate_chains:
995 all_revs.update(chain)
996 other = None
997 for r in self.revlog.revs(prev, snapfloor):
998 if r not in all_revs:
999 other = r
985 1000 break
986 parents_snaps[idx].add(s)
987 snapfloor = min(parents_snaps[0]) + 1
988 snapshot_cache.update(revlog, snapfloor)
989 # search for the highest "unrelated" revision
990 #
991 # Adding snapshots used by "unrelated" revision increase the odd we
992 # reuse an independant, yet better snapshot chain.
993 #
994 # XXX instead of building a set of revisions, we could lazily enumerate
995 # over the chains. That would be more efficient, however we stick to
996 # simple code for now.
997 all_revs = set()
998 for chain in candidate_chains:
999 all_revs.update(chain)
1000 other = None
1001 for r in revlog.revs(prev, snapfloor):
1002 if r not in all_revs:
1003 other = r
1004 break
1005 if other is not None:
1006 # To avoid unfair competition, we won't use unrelated intermediate
1007 # snapshot that are deeper than the ones from the parent delta
1008 # chain.
1009 max_depth = max(parents_snaps.keys())
1010 chain = deltachain(other)
1011 for depth, s in enumerate(chain):
1012 if s < snapfloor:
1013 continue
1014 if max_depth < depth:
1015 break
1016 if not revlog.issnapshot(s):
1017 break
1018 parents_snaps[depth].add(s)
1019 # Test them as possible intermediate snapshot base
1020 # We test them from highest to lowest level. High level one are more
1021 # likely to result in small delta
1022 floor = None
1023 for idx, snaps in sorted(parents_snaps.items(), reverse=True):
1024 siblings = set()
1025 for s in snaps:
1026 siblings.update(snapshot_cache.snapshots[s])
1027 # Before considering making a new intermediate snapshot, we check
1028 # if an existing snapshot, children of base we consider, would be
1029 # suitable.
1001 if other is not None:
1002 # To avoid unfair competition, we won't use unrelated
1003 # intermediate snapshot that are deeper than the ones from the
1004 # parent delta chain.
1005 max_depth = max(parents_snaps.keys())
1006 chain = deltachain(other)
1007 for depth, s in enumerate(chain):
1008 if s < snapfloor:
1009 continue
1010 if max_depth < depth:
1011 break
1012 if not self.revlog.issnapshot(s):
1013 break
1014 parents_snaps[depth].add(s)
1015 # Test them as possible intermediate snapshot base We test them
1016 # from highest to lowest level. High level one are more likely to
1017 # result in small delta
1018 floor = None
1019 for idx, snaps in sorted(parents_snaps.items(), reverse=True):
1020 siblings = set()
1021 for s in snaps:
1022 siblings.update(self.snapshot_cache.snapshots[s])
1023 # Before considering making a new intermediate snapshot, we
1024 # check if an existing snapshot, children of base we consider,
1025 # would be suitable.
1026 #
1027 # It give a change to reuse a delta chain "unrelated" to the
1028 # current revision instead of starting our own. Without such
1029 # re-use, topological branches would keep reopening new chains.
1030 # Creating more and more snapshot as the repository grow.
1031
1032 if floor is not None:
1033 # We only do this for siblings created after the one in our
1034 # parent's delta chain. Those created before has less
1035 # chances to be valid base since our ancestors had to
1036 # create a new snapshot.
1037 siblings = [r for r in siblings if floor < r]
1038 yield tuple(sorted(siblings))
1039 # then test the base from our parent's delta chain.
1040 yield tuple(sorted(snaps))
1041 floor = min(snaps)
1042 # No suitable base found in the parent chain, search if any full
1043 # snapshots emitted since parent's base would be a suitable base
1044 # for an intermediate snapshot.
1030 1045 #
1031 # It give a change to reuse a delta chain "unrelated" to the
1032 # current revision instead of starting our own. Without such
1033 # re-use, topological branches would keep reopening new chains.
1046 # It give a chance to reuse a delta chain unrelated to the current
1047 # revisions instead of starting our own. Without such re-use,
1048 # topological branches would keep reopening new full chains.
1034 1049 # Creating more and more snapshot as the repository grow.
1050 full = [
1051 r
1052 for r in self.snapshot_cache.snapshots[nullrev]
1053 if snapfloor <= r
1054 ]
1055 yield tuple(sorted(full))
1035 1056
1036 if floor is not None:
1037 # We only do this for siblings created after the one in our
1038 # parent's delta chain. Those created before has less chances
1039 # to be valid base since our ancestors had to create a new
1040 # snapshot.
1041 siblings = [r for r in siblings if floor < r]
1042 yield tuple(sorted(siblings))
1043 # then test the base from our parent's delta chain.
1044 yield tuple(sorted(snaps))
1045 floor = min(snaps)
1046 # No suitable base found in the parent chain, search if any full
1047 # snapshots emitted since parent's base would be a suitable base for an
1048 # intermediate snapshot.
1049 #
1050 # It give a chance to reuse a delta chain unrelated to the current
1051 # revisions instead of starting our own. Without such re-use,
1052 # topological branches would keep reopening new full chains. Creating
1053 # more and more snapshot as the repository grow.
1054 full = [r for r in snapshot_cache.snapshots[nullrev] if snapfloor <= r]
1055 yield tuple(sorted(full))
1056
1057 if not sparse:
1058 # other approach failed try against prev to hopefully save us a
1059 # fulltext.
1060 yield (prev,)
1057 if not sparse:
1058 # other approach failed try against prev to hopefully save us a
1059 # fulltext.
1060 yield (prev,)
1061 1061
1062 1062
1063 1063 class SnapshotCache:
General Comments 0
You need to be logged in to leave comments. Login now