changeset 18168:c351759ab0a0

branchmap: takes filtered revision in account for cache calculation Tracking tipnode and tiprev is not enough to ensure validaty of the cache as they do not help distinguish a cache that ignored various revisions below tiprev. To detect such difference, we build a hash of all ignored revisions. This hash is then used when checking the validity of a cache for a repo.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Mon, 31 Dec 2012 18:11:18 -0600
parents 59ac9a551bf4
children ae663cba9a8d
files mercurial/branchmap.py
diffstat 1 files changed, 28 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/branchmap.py	Mon Dec 24 02:57:23 2012 +0100
+++ b/mercurial/branchmap.py	Mon Dec 31 18:11:18 2012 -0600
@@ -7,6 +7,7 @@
 
 from node import bin, hex, nullid, nullrev
 import encoding
+import util
 
 def read(repo):
     try:
@@ -69,10 +70,33 @@
 class branchcache(dict):
     """A dict like object that hold branches heads cache"""
 
-    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev):
+    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
+                 filteredhash=None):
         super(branchcache, self).__init__(entries)
         self.tipnode = tipnode
         self.tiprev = tiprev
+        self.filteredhash = filteredhash
+
+    def _hashfiltered(self, repo):
+        """build hash of revision filtered in the current cache
+
+        Tracking tipnode and tiprev is not enough to ensure validaty of the
+        cache as they do not help to distinct cache that ignored various
+        revision bellow tiprev.
+
+        To detect such difference, we build a cache of all ignored revisions.
+        """
+        cl = repo.changelog
+        if not cl.filteredrevs:
+            return None
+        key = None
+        revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev)
+        if revs:
+            s = util.sha1()
+            for rev in revs:
+                s.update('%s;' % rev)
+            key = s.digest()
+        return key
 
     def validfor(self, repo):
         """Is the cache content valide regarding a repo
@@ -80,7 +104,8 @@
         - False when cached tipnode are unknown or if we detect a strip.
         - True when cache is up to date or a subset of current repo."""
         try:
-            return self.tipnode == repo.changelog.node(self.tiprev)
+            return ((self.tipnode == repo.changelog.node(self.tiprev))
+                    and (self.filteredhash == self._hashfiltered(repo)))
         except IndexError:
             return False
 
@@ -172,3 +197,4 @@
                 if tiprev > self.tiprev:
                     self.tipnode = cl.node(tiprev)
                     self.tiprev = tiprev
+        self.filteredhash = self._hashfiltered(repo)