comparison mercurial/branchmap.py @ 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 8d48af68e2ae
comparison
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)