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 |
|
|
|
1003 |
|
|
|
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 |
|
|
|
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 chan |
|
|
1032 |
# |
|
|
1033 |
# |
|
|
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 |
|
|
|
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