comparison mercurial/upgrade.py @ 31896:127b41e975fd

upgrade: split finding deficiencies from finding optimisations Our ultimate goal is to make it easier to get a diagnostic of the repository format. A first important and step for that is to separate part related to repository format from the optimisation. We start by having two different functions returning the two categories of possible "improvement".
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Mon, 10 Apr 2017 21:00:52 +0200
parents 783b4c9bd5f5
children d0067250542d
comparison
equal deleted inserted replaced
31895:783b4c9bd5f5 31896:127b41e975fd
136 self.upgrademessage = upgrademessage 136 self.upgrademessage = upgrademessage
137 137
138 for k, v in kwargs.items(): 138 for k, v in kwargs.items():
139 setattr(self, k, v) 139 setattr(self, k, v)
140 140
141 def findimprovements(repo): 141 def finddeficiencies(repo):
142 """Determine improvements that can be made to the repo during upgrade. 142 """returns a list of deficiencies that the repo suffer from"""
143
144 Returns a list of ``upgradeimprovement`` describing repository deficiencies
145 and optimizations.
146 """
147 newreporeqs = localrepo.newreporequirements(repo) 143 newreporeqs = localrepo.newreporequirements(repo)
148 144
149 improvements = [] 145 deficiencies = []
150 146
151 # We could detect lack of revlogv1 and store here, but they were added 147 # We could detect lack of revlogv1 and store here, but they were added
152 # in 0.9.2 and we don't support upgrading repos without these 148 # in 0.9.2 and we don't support upgrading repos without these
153 # requirements, so let's not bother. 149 # requirements, so let's not bother.
154 150
155 if 'fncache' not in repo.requirements: 151 if 'fncache' not in repo.requirements:
156 improvements.append(improvement( 152 deficiencies.append(improvement(
157 name='fncache', 153 name='fncache',
158 type=deficiency, 154 type=deficiency,
159 description=_('long and reserved filenames may not work correctly; ' 155 description=_('long and reserved filenames may not work correctly; '
160 'repository performance is sub-optimal'), 156 'repository performance is sub-optimal'),
161 upgrademessage=_('repository will be more resilient to storing ' 157 upgrademessage=_('repository will be more resilient to storing '
163 'operations should be improved'), 159 'operations should be improved'),
164 fromdefault=True, 160 fromdefault=True,
165 fromconfig='fncache' in newreporeqs)) 161 fromconfig='fncache' in newreporeqs))
166 162
167 if 'dotencode' not in repo.requirements: 163 if 'dotencode' not in repo.requirements:
168 improvements.append(improvement( 164 deficiencies.append(improvement(
169 name='dotencode', 165 name='dotencode',
170 type=deficiency, 166 type=deficiency,
171 description=_('storage of filenames beginning with a period or ' 167 description=_('storage of filenames beginning with a period or '
172 'space may not work correctly'), 168 'space may not work correctly'),
173 upgrademessage=_('repository will be better able to store files ' 169 upgrademessage=_('repository will be better able to store files '
174 'beginning with a space or period'), 170 'beginning with a space or period'),
175 fromdefault=True, 171 fromdefault=True,
176 fromconfig='dotencode' in newreporeqs)) 172 fromconfig='dotencode' in newreporeqs))
177 173
178 if 'generaldelta' not in repo.requirements: 174 if 'generaldelta' not in repo.requirements:
179 improvements.append(improvement( 175 deficiencies.append(improvement(
180 name='generaldelta', 176 name='generaldelta',
181 type=deficiency, 177 type=deficiency,
182 description=_('deltas within internal storage are unable to ' 178 description=_('deltas within internal storage are unable to '
183 'choose optimal revisions; repository is larger and ' 179 'choose optimal revisions; repository is larger and '
184 'slower than it could be; interaction with other ' 180 'slower than it could be; interaction with other '
198 # changelogs with deltas. 194 # changelogs with deltas.
199 cl = repo.changelog 195 cl = repo.changelog
200 for rev in cl: 196 for rev in cl:
201 chainbase = cl.chainbase(rev) 197 chainbase = cl.chainbase(rev)
202 if chainbase != rev: 198 if chainbase != rev:
203 improvements.append(improvement( 199 deficiencies.append(improvement(
204 name='removecldeltachain', 200 name='removecldeltachain',
205 type=deficiency, 201 type=deficiency,
206 description=_('changelog storage is using deltas instead of ' 202 description=_('changelog storage is using deltas instead of '
207 'raw entries; changelog reading and any ' 203 'raw entries; changelog reading and any '
208 'operation relying on changelog data are slower ' 204 'operation relying on changelog data are slower '
212 'faster; changelog size may be reduced'), 208 'faster; changelog size may be reduced'),
213 fromdefault=True, 209 fromdefault=True,
214 fromconfig=True)) 210 fromconfig=True))
215 break 211 break
216 212
217 # Now for the optimizations. 213 return deficiencies
218 214
215 def findoptimizations(repo):
216 """Determine optimisation that could be used during upgrade"""
219 # These are unconditionally added. There is logic later that figures out 217 # These are unconditionally added. There is logic later that figures out
220 # which ones to apply. 218 # which ones to apply.
221 219 optimizations = []
222 improvements.append(improvement( 220
221 optimizations.append(improvement(
223 name='redeltaparent', 222 name='redeltaparent',
224 type=optimisation, 223 type=optimisation,
225 description=_('deltas within internal storage will be recalculated to ' 224 description=_('deltas within internal storage will be recalculated to '
226 'choose an optimal base revision where this was not ' 225 'choose an optimal base revision where this was not '
227 'already done; the size of the repository may shrink and ' 226 'already done; the size of the repository may shrink and '
230 'execution considerably; subsequent invocations should ' 229 'execution considerably; subsequent invocations should '
231 'not run noticeably slower'), 230 'not run noticeably slower'),
232 upgrademessage=_('deltas within internal storage will choose a new ' 231 upgrademessage=_('deltas within internal storage will choose a new '
233 'base revision if needed'))) 232 'base revision if needed')))
234 233
235 improvements.append(improvement( 234 optimizations.append(improvement(
236 name='redeltamultibase', 235 name='redeltamultibase',
237 type=optimisation, 236 type=optimisation,
238 description=_('deltas within internal storage will be recalculated ' 237 description=_('deltas within internal storage will be recalculated '
239 'against multiple base revision and the smallest ' 238 'against multiple base revision and the smallest '
240 'difference will be used; the size of the repository may ' 239 'difference will be used; the size of the repository may '
247 upgrademessage=_('deltas within internal storage will choose an ' 246 upgrademessage=_('deltas within internal storage will choose an '
248 'optimal delta by computing deltas against multiple ' 247 'optimal delta by computing deltas against multiple '
249 'parents; may slow down execution time ' 248 'parents; may slow down execution time '
250 'significantly'))) 249 'significantly')))
251 250
252 improvements.append(improvement( 251 optimizations.append(improvement(
253 name='redeltaall', 252 name='redeltaall',
254 type=optimisation, 253 type=optimisation,
255 description=_('deltas within internal storage will always be ' 254 description=_('deltas within internal storage will always be '
256 'recalculated without reusing prior deltas; this will ' 255 'recalculated without reusing prior deltas; this will '
257 'likely make execution run several times slower; this ' 256 'likely make execution run several times slower; this '
258 'optimization is typically not needed'), 257 'optimization is typically not needed'),
259 upgrademessage=_('deltas within internal storage will be fully ' 258 upgrademessage=_('deltas within internal storage will be fully '
260 'recomputed; this will likely drastically slow down ' 259 'recomputed; this will likely drastically slow down '
261 'execution time'))) 260 'execution time')))
262 261
263 return improvements 262 return optimizations
264 263
265 def determineactions(repo, improvements, sourcereqs, destreqs, 264 def determineactions(repo, improvements, sourcereqs, destreqs,
266 optimize): 265 optimize):
267 """Determine upgrade actions that will be performed. 266 """Determine upgrade actions that will be performed.
268 267
269 Given a list of improvements as returned by ``upgradefindimprovements``, 268 Given a list of improvements as returned by ``finddeficiencies`` and
270 determine the list of upgrade actions that will be performed. 269 ``findoptimizations``, determine the list of upgrade actions that
270 will be performed.
271 271
272 The role of this function is to filter improvements if needed, apply 272 The role of this function is to filter improvements if needed, apply
273 recommended optimizations from the improvements list that make sense, 273 recommended optimizations from the improvements list that make sense,
274 etc. 274 etc.
275 275
619 raise error.Abort(_('cannot upgrade repository; do not support ' 619 raise error.Abort(_('cannot upgrade repository; do not support '
620 'destination requirement: %s') % 620 'destination requirement: %s') %
621 _(', ').join(sorted(unsupportedreqs))) 621 _(', ').join(sorted(unsupportedreqs)))
622 622
623 # Find and validate all improvements that can be made. 623 # Find and validate all improvements that can be made.
624 improvements = findimprovements(repo) 624 improvements = finddeficiencies(repo) + findoptimizations(repo)
625 for i in improvements: 625 for i in improvements:
626 if i.type not in (deficiency, optimisation): 626 if i.type not in (deficiency, optimisation):
627 raise error.Abort(_('unexpected improvement type %s for %s') % ( 627 raise error.Abort(_('unexpected improvement type %s for %s') % (
628 i.type, i.name)) 628 i.type, i.name))
629 629