# HG changeset patch # User Pierre-Yves David # Date 1356999078 21600 # Node ID c351759ab0a07dcd92d6312ab0a02e5bfaafde4a # Parent 59ac9a551bf4aa72cc9b2e4e167f7ac03179fbaf 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. diff -r 59ac9a551bf4 -r c351759ab0a0 mercurial/branchmap.py --- 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)