[PATCH 2 of 7 Series-F] performance: speedup computation of hidden revisions

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


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1357274641 -3600
# Node ID fdd02003dac5afd722565ebff18fcb56a3524bd8
# Parent  191a394f3de541324eeb95c07426ebf9f3428aa7
performance: speedup computation of hidden revisions

In they current state revset call can be very costly as we test predicates on
the will repository. The hidden filter will be very widely used and need to be
very fast.

The current changeset drop revset call in favor of direct revision manipulation.


Performance test on my Mercurial checkout

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

Before this changes, :

 ! obsolete
 ! wall 0.004483 comb 0.000000 user 0.000000 sys 0.000000 (best of 553)
 ! hidden
 ! wall 0.077553 comb 0.080000 user 0.080000 sys 0.000000 (best of 100)


After this changes:

  ! obsolete
  ! wall 0.004470 comb 0.000000 user 0.000000 sys 0.000000 (best of 542)
  ! hidden
  ! wall 0.011230 comb 0.010000 user 0.010000 sys 0.000000 (best of 238)

Performance test on a Mozilla central checkout:

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

Before this changes, :

  ! obsolete
  ! wall 0.000017 comb 0.000000 user 0.000000 sys 0.000000 (best of 123458)
  ! hidden
  ! wall 0.389472 comb 0.380000 user 0.380000 sys 0.000000 (best of 25)


After this changes:

  ! obsolete
  ! wall 0.000017 comb 0.000000 user 0.000000 sys 0.000000 (best of 123089)
  ! hidden
  ! wall 0.000079 comb 0.000000 user 0.000000 sys 0.000000 (best of 33930)

diff --git a/mercurial/repoview.py b/mercurial/repoview.py
--- a/mercurial/repoview.py
+++ b/mercurial/repoview.py
@@ -7,21 +7,31 @@
 # GNU General Public License version 2 or any later version.
 
 import copy
 import phases
 import util
+import obsolete, bookmarks, revset
 
 
 def computehidden(repo):
     """compute the set of hidden revision to filter
 
     During most operation hidden should be filtered."""
     assert not repo.changelog.filteredrevs
-    if repo.obsstore:
-        ### hide extinct changeset that are not accessible by any mean
-        hiddenquery = 'extinct() - ::(parents() + bookmark())'
-        return frozenset(repo.revs(hiddenquery))
+    hideable = obsolete.getrevs(repo, 'obsolete')
+    if hideable:
+        cl = repo.changelog
+        firsthideable = min(hideable)
+        revs = cl.revs(start=firsthideable)
+        blockers = [r for r in revset._children(repo, revs, hideable)
+                      if r not in hideable]
+        for par in repo[None].parents():
+            blockers.append(par.rev())
+        for bm in bookmarks.listbookmarks(repo).values():
+            blockers.append(repo[bm].rev())
+        blocked = cl.ancestors(blockers, inclusive=True)
+        return frozenset(r for r in hideable if r not in blocked)
     return frozenset()
 
 def computeunserved(repo):
     """compute the set of revision that should be filtered when used a server
 


More information about the Mercurial-devel mailing list