Show More
@@ -9,12 +9,9 b'' | |||
|
9 | 9 | from __future__ import absolute_import |
|
10 | 10 | |
|
11 | 11 | import copy |
|
12 | import hashlib | |
|
13 | import struct | |
|
14 | 12 | |
|
15 | 13 | from .node import nullrev |
|
16 | 14 | from . import ( |
|
17 | error, | |
|
18 | 15 | obsolete, |
|
19 | 16 | phases, |
|
20 | 17 | tags as tagsmod, |
@@ -126,82 +123,6 b' def _domainancestors(pfunc, revs, domain' | |||
|
126 | 123 | stack.append(p) |
|
127 | 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 | 126 | def computehidden(repo): |
|
206 | 127 | """compute the set of hidden revision to filter |
|
207 | 128 | |
@@ -212,10 +133,7 b' def computehidden(repo):' | |||
|
212 | 133 | hideable = hideablerevs(repo) |
|
213 | 134 | if hideable: |
|
214 | 135 | cl = repo.changelog |
|
215 |
hidden = |
|
|
216 | if hidden is None: | |
|
217 | hidden = frozenset(_getstatichidden(repo)) | |
|
218 | trywritehiddencache(repo, hideable, hidden) | |
|
136 | hidden = frozenset(_getstatichidden(repo)) | |
|
219 | 137 | |
|
220 | 138 | # check if we have wd parents, bookmarks or tags pointing to hidden |
|
221 | 139 | # changesets and remove those. |
@@ -70,10 +70,6 b' Beat up tags caches:' | |||
|
70 | 70 | $ damage tags tags2-visible |
|
71 | 71 | $ damage "tag -f t3" hgtagsfnodes1 |
|
72 | 72 | |
|
73 | Beat up hidden cache: | |
|
74 | ||
|
75 | $ damage log hidden | |
|
76 | ||
|
77 | 73 | Beat up branch caches: |
|
78 | 74 | |
|
79 | 75 | $ damage branches branch2-base "rm .hg/cache/branch2-[vs]*" |
@@ -1093,25 +1093,6 b' Test heads computation on pending index ' | |||
|
1093 | 1093 | $ hg amendtransient |
|
1094 | 1094 | [1, 3] |
|
1095 | 1095 | |
|
1096 | Check that corrupted hidden cache does not crash | |
|
1097 | ||
|
1098 | $ printf "" > .hg/cache/hidden | |
|
1099 | $ hg log -r . -T '{node}' --debug | |
|
1100 | corrupted hidden cache | |
|
1101 | 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol) | |
|
1102 | $ hg log -r . -T '{node}' --debug | |
|
1103 | 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol) | |
|
1104 | ||
|
1105 | #if unix-permissions | |
|
1106 | Check that wrong hidden cache permission does not crash | |
|
1107 | ||
|
1108 | $ chmod 000 .hg/cache/hidden | |
|
1109 | $ hg log -r . -T '{node}' --debug | |
|
1110 | cannot read hidden cache | |
|
1111 | error writing hidden changesets cache | |
|
1112 | 8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol) | |
|
1113 | #endif | |
|
1114 | ||
|
1115 | 1096 | Test cache consistency for the visible filter |
|
1116 | 1097 | 1) We want to make sure that the cached filtered revs are invalidated when |
|
1117 | 1098 | bookmarks change |
General Comments 0
You need to be logged in to leave comments.
Login now