# HG changeset patch # User Pierre-Yves David # Date 1708517129 -3600 # Node ID ac1c751884406f561b68bf40607339c06ed8605a # Parent e57d4b868a3eca680e9a700204771ac5569cd18d phases: invalidate the phases set less often on retract boundary We already have the information to update the phase set, so we do so directly instead of invalidating the cache. This show a sizeable speedup in our `perf::unbundle` benchmark on the many-draft mozilla-try repository. ### data-env-vars.name = mozilla-try-2023-03-22-zstd-sparse-revlog # benchmark.name = hg.perf.perf-unbundle # bin-env-vars.hg.flavor = no-rust # bin-env-vars.hg.py-re2-module = default # benchmark.variants.issue6528 = disabled # benchmark.variants.revs = last-10 before: 2.055259 seconds after: 1.887064 seconds (-8.18%) # benchmark.variants.revs = last-100 before: 2.409239 seconds after: 2.222429 seconds (-7.75%) # benchmark.variants.revs = last-1000 before: 3.945648 seconds after: 3.762480 seconds (-4.64%) diff -r e57d4b868a3e -r ac1c75188440 mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py Wed Feb 21 13:05:23 2024 +0100 +++ b/mercurial/bundlerepo.py Wed Feb 21 13:05:29 2024 +0100 @@ -269,9 +269,10 @@ def _write(self, fp): raise NotImplementedError - def _updateroots(self, repo, phase, newroots, tr): + def _updateroots(self, repo, phase, newroots, tr, invalidate=True): self._phaseroots[phase] = newroots - self.invalidate() + if invalidate: + self.invalidate() self.dirty = True diff -r e57d4b868a3e -r ac1c75188440 mercurial/phases.py --- a/mercurial/phases.py Wed Feb 21 13:05:23 2024 +0100 +++ b/mercurial/phases.py Wed Feb 21 13:05:29 2024 +0100 @@ -624,10 +624,11 @@ fp.write(b'%i %s\n' % (phase, hex(h))) self.dirty = False - def _updateroots(self, repo, phase, newroots, tr): + def _updateroots(self, repo, phase, newroots, tr, invalidate=True): self._phaseroots[phase] = newroots - self.invalidate() self.dirty = True + if invalidate: + self.invalidate() assert repo.filtername is None wrepo = weakref.ref(repo) @@ -811,11 +812,23 @@ changed_revs[r] = r_phase elif r in currentroots: replaced_roots.add(r) + sets = self._phasesets + sets[targetphase].update(changed_revs) + for r, old in changed_revs.items(): + if old > public: + sets[old].discard(r) if new_roots: assert changed_revs + final_roots = new_roots | currentroots - replaced_roots - self._updateroots(repo, targetphase, final_roots, tr) + self._updateroots( + repo, + targetphase, + final_roots, + tr, + invalidate=False, + ) if targetphase > 1: retracted = set(changed_revs) for lower_phase in range(1, targetphase): @@ -824,7 +837,13 @@ continue if lower_roots & retracted: simpler_roots = lower_roots - retracted - self._updateroots(repo, lower_phase, simpler_roots, tr) + self._updateroots( + repo, + lower_phase, + simpler_roots, + tr, + invalidate=False, + ) return changed_revs else: assert not changed_revs