comparison mercurial/revlogutils/deltas.py @ 51356:701caeabbee7

delta-find: finish reworking the snapshot logic and drop more layer The refining logic only applies to the snapshot logic, and this is now all contained in a dedicated method. Along the way, we drop the refined_groups // raw_groups layer as they no longer make sense. The result is a more explicit `iter_groups` method. This conclude the splitting and simplification of the groups generation. We are now ready to dispatch this in more diverse classes.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 23 Nov 2023 22:40:11 +0100
parents fac6038b11f5
children d7e2acdd50ba
comparison
equal deleted inserted replaced
51355:fac6038b11f5 51356:701caeabbee7
836 836
837 def _init_group(self): 837 def _init_group(self):
838 # Why search for delta base if we cannot use a delta base ? 838 # Why search for delta base if we cannot use a delta base ?
839 # also see issue6056 839 # also see issue6056
840 assert self.revlog.delta_config.general_delta 840 assert self.revlog.delta_config.general_delta
841 self._candidates_iterator = self._refined_groups() 841 self._candidates_iterator = self._iter_groups()
842 self._last_good = None 842 self._last_good = None
843 if ( 843 if (
844 self.cachedelta is not None 844 self.cachedelta is not None
845 and self.cachedelta[2] > DELTA_BASE_REUSE_NO 845 and self.cachedelta[2] > DELTA_BASE_REUSE_NO
846 and self._pre_filter_rev(self.cachedelta[0]) 846 and self._pre_filter_rev(self.cachedelta[0])
1080 self.current_stage = _STAGE_PREV 1080 self.current_stage = _STAGE_PREV
1081 yield (self.target_rev - 1,) 1081 yield (self.target_rev - 1,)
1082 1082
1083 def _iter_snapshots_base(self): 1083 def _iter_snapshots_base(self):
1084 assert self.revlog.delta_config.sparse_revlog 1084 assert self.revlog.delta_config.sparse_revlog
1085 assert self.current_stage == _STAGE_SNAPSHOT
1085 prev = self.target_rev - 1 1086 prev = self.target_rev - 1
1086 deltachain = lambda rev: self.revlog._deltachain(rev)[0] 1087 deltachain = lambda rev: self.revlog._deltachain(rev)[0]
1087 1088
1088 parents = [p for p in (self.p1, self.p2) if p != nullrev] 1089 parents = [p for p in (self.p1, self.p2) if p != nullrev]
1089 if not parents: 1090 if not parents:
1090 return 1091 return
1091 self.current_stage = _STAGE_SNAPSHOT
1092 # See if we can use an existing snapshot in the parent chains to 1092 # See if we can use an existing snapshot in the parent chains to
1093 # use as a base for a new intermediate-snapshot 1093 # use as a base for a new intermediate-snapshot
1094 # 1094 #
1095 # search for snapshot in parents delta chain map: snapshot-level: 1095 # search for snapshot in parents delta chain map: snapshot-level:
1096 # snapshot-rev 1096 # snapshot-rev
1171 full = [ 1171 full = [
1172 r for r in self.snapshot_cache.snapshots[nullrev] if snapfloor <= r 1172 r for r in self.snapshot_cache.snapshots[nullrev] if snapfloor <= r
1173 ] 1173 ]
1174 yield tuple(sorted(full)) 1174 yield tuple(sorted(full))
1175 1175
1176 def _refined_groups(self): 1176 def _iter_snapshots(self):
1177 assert self.revlog.delta_config.sparse_revlog
1178 self.current_stage = _STAGE_SNAPSHOT
1177 good = None 1179 good = None
1178 groups = self._raw_groups() 1180 groups = self._iter_snapshots_base()
1179 for candidates in groups: 1181 for candidates in groups:
1180 good = yield candidates 1182 good = yield candidates
1181 if good is not None: 1183 if good is not None:
1182 break 1184 break
1183
1184 # If sparse revlog is enabled, we can try to refine the available
1185 # deltas
1186 if not self.revlog.delta_config.sparse_revlog:
1187 self.current_stage = _STAGE_FULL
1188 yield None
1189 return
1190
1191 # if we have a refinable value, try to refine it 1185 # if we have a refinable value, try to refine it
1192 if ( 1186 if (
1193 good is not None 1187 good is not None
1194 and good not in (self.p1, self.p2) 1188 and good not in (self.p1, self.p2)
1195 and self.revlog.issnapshot(good) 1189 and self.revlog.issnapshot(good)
1211 previous = good 1205 previous = good
1212 children = tuple( 1206 children = tuple(
1213 sorted(c for c in self.snapshot_cache.snapshots[good]) 1207 sorted(c for c in self.snapshot_cache.snapshots[good])
1214 ) 1208 )
1215 good = yield children 1209 good = yield children
1216
1217 self.current_stage = _STAGE_FULL
1218 yield None 1210 yield None
1219 1211
1220 def _raw_groups(self): 1212 def _iter_groups(self):
1221 """Provides group of revision to be tested as delta base 1213 good = None
1222 1214 for group in self._iter_parents():
1223 This lower level function focus on emitting delta theorically 1215 good = yield group
1224 interresting without looking it any practical details. 1216 if good is not None:
1225 1217 break
1226 The group order aims at providing fast or small candidates first.
1227 """
1228 yield from self._iter_parents()
1229 if self.revlog.delta_config.sparse_revlog:
1230 yield from self._iter_snapshots_base()
1231 else: 1218 else:
1232 yield from self._iter_prev() 1219 assert good is None
1220 if self.revlog.delta_config.sparse_revlog:
1221 # If sparse revlog is enabled, we can try to refine the
1222 # available deltas
1223 iter_snap = self._iter_snapshots()
1224 group = iter_snap.send(None)
1225 while group is not None:
1226 good = yield group
1227 group = iter_snap.send(good)
1228 else:
1229 yield from self._iter_prev()
1230 yield None
1233 1231
1234 1232
1235 class SnapshotCache: 1233 class SnapshotCache:
1236 __slots__ = ('snapshots', '_start_rev', '_end_rev') 1234 __slots__ = ('snapshots', '_start_rev', '_end_rev')
1237 1235