comparison mercurial/repoview.py @ 32478:1cc7c96cad75

hidden: drop the hidden cache logic The improvement in time complexitty and the speed-up in computation is large enough that the has little use now. Its update time can even gets in the way. So we drop it. This will allow us to unify the static/dynamic blockers logic in the next changeset.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sun, 21 May 2017 15:53:08 +0200
parents 20c1c2fb8106
children 4c5bc7cbd989
comparison
equal deleted inserted replaced
32477:20c1c2fb8106 32478:1cc7c96cad75
7 # GNU General Public License version 2 or any later version. 7 # GNU General Public License version 2 or any later version.
8 8
9 from __future__ import absolute_import 9 from __future__ import absolute_import
10 10
11 import copy 11 import copy
12 import hashlib
13 import struct
14 12
15 from .node import nullrev 13 from .node import nullrev
16 from . import ( 14 from . import (
17 error,
18 obsolete, 15 obsolete,
19 phases, 16 phases,
20 tags as tagsmod, 17 tags as tagsmod,
21 ) 18 )
22 19
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: