124 if p != nullrev and p in domain and p not in ancestors: |
121 if p != nullrev and p in domain and p not in ancestors: |
125 ancestors.add(p) |
122 ancestors.add(p) |
126 stack.append(p) |
123 stack.append(p) |
127 return ancestors |
124 return ancestors |
128 |
125 |
129 cacheversion = 1 |
|
130 cachefile = 'cache/hidden' |
|
131 |
|
132 def cachehash(repo, hideable): |
|
133 """return sha1 hash of repository data to identify a valid cache. |
|
134 |
|
135 We calculate a sha1 of repo heads and the content of the obsstore and write |
|
136 it to the cache. Upon reading we can easily validate by checking the hash |
|
137 against the stored one and discard the cache in case the hashes don't match. |
|
138 """ |
|
139 h = hashlib.sha1() |
|
140 h.update(''.join(repo.heads())) |
|
141 h.update('%d' % hash(frozenset(hideable))) |
|
142 return h.digest() |
|
143 |
|
144 def _writehiddencache(cachefile, cachehash, hidden): |
|
145 """write hidden data to a cache file""" |
|
146 data = struct.pack('>%ii' % len(hidden), *sorted(hidden)) |
|
147 cachefile.write(struct.pack(">H", cacheversion)) |
|
148 cachefile.write(cachehash) |
|
149 cachefile.write(data) |
|
150 |
|
151 def trywritehiddencache(repo, hideable, hidden): |
|
152 """write cache of hidden changesets to disk |
|
153 |
|
154 Will not write the cache if a wlock cannot be obtained lazily. |
|
155 The cache consists of a head of 22byte: |
|
156 2 byte version number of the cache |
|
157 20 byte sha1 to validate the cache |
|
158 n*4 byte hidden revs |
|
159 """ |
|
160 wlock = fh = None |
|
161 try: |
|
162 wlock = repo.wlock(wait=False) |
|
163 # write cache to file |
|
164 newhash = cachehash(repo, hideable) |
|
165 fh = repo.vfs.open(cachefile, 'w+b', atomictemp=True) |
|
166 _writehiddencache(fh, newhash, hidden) |
|
167 fh.close() |
|
168 except (IOError, OSError): |
|
169 repo.ui.debug('error writing hidden changesets cache\n') |
|
170 except error.LockHeld: |
|
171 repo.ui.debug('cannot obtain lock to write hidden changesets cache\n') |
|
172 finally: |
|
173 if wlock: |
|
174 wlock.release() |
|
175 |
|
176 def _readhiddencache(repo, cachefilename, newhash): |
|
177 hidden = fh = None |
|
178 try: |
|
179 if repo.vfs.exists(cachefile): |
|
180 fh = repo.vfs.open(cachefile, 'rb') |
|
181 version, = struct.unpack(">H", fh.read(2)) |
|
182 oldhash = fh.read(20) |
|
183 if (cacheversion, oldhash) == (version, newhash): |
|
184 # cache is valid, so we can start reading the hidden revs |
|
185 data = fh.read() |
|
186 count = len(data) / 4 |
|
187 hidden = frozenset(struct.unpack('>%ii' % count, data)) |
|
188 return hidden |
|
189 except struct.error: |
|
190 repo.ui.debug('corrupted hidden cache\n') |
|
191 # No need to fix the content as it will get rewritten |
|
192 return None |
|
193 except (IOError, OSError): |
|
194 repo.ui.debug('cannot read hidden cache\n') |
|
195 return None |
|
196 finally: |
|
197 if fh: |
|
198 fh.close() |
|
199 |
|
200 def tryreadcache(repo, hideable): |
|
201 """read a cache if the cache exists and is valid, otherwise returns None.""" |
|
202 newhash = cachehash(repo, hideable) |
|
203 return _readhiddencache(repo, cachefile, newhash) |
|
204 |
|
205 def computehidden(repo): |
126 def computehidden(repo): |
206 """compute the set of hidden revision to filter |
127 """compute the set of hidden revision to filter |
207 |
128 |
208 During most operation hidden should be filtered.""" |
129 During most operation hidden should be filtered.""" |
209 assert not repo.changelog.filteredrevs |
130 assert not repo.changelog.filteredrevs |
210 |
131 |
211 hidden = frozenset() |
132 hidden = frozenset() |
212 hideable = hideablerevs(repo) |
133 hideable = hideablerevs(repo) |
213 if hideable: |
134 if hideable: |
214 cl = repo.changelog |
135 cl = repo.changelog |
215 hidden = tryreadcache(repo, hideable) |
136 hidden = frozenset(_getstatichidden(repo)) |
216 if hidden is None: |
|
217 hidden = frozenset(_getstatichidden(repo)) |
|
218 trywritehiddencache(repo, hideable, hidden) |
|
219 |
137 |
220 # check if we have wd parents, bookmarks or tags pointing to hidden |
138 # check if we have wd parents, bookmarks or tags pointing to hidden |
221 # changesets and remove those. |
139 # changesets and remove those. |
222 dynamic = hidden & revealedrevs(repo) |
140 dynamic = hidden & revealedrevs(repo) |
223 if dynamic: |
141 if dynamic: |