branchmap: enable caching for filtered version too
authorPierre-Yves David <pierre-yves.david@ens-lyon.org>
Mon, 24 Dec 2012 03:21:15 +0100
changeset 18189 b9026ba002f6
parent 18188 46ed5226503a
child 18190 d57879e72e18
branchmap: enable caching for filtered version too The `_branchcache` attribute is turned into a dictionary. Key are filter name and value is a `branchcache` object. Unfiltered version is cached as `None` filter. The attribute is renamed to `_branchcaches` to avoid confusion with the previous one. Both old and new contents are dictionary even if their contents are different. I prefer possible extension code to crash right away instead of just messing the wrong dictionary. As all different caches work isolated to each other, this code keeps the previous behavior of using the unfiltered cache we nothing is filtered. This is a cheap way to have cache collaborate and nullify potential impact in the default case.
mercurial/branchmap.py
mercurial/localrepo.py
mercurial/statichttprepo.py
tests/test-phases.t
--- a/mercurial/branchmap.py	Tue Jan 01 21:27:13 2013 +0100
+++ b/mercurial/branchmap.py	Mon Dec 24 03:21:15 2012 +0100
@@ -59,9 +59,9 @@
 
 
 def updatecache(repo):
-    repo = repo.unfiltered()  # Until we get a smarter cache management
     cl = repo.changelog
-    partial = repo._branchcache
+    filtername = repo.filtername
+    partial = repo._branchcaches.get(filtername)
 
     if partial is None or not partial.validfor(repo):
         partial = read(repo)
@@ -81,7 +81,7 @@
     if partial.tiprev < tiprev:
         ctxgen = (repo[r] for r in cl.revs(partial.tiprev + 1, tiprev))
         partial.update(repo, ctxgen)
-    repo._branchcache = partial
+    repo._branchcaches[repo.filtername] = partial
 
 class branchcache(dict):
     """A dict like object that hold branches heads cache"""
--- a/mercurial/localrepo.py	Tue Jan 01 21:27:13 2013 +0100
+++ b/mercurial/localrepo.py	Mon Dec 24 03:21:15 2012 +0100
@@ -229,7 +229,7 @@
             self._writerequirements()
 
 
-        self._branchcache = None
+        self._branchcaches = {}
         self.filterpats = {}
         self._datafilters = {}
         self._transref = self._lockref = self._wlockref = None
@@ -664,14 +664,10 @@
 
     def branchmap(self):
         '''returns a dictionary {branch: [branchheads]}'''
-        if self.changelog.filteredrevs:
-            # some changeset are excluded we can't use the cache
-            bmap = branchmap.branchcache()
-            bmap.update(self, (self[r] for r in self))
-            return bmap
-        else:
-            branchmap.updatecache(self)
-            return self._branchcache
+        if self.filtername and not self.changelog.filteredrevs:
+            return self.unfiltered().branchmap()
+        branchmap.updatecache(self)
+        return self._branchcaches[self.filtername]
 
 
     def _branchtip(self, heads):
@@ -978,7 +974,7 @@
             # can't use delattr on proxy
             del self.__dict__['_tagscache']
 
-        self.unfiltered()._branchcache = None # in UTF-8
+        self.unfiltered()._branchcaches.clear()
         self.invalidatevolatilesets()
 
     def invalidatevolatilesets(self):
@@ -1437,7 +1433,7 @@
         if newheadnodes:
             ctxgen = (self[node] for node in newheadnodes
                       if self.changelog.hasnode(node))
-            cache = self._branchcache
+            cache = self._branchcaches[None]
             cache.update(self, ctxgen)
             cache.write(self)
 
@@ -2500,8 +2496,8 @@
                     cache = branchmap.branchcache(rbranchmap,
                                                   self[rtiprev].node(),
                                                   rtiprev)
-                    self._branchcache = cache
-                    cache.write(self)
+                    self._branchcaches[None] = cache
+                    cache.write(self.unfiltered())
             self.invalidate()
             return len(self.heads()) + 1
         finally:
--- a/mercurial/statichttprepo.py	Tue Jan 01 21:27:13 2013 +0100
+++ b/mercurial/statichttprepo.py	Mon Dec 24 03:21:15 2012 +0100
@@ -134,7 +134,7 @@
         self.changelog = changelog.changelog(self.sopener)
         self._tags = None
         self.nodetagscache = None
-        self._branchcache = None
+        self._branchcaches = {}
         self.encodepats = None
         self.decodepats = None
 
--- a/tests/test-phases.t	Tue Jan 01 21:27:13 2013 +0100
+++ b/tests/test-phases.t	Mon Dec 24 03:21:15 2012 +0100
@@ -173,6 +173,21 @@
 
 :note: The "(+1 heads)" is wrong as we do not had any visible head
 
+check that branch cache with "unserved" filter are properly computed and stored
+
+  $ ls ../push-dest/.hg/cache/branchheads*
+  ../push-dest/.hg/cache/branchheads
+  ../push-dest/.hg/cache/branchheads-unserved
+  $ cat ../push-dest/.hg/cache/branchheads
+  6d6770faffce199f1fddd1cf87f6f026138cf061 6
+  b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e default
+  2713879da13d6eea1ff22b442a5a87cb31a7ce6a default
+  6d6770faffce199f1fddd1cf87f6f026138cf061 default
+  $ cat ../push-dest/.hg/cache/branchheads-unserved
+  cf9fe039dfd67e829edf6522a45de057b5c86519 4
+  b3325c91a4d916bcc4cdc83ea3fe4ece46a42f6e default
+  cf9fe039dfd67e829edf6522a45de057b5c86519 default
+
 
 Restore condition prior extra insertion.
   $ hg -q --config extensions.mq= strip .