[PATCH 16 of 18 V2] branchmap: allow to use cache of subset

Pierre-Yves David pierre-yves.david at ens-lyon.org
Fri Jan 4 01:04:19 UTC 2013


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
# Date 1357087657 -3600
# Node ID 1469aa3af5ce05b94f02382f8d04fd43a26e193a
# Parent  6fe89fa91a993ac6d98953ae34d8f3aca1ce15c9
branchmap: allow to use cache of subset

Filtered repository are *subset* of unfiltered repository. This means that a
filtered branchmap could be use to compute the unfiltered version.

And filtered version happen to be subset of each other:
- "all() - unserved()" is a subset of "all() - hidden()"
- "all() - hidden()" is a subset of "all()"

This means that branchmap with "unfiltered" filter can be used as a base for
"hidden" branchmap that itself could be used as a base for unfiltered
branchmap.

   unserved < hidden < None

This changeset implements this mechanism. If the on disk branchcache is not valid
we use the branchcache of the nearest subset as base instead of computing it from
scratch. Such fallback can be cascaded multiple time is necessary.

Note that both "hidden" and "unserved" set are a bit volatile. We will add more stable
filtering in next changesets.

diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py
--- a/mercurial/branchmap.py
+++ b/mercurial/branchmap.py
@@ -5,11 +5,11 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
 from node import bin, hex, nullid, nullrev
 import encoding
-import util
+import util, repoview
 
 def _filename(repo):
     """name of a branchcache file for a given repo or repoview"""
     filename = "cache/branchheads"
     if repo.filtername:
@@ -61,20 +61,28 @@ def read(repo):
 def updatecache(repo):
     cl = repo.changelog
     filtername = repo.filtername
     partial = repo._branchcaches.get(filtername)
 
+    revs = []
     if partial is None or not partial.validfor(repo):
         partial = read(repo)
         if partial is None:
-            partial = branchcache()
-
-    revs = list(cl.revs(start=partial.tiprev +1))
+            subsetname = repoview.subsettable.get(filtername)
+            if subsetname is None:
+                partial = branchcache()
+            else:
+                subset = repo.filtered(subsetname)
+                partial = subset.branchmap().copy()
+                extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
+                revs.extend(r for  r in extrarevs if r <= partial.tiprev)
+    revs.extend(cl.revs(start=partial.tiprev + 1))
     if revs:
         ctxgen = (repo[r] for r in revs)
         partial.update(repo, ctxgen)
         partial.write(repo)
+    assert partial.validfor(repo)
     repo._branchcaches[repo.filtername] = partial
 
 class branchcache(dict):
     """A dict like object that hold branches heads cache"""
 
diff --git a/tests/test-acl.t b/tests/test-acl.t
--- a/tests/test-acl.t
+++ b/tests/test-acl.t
@@ -138,10 +138,11 @@ Extension disabled for lack of acl.sourc
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -199,10 +200,11 @@ No [acl.allow]/[acl.deny]
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -270,10 +272,11 @@ Empty [acl.allow]
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -768,10 +771,11 @@ wilma can change files with a .txt exten
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1085,10 +1089,11 @@ fred is always allowed
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1160,10 +1165,11 @@ no one is allowed inside foo/Bar/
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1311,10 +1317,11 @@ OS-level groups
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   3 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1508,10 +1515,11 @@ Branch acl deny test
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1819,10 +1827,11 @@ push foobar into the remote
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -1906,10 +1915,11 @@ Branch acl conflicting deny
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
@@ -2061,10 +2071,11 @@ Non-astro users must be denied
   """
   pushing to ../b
   query 1; heads
   searching for changes
   all remote heads known locally
+  invalid branchheads cache (unserved): tip differs
   listing keys for "bookmarks"
   4 changesets found
   list of changesets:
   ef1ea85a6374b77d6da9dcda9541f498f2d17df7
   f9cafe1212c8c6fa1120d14a556e18cc44ff8bdd
diff --git a/tests/test-fncache.t b/tests/test-fncache.t
--- a/tests/test-fncache.t
+++ b/tests/test-fncache.t
@@ -68,11 +68,11 @@ Non store repo:
   $ find .hg | sort
   .hg
   .hg/00changelog.i
   .hg/00manifest.i
   .hg/cache
-  .hg/cache/branchheads
+  .hg/cache/branchheads-unserved
   .hg/data
   .hg/data/tst.d.hg
   .hg/data/tst.d.hg/foo.i
   .hg/dirstate
   .hg/last-message.txt
@@ -96,11 +96,11 @@ Non fncache repo:
   adding tst.d/Foo
   $ find .hg | sort
   .hg
   .hg/00changelog.i
   .hg/cache
-  .hg/cache/branchheads
+  .hg/cache/branchheads-unserved
   .hg/dirstate
   .hg/last-message.txt
   .hg/requires
   .hg/store
   .hg/store/00changelog.i
diff --git a/tests/test-hardlinks.t b/tests/test-hardlinks.t
--- a/tests/test-hardlinks.t
+++ b/tests/test-hardlinks.t
@@ -194,11 +194,11 @@ Create hardlinked copy r4 of r3 (on Linu
 r4 has hardlinks in the working dir (not just inside .hg):
 
   $ nlinksdir r4
   2 r4/.hg/00changelog.i
   2 r4/.hg/branch
-  2 r4/.hg/cache/branchheads
+  2 r4/.hg/cache/branchheads-unserved
   2 r4/.hg/dirstate
   2 r4/.hg/hgrc
   2 r4/.hg/last-message.txt
   2 r4/.hg/requires
   2 r4/.hg/store/00changelog.i
@@ -224,11 +224,11 @@ Update back to revision 11 in r4 should 
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
   $ nlinksdir r4
   2 r4/.hg/00changelog.i
   1 r4/.hg/branch
-  2 r4/.hg/cache/branchheads
+  2 r4/.hg/cache/branchheads-unserved
   1 r4/.hg/dirstate
   2 r4/.hg/hgrc
   2 r4/.hg/last-message.txt
   2 r4/.hg/requires
   2 r4/.hg/store/00changelog.i
diff --git a/tests/test-inherit-mode.t b/tests/test-inherit-mode.t
--- a/tests/test-inherit-mode.t
+++ b/tests/test-inherit-mode.t
@@ -64,11 +64,11 @@ new directories are setgid
 
   $ python ../printmodes.py .
   00700 ./.hg/
   00600 ./.hg/00changelog.i
   00770 ./.hg/cache/
-  00660 ./.hg/cache/branchheads
+  00660 ./.hg/cache/branchheads-unserved
   00660 ./.hg/dirstate
   00660 ./.hg/last-message.txt
   00600 ./.hg/requires
   00770 ./.hg/store/
   00660 ./.hg/store/00changelog.i
@@ -109,11 +109,11 @@ group can still write everything
 
   $ python ../printmodes.py ../push
   00770 ../push/.hg/
   00660 ../push/.hg/00changelog.i
   00770 ../push/.hg/cache/
-  00660 ../push/.hg/cache/branchheads
+  00660 ../push/.hg/cache/branchheads-unserved
   00660 ../push/.hg/requires
   00770 ../push/.hg/store/
   00660 ../push/.hg/store/00changelog.i
   00660 ../push/.hg/store/00manifest.i
   00770 ../push/.hg/store/data/
diff --git a/tests/test-keyword.t b/tests/test-keyword.t
--- a/tests/test-keyword.t
+++ b/tests/test-keyword.t
@@ -745,11 +745,13 @@ Interrupted commit should not change sta
   ? log
 
 Commit with multi-line message and custom expansion
 
   $ hg --debug commit -l log -d '2 0' -u 'User Name <user at example.com>'
+  invalid branchheads cache: tip differs
   a
+  invalid branchheads cache: tip differs
   overwriting a expanding keywords
   committed changeset 2:bb948857c743469b22bbf51f7ec8112279ca5d83
   $ rm log
 
 Stat, verify and show custom expansion (firstline)
@@ -787,10 +789,12 @@ annotate
 remove with status checks
 
   $ hg debugrebuildstate
   $ hg remove a
   $ hg --debug commit -m rma
+  invalid branchheads cache: tip differs
+  invalid branchheads cache: tip differs
   committed changeset 3:d14c712653769de926994cf7fbb06c8fbd68f012
   $ hg status
   ? c
 
 Rollback, revert, and check expansion
@@ -897,12 +901,14 @@ kwexpand x/a should abort
   $ hg --verbose kwexpand x/a
   abort: outstanding uncommitted changes
   [255]
   $ cd x
   $ hg --debug commit -m xa -d '3 0' -u 'User Name <user at example.com>'
+  invalid branchheads cache: tip differs
   x/a
    x/a: copy a:779c764182ce5d43e2b1eb66ce06d7b47bfe342e
+  invalid branchheads cache: tip differs
   overwriting x/a expanding keywords
   committed changeset 3:b4560182a3f9a358179fd2d835c15e9da379c1e4
   $ cat a
   expand $Id: x/a b4560182a3f9 Thu, 01 Jan 1970 00:00:03 +0000 user $
   do not process $Id:
diff --git a/tests/test-newbranch.t b/tests/test-newbranch.t
--- a/tests/test-newbranch.t
+++ b/tests/test-newbranch.t
@@ -1,7 +1,17 @@
   $ branchcache=.hg/cache/branchheads
 
+  $ listbranchcaches() {
+  >    for f in .hg/cache/branchheads*;
+  >       do echo === $f ===;
+  >       cat $f;
+  >     done;
+  > }
+  $ purgebranchcaches() {
+  >     rm .hg/cache/branchheads*
+  > }
+
   $ hg init t
   $ cd t
 
   $ hg branches
   $ echo foo > a
@@ -110,11 +120,11 @@ Test for invalid branch cache:
 
   $ hg rollback
   repository tip rolled back to revision 4 (undo commit)
   working directory now based on revisions 4 and 3
 
-  $ cp $branchcache .hg/bc-invalid
+  $ cp ${branchcache}-unserved .hg/bc-invalid
 
   $ hg log -r foo
   changeset:   4:adf1a74a7f7b
   branch:      foo
   tag:         tip
@@ -140,17 +150,20 @@ Test for invalid branch cache:
   extra:       branch=foo
   description:
   modify a branch
   
   
-  $ rm $branchcache
+  $ purgebranchcaches
   $ echo corrupted > $branchcache
 
   $ hg log -qr foo
   4:adf1a74a7f7b
 
-  $ cat $branchcache
+  $ listbranchcaches
+  === .hg/cache/branchheads ===
+  corrupted
+  === .hg/cache/branchheads-unserved ===
   adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
   1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
   adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
   c21617b13b220988e7a2e26290fbe4325ffa7139 bar
 
@@ -160,19 +173,21 @@ Push should update the branch cache:
 
 Pushing just rev 0:
 
   $ hg push -qr 0 ../target
 
-  $ cat ../target/$branchcache
+  $ (cd ../target/; listbranchcaches)
+  === .hg/cache/branchheads-unserved ===
   db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 0
   db01e8ea3388fd3c7c94e1436ea2bd6a53d581c5 default
 
 Pushing everything:
 
   $ hg push -qf ../target
 
-  $ cat ../target/$branchcache
+  $ (cd ../target/; listbranchcaches)
+  === .hg/cache/branchheads-unserved ===
   adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 4
   1c28f494dae69a2f8fc815059d257eccf3fcfe75 default
   adf1a74a7f7b4cd193d12992f5d0d6a004ed21d6 foo
   c21617b13b220988e7a2e26290fbe4325ffa7139 bar
 
diff --git a/tests/test-obsolete-divergent.t b/tests/test-obsolete-divergent.t
--- a/tests/test-obsolete-divergent.t
+++ b/tests/test-obsolete-divergent.t
@@ -60,10 +60,11 @@ direct divergence
 A_1 have two direct and divergent successors A_1 and A_1
 
   $ newcase direct
   $ hg debugobsolete `getid A_0` `getid A_1`
   $ hg debugobsolete `getid A_0` `getid A_2`
+  invalid branchheads cache (unserved): tip differs
   $ hg log -G --hidden
   o  3:392fd25390da A_2
   |
   | o  2:82623d38b9ba A_1
   |/
@@ -101,10 +102,11 @@ indirect divergence with known changeset
 -------------------------------------------
 
   $ newcase indirect_known
   $ hg debugobsolete `getid A_0` `getid A_1`
   $ hg debugobsolete `getid A_0` `getid A_2`
+  invalid branchheads cache (unserved): tip differs
   $ mkcommit A_3
   created new head
   $ hg debugobsolete `getid A_2` `getid A_3`
   $ hg log -G --hidden
   @  4:01f36c5a8fda A_3
@@ -139,10 +141,11 @@ indirect divergence with known changeset
 -------------------------------------------
 
   $ newcase indirect_unknown
   $ hg debugobsolete `getid A_0` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid A_1`
+  invalid branchheads cache (unserved): tip differs
   $ hg debugobsolete `getid A_0` `getid A_2`
   $ hg log -G --hidden
   o  3:392fd25390da A_2
   |
   | o  2:82623d38b9ba A_1
@@ -170,10 +173,11 @@ do not take unknown node in account if t
 -----------------------------------------------------
 
   $ newcase final-unknown
   $ hg debugobsolete `getid A_0` `getid A_1`
   $ hg debugobsolete `getid A_1` `getid A_2`
+  invalid branchheads cache (unserved): tip differs
   $ hg debugobsolete `getid A_0` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
   $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb cccccccccccccccccccccccccccccccccccccccc
   $ hg debugobsolete `getid A_1` dddddddddddddddddddddddddddddddddddddddd
 
   $ hg debugsuccessorssets 'desc('A_0')'
@@ -186,10 +190,11 @@ divergence that converge again is not di
 -----------------------------------------------------
 
   $ newcase converged_divergence
   $ hg debugobsolete `getid A_0` `getid A_1`
   $ hg debugobsolete `getid A_0` `getid A_2`
+  invalid branchheads cache (unserved): tip differs
   $ mkcommit A_3
   created new head
   $ hg debugobsolete `getid A_1` `getid A_3`
   $ hg debugobsolete `getid A_2` `getid A_3`
   $ hg log -G --hidden
@@ -432,10 +437,11 @@ Do not report divergent successors-set i
 successors-set. (report [A,B] not [A] + [A,B])
 
   $ newcase subset
   $ hg debugobsolete `getid A_0` `getid A_2`
   $ hg debugobsolete `getid A_0` `getid A_1` `getid A_2`
+  invalid branchheads cache (unserved): tip differs
   $ hg debugsuccessorssets 'desc('A_0')'
   007dc284c1f8
       82623d38b9ba 392fd25390da
 
   $ cd ..
diff --git a/tests/test-rebase-collapse.t b/tests/test-rebase-collapse.t
--- a/tests/test-rebase-collapse.t
+++ b/tests/test-rebase-collapse.t
@@ -272,11 +272,11 @@ also, the parent of a node that is a chi
 
   $ hg heads --template="{rev}:{node} {branch}\n"
   7:c65502d4178782309ce0574c5ae6ee9485a9bafa default
   6:c772a8b2dc17629cec88a19d09c926c4814b12c7 default
 
-  $ cat $TESTTMP/b2/.hg/cache/branchheads
+  $ cat $TESTTMP/b2/.hg/cache/branchheads-unserved
   c65502d4178782309ce0574c5ae6ee9485a9bafa 7
   c772a8b2dc17629cec88a19d09c926c4814b12c7 default
   c65502d4178782309ce0574c5ae6ee9485a9bafa default
 
   $ hg strip 4



More information about the Mercurial-devel mailing list