Mercurial > public > mercurial-scm > hg
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) |