[PATCH 3 of 7 Series-F] performance: speedup computation of unserved revisions

pierre-yves.david at logilab.fr pierre-yves.david at logilab.fr
Tue Jan 8 12:54:02 CST 2013


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1357327145 -3600
# Node ID 66e2c7a2eeb8e0ce02ec87fc1ca3197efafafe20
# Parent  fdd02003dac5afd722565ebff18fcb56a3524bd8
performance: speedup computation of unserved revisions

In they current state revset call can be very costly as we test predicates on
the will repository. The "unserved" filter is used in multiple application and
serve in particular in some branch cache loading operation. We better make it
fast.

The current changeset drop revset call in favor of direct testing of the phase
of changeset.

Performance test on my Mercurial checkout

- 19857 total changesets,
- 1584 obsolete changesets,
- 13310 obsolescence markers.

Before this changes, :

  ! hidden
  ! wall 0.011419 comb 0.010000 user 0.010000 sys 0.000000 (best of 205)
  ! unserved
  ! wall 0.030477 comb 0.030000 user 0.030000 sys 0.000000 (best of 100)

After this changes:

  ! hidden
  ! wall 0.011119 comb 0.020000 user 0.020000 sys 0.000000 (best of 203)
  ! unserved
  ! wall 0.011844 comb 0.010000 user 0.010000 sys 0.000000 (best of 226)

Performance test on a Mozilla central checkout:

- 117293 total changesets,
- 1 obsolete changeset,
- 1 obsolescence marker.

Before this changes, :

  ! hidden
  ! wall 0.000079 comb 0.000000 user 0.000000 sys 0.000000 (best of 28270)
  ! unserved
  ! wall 0.111259 comb 0.120000 user 0.110000 sys 0.010000 (best of 85)


After this changes:

  ! hidden
  ! wall 0.000078 comb 0.000000 user 0.000000 sys 0.000000 (best of 30150)
  ! unserved
  ! wall 0.000084 comb 0.000000 user 0.000000 sys 0.000000 (best of 30192)

diff --git a/mercurial/repoview.py b/mercurial/repoview.py
--- a/mercurial/repoview.py
+++ b/mercurial/repoview.py
@@ -36,12 +36,21 @@ def computeunserved(repo):
     """compute the set of revision that should be filtered when used a server
 
     Secret and hidden changeset should not pretend to be here."""
     assert not repo.changelog.filteredrevs
     # fast path in simple case to avoid impact of non optimised code
-    if phases.hassecret(repo) or repo.obsstore:
-        return frozenset(repo.revs('hidden() + secret()'))
+    hiddens = filteredrevs(repo, 'hidden')
+    if phases.hassecret(repo):
+        cl = repo.changelog
+        secret = phases.secret
+        getphase = repo._phasecache.phase
+        first = min(cl.rev(n) for n in repo._phasecache.phaseroots[secret])
+        revs = cl.revs(start=first)
+        secrets = set(r for r in revs if getphase(repo, r) >= secret)
+        return frozenset(hiddens | secrets)
+    else:
+        return hiddens
     return frozenset()
 
 def computemutable(repo):
     """compute the set of revision that should be filtered when used a server
 


More information about the Mercurial-devel mailing list