mercurial/branchmap.py
changeset 18168 c351759ab0a0
parent 18167 59ac9a551bf4
child 18184 8d48af68e2ae
equal deleted inserted replaced
18167:59ac9a551bf4 18168:c351759ab0a0
     5 # This software may be used and distributed according to the terms of the
     5 # This software may be used and distributed according to the terms of the
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from node import bin, hex, nullid, nullrev
     8 from node import bin, hex, nullid, nullrev
     9 import encoding
     9 import encoding
       
    10 import util
    10 
    11 
    11 def read(repo):
    12 def read(repo):
    12     try:
    13     try:
    13         f = repo.opener("cache/branchheads")
    14         f = repo.opener("cache/branchheads")
    14         lines = f.read().split('\n')
    15         lines = f.read().split('\n')
    67     repo._branchcache = partial
    68     repo._branchcache = partial
    68 
    69 
    69 class branchcache(dict):
    70 class branchcache(dict):
    70     """A dict like object that hold branches heads cache"""
    71     """A dict like object that hold branches heads cache"""
    71 
    72 
    72     def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev):
    73     def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
       
    74                  filteredhash=None):
    73         super(branchcache, self).__init__(entries)
    75         super(branchcache, self).__init__(entries)
    74         self.tipnode = tipnode
    76         self.tipnode = tipnode
    75         self.tiprev = tiprev
    77         self.tiprev = tiprev
       
    78         self.filteredhash = filteredhash
       
    79 
       
    80     def _hashfiltered(self, repo):
       
    81         """build hash of revision filtered in the current cache
       
    82 
       
    83         Tracking tipnode and tiprev is not enough to ensure validaty of the
       
    84         cache as they do not help to distinct cache that ignored various
       
    85         revision bellow tiprev.
       
    86 
       
    87         To detect such difference, we build a cache of all ignored revisions.
       
    88         """
       
    89         cl = repo.changelog
       
    90         if not cl.filteredrevs:
       
    91             return None
       
    92         key = None
       
    93         revs = sorted(r for r in cl.filteredrevs if r <= self.tiprev)
       
    94         if revs:
       
    95             s = util.sha1()
       
    96             for rev in revs:
       
    97                 s.update('%s;' % rev)
       
    98             key = s.digest()
       
    99         return key
    76 
   100 
    77     def validfor(self, repo):
   101     def validfor(self, repo):
    78         """Is the cache content valide regarding a repo
   102         """Is the cache content valide regarding a repo
    79 
   103 
    80         - False when cached tipnode are unknown or if we detect a strip.
   104         - False when cached tipnode are unknown or if we detect a strip.
    81         - True when cache is up to date or a subset of current repo."""
   105         - True when cache is up to date or a subset of current repo."""
    82         try:
   106         try:
    83             return self.tipnode == repo.changelog.node(self.tiprev)
   107             return ((self.tipnode == repo.changelog.node(self.tiprev))
       
   108                     and (self.filteredhash == self._hashfiltered(repo)))
    84         except IndexError:
   109         except IndexError:
    85             return False
   110             return False
    86 
   111 
    87 
   112 
    88     def write(self, repo):
   113     def write(self, repo):
   170             for heads in self.values():
   195             for heads in self.values():
   171                 tiprev = max(cl.rev(node) for node in heads)
   196                 tiprev = max(cl.rev(node) for node in heads)
   172                 if tiprev > self.tiprev:
   197                 if tiprev > self.tiprev:
   173                     self.tipnode = cl.node(tiprev)
   198                     self.tipnode = cl.node(tiprev)
   174                     self.tiprev = tiprev
   199                     self.tiprev = tiprev
       
   200         self.filteredhash = self._hashfiltered(repo)