Show More
@@ -2193,7 +2193,6 b' class revlog(object):' | |||||
2193 | nodesorder = 'storage' |
|
2193 | nodesorder = 'storage' | |
2194 |
|
2194 | |||
2195 | frev = self.rev |
|
2195 | frev = self.rev | |
2196 | fnode = self.node |
|
|||
2197 |
|
2196 | |||
2198 | if nodesorder == 'nodes': |
|
2197 | if nodesorder == 'nodes': | |
2199 | revs = [frev(n) for n in nodes] |
|
2198 | revs = [frev(n) for n in nodes] | |
@@ -2204,100 +2203,17 b' class revlog(object):' | |||||
2204 | revs = set(frev(n) for n in nodes) |
|
2203 | revs = set(frev(n) for n in nodes) | |
2205 | revs = dagop.linearize(revs, self.parentrevs) |
|
2204 | revs = dagop.linearize(revs, self.parentrevs) | |
2206 |
|
2205 | |||
2207 | prevrev = None |
|
2206 | return storageutil.emitrevisions( | |
2208 |
|
2207 | self, revs, revlogrevisiondelta, | ||
2209 | if deltaprevious or assumehaveparentrevisions: |
|
2208 | deltaparentfn=self.deltaparent, | |
2210 | prevrev = self.parentrevs(revs[0])[0] |
|
2209 | candeltafn=self.candelta, | |
2211 |
|
2210 | rawsizefn=self.rawsize, | ||
2212 | # Set of revs available to delta against. |
|
2211 | revdifffn=self.revdiff, | |
2213 | available = set() |
|
2212 | flagsfn=self.flags, | |
2214 |
|
2213 | sendfulltext=not self._storedeltachains, | ||
2215 | for rev in revs: |
|
2214 | revisiondata=revisiondata, | |
2216 | if rev == nullrev: |
|
2215 | assumehaveparentrevisions=assumehaveparentrevisions, | |
2217 | continue |
|
2216 | deltaprevious=deltaprevious) | |
2218 |
|
||||
2219 | node = fnode(rev) |
|
|||
2220 | deltaparentrev = self.deltaparent(rev) |
|
|||
2221 | p1rev, p2rev = self.parentrevs(rev) |
|
|||
2222 |
|
||||
2223 | # Forced delta against previous mode. |
|
|||
2224 | if deltaprevious: |
|
|||
2225 | baserev = prevrev |
|
|||
2226 |
|
||||
2227 | # Revlog is configured to use full snapshots. Stick to that. |
|
|||
2228 | elif not self._storedeltachains: |
|
|||
2229 | baserev = nullrev |
|
|||
2230 |
|
||||
2231 | # There is a delta in storage. We try to use that because it |
|
|||
2232 | # amounts to effectively copying data from storage and is |
|
|||
2233 | # therefore the fastest. |
|
|||
2234 | elif deltaparentrev != nullrev: |
|
|||
2235 | # Base revision was already emitted in this group. We can |
|
|||
2236 | # always safely use the delta. |
|
|||
2237 | if deltaparentrev in available: |
|
|||
2238 | baserev = deltaparentrev |
|
|||
2239 |
|
||||
2240 | # Base revision is a parent that hasn't been emitted already. |
|
|||
2241 | # Use it if we can assume the receiver has the parent revision. |
|
|||
2242 | elif (assumehaveparentrevisions |
|
|||
2243 | and deltaparentrev in (p1rev, p2rev)): |
|
|||
2244 | baserev = deltaparentrev |
|
|||
2245 |
|
||||
2246 | # No guarantee the receiver has the delta parent. Send delta |
|
|||
2247 | # against last revision (if possible), which in the common case |
|
|||
2248 | # should be similar enough to this revision that the delta is |
|
|||
2249 | # reasonable. |
|
|||
2250 | elif prevrev is not None: |
|
|||
2251 | baserev = prevrev |
|
|||
2252 | else: |
|
|||
2253 | baserev = nullrev |
|
|||
2254 |
|
||||
2255 | # Storage has a fulltext revision. |
|
|||
2256 |
|
||||
2257 | # Let's use the previous revision, which is as good a guess as any. |
|
|||
2258 | # There is definitely room to improve this logic. |
|
|||
2259 | elif prevrev is not None: |
|
|||
2260 | baserev = prevrev |
|
|||
2261 | else: |
|
|||
2262 | baserev = nullrev |
|
|||
2263 |
|
||||
2264 | # But we can't actually use our chosen delta base for whatever |
|
|||
2265 | # reason. Reset to fulltext. |
|
|||
2266 | if baserev != nullrev and not self.candelta(baserev, rev): |
|
|||
2267 | baserev = nullrev |
|
|||
2268 |
|
||||
2269 | revision = None |
|
|||
2270 | delta = None |
|
|||
2271 | baserevisionsize = None |
|
|||
2272 |
|
||||
2273 | if revisiondata: |
|
|||
2274 | if self.iscensored(baserev) or self.iscensored(rev): |
|
|||
2275 | try: |
|
|||
2276 | revision = self.revision(node, raw=True) |
|
|||
2277 | except error.CensoredNodeError as e: |
|
|||
2278 | revision = e.tombstone |
|
|||
2279 |
|
||||
2280 | if baserev != nullrev: |
|
|||
2281 | baserevisionsize = self.rawsize(baserev) |
|
|||
2282 |
|
||||
2283 | elif baserev == nullrev and not deltaprevious: |
|
|||
2284 | revision = self.revision(node, raw=True) |
|
|||
2285 | available.add(rev) |
|
|||
2286 | else: |
|
|||
2287 | delta = self.revdiff(baserev, rev) |
|
|||
2288 | available.add(rev) |
|
|||
2289 |
|
||||
2290 | yield revlogrevisiondelta( |
|
|||
2291 | node=node, |
|
|||
2292 | p1node=fnode(p1rev), |
|
|||
2293 | p2node=fnode(p2rev), |
|
|||
2294 | basenode=fnode(baserev), |
|
|||
2295 | flags=self.flags(rev), |
|
|||
2296 | baserevisionsize=baserevisionsize, |
|
|||
2297 | revision=revision, |
|
|||
2298 | delta=delta) |
|
|||
2299 |
|
||||
2300 | prevrev = rev |
|
|||
2301 |
|
2217 | |||
2302 | DELTAREUSEALWAYS = 'always' |
|
2218 | DELTAREUSEALWAYS = 'always' | |
2303 | DELTAREUSESAMEREVS = 'samerevs' |
|
2219 | DELTAREUSESAMEREVS = 'samerevs' |
@@ -262,3 +262,149 b' def resolvestripinfo(minlinkrev, tiprev,' | |||||
262 | futurelargelinkrevs.add(plinkrev) |
|
262 | futurelargelinkrevs.add(plinkrev) | |
263 |
|
263 | |||
264 | return strippoint, brokenrevs |
|
264 | return strippoint, brokenrevs | |
|
265 | ||||
|
266 | def emitrevisions(store, revs, resultcls, deltaparentfn, candeltafn, | |||
|
267 | rawsizefn, revdifffn, flagsfn, sendfulltext=False, | |||
|
268 | revisiondata=False, assumehaveparentrevisions=False, | |||
|
269 | deltaprevious=False): | |||
|
270 | """Generic implementation of ifiledata.emitrevisions(). | |||
|
271 | ||||
|
272 | Emitting revision data is subtly complex. This function attempts to | |||
|
273 | encapsulate all the logic for doing so in a backend-agnostic way. | |||
|
274 | ||||
|
275 | ``store`` | |||
|
276 | Object conforming to ``ifilestorage`` interface. | |||
|
277 | ||||
|
278 | ``revs`` | |||
|
279 | List of integer revision numbers whose data to emit. | |||
|
280 | ||||
|
281 | ``resultcls`` | |||
|
282 | A type implementing the ``irevisiondelta`` interface that will be | |||
|
283 | constructed and returned. | |||
|
284 | ||||
|
285 | ``deltaparentfn`` | |||
|
286 | Callable receiving a revision number and returning the revision number | |||
|
287 | of a revision that the internal delta is stored against. This delta | |||
|
288 | will be preferred over computing a new arbitrary delta. | |||
|
289 | ||||
|
290 | ``candeltafn`` | |||
|
291 | Callable receiving a pair of revision numbers that returns a bool | |||
|
292 | indicating whether a delta between them can be produced. | |||
|
293 | ||||
|
294 | ``rawsizefn`` | |||
|
295 | Callable receiving a revision number and returning the length of the | |||
|
296 | ``store.revision(rev, raw=True)``. | |||
|
297 | ||||
|
298 | ``revdifffn`` | |||
|
299 | Callable receiving a pair of revision numbers that returns a delta | |||
|
300 | between them. | |||
|
301 | ||||
|
302 | ``flagsfn`` | |||
|
303 | Callable receiving a revision number and returns the integer flags | |||
|
304 | value for it. | |||
|
305 | ||||
|
306 | ``sendfulltext`` | |||
|
307 | Whether to send fulltext revisions instead of deltas, if allowed. | |||
|
308 | ||||
|
309 | ``revisiondata`` | |||
|
310 | ``assumehaveparentrevisions`` | |||
|
311 | ``deltaprevious`` | |||
|
312 | See ``ifiledata.emitrevisions()`` interface documentation. | |||
|
313 | """ | |||
|
314 | ||||
|
315 | fnode = store.node | |||
|
316 | ||||
|
317 | prevrev = None | |||
|
318 | ||||
|
319 | if deltaprevious or assumehaveparentrevisions: | |||
|
320 | prevrev = store.parentrevs(revs[0])[0] | |||
|
321 | ||||
|
322 | # Set of revs available to delta against. | |||
|
323 | available = set() | |||
|
324 | ||||
|
325 | for rev in revs: | |||
|
326 | if rev == nullrev: | |||
|
327 | continue | |||
|
328 | ||||
|
329 | node = fnode(rev) | |||
|
330 | deltaparentrev = deltaparentfn(rev) | |||
|
331 | p1rev, p2rev = store.parentrevs(rev) | |||
|
332 | ||||
|
333 | # Forced delta against previous mode. | |||
|
334 | if deltaprevious: | |||
|
335 | baserev = prevrev | |||
|
336 | ||||
|
337 | # We're instructed to send fulltext. Honor that. | |||
|
338 | elif sendfulltext: | |||
|
339 | baserev = nullrev | |||
|
340 | ||||
|
341 | # There is a delta in storage. We try to use that because it | |||
|
342 | # amounts to effectively copying data from storage and is | |||
|
343 | # therefore the fastest. | |||
|
344 | elif deltaparentrev != nullrev: | |||
|
345 | # Base revision was already emitted in this group. We can | |||
|
346 | # always safely use the delta. | |||
|
347 | if deltaparentrev in available: | |||
|
348 | baserev = deltaparentrev | |||
|
349 | ||||
|
350 | # Base revision is a parent that hasn't been emitted already. | |||
|
351 | # Use it if we can assume the receiver has the parent revision. | |||
|
352 | elif (assumehaveparentrevisions | |||
|
353 | and deltaparentrev in (p1rev, p2rev)): | |||
|
354 | baserev = deltaparentrev | |||
|
355 | ||||
|
356 | # No guarantee the receiver has the delta parent. Send delta | |||
|
357 | # against last revision (if possible), which in the common case | |||
|
358 | # should be similar enough to this revision that the delta is | |||
|
359 | # reasonable. | |||
|
360 | elif prevrev is not None: | |||
|
361 | baserev = prevrev | |||
|
362 | else: | |||
|
363 | baserev = nullrev | |||
|
364 | ||||
|
365 | # Storage has a fulltext revision. | |||
|
366 | ||||
|
367 | # Let's use the previous revision, which is as good a guess as any. | |||
|
368 | # There is definitely room to improve this logic. | |||
|
369 | elif prevrev is not None: | |||
|
370 | baserev = prevrev | |||
|
371 | else: | |||
|
372 | baserev = nullrev | |||
|
373 | ||||
|
374 | # But we can't actually use our chosen delta base for whatever | |||
|
375 | # reason. Reset to fulltext. | |||
|
376 | if baserev != nullrev and not candeltafn(baserev, rev): | |||
|
377 | baserev = nullrev | |||
|
378 | ||||
|
379 | revision = None | |||
|
380 | delta = None | |||
|
381 | baserevisionsize = None | |||
|
382 | ||||
|
383 | if revisiondata: | |||
|
384 | if store.iscensored(baserev) or store.iscensored(rev): | |||
|
385 | try: | |||
|
386 | revision = store.revision(node, raw=True) | |||
|
387 | except error.CensoredNodeError as e: | |||
|
388 | revision = e.tombstone | |||
|
389 | ||||
|
390 | if baserev != nullrev: | |||
|
391 | baserevisionsize = rawsizefn(baserev) | |||
|
392 | ||||
|
393 | elif baserev == nullrev and not deltaprevious: | |||
|
394 | revision = store.revision(node, raw=True) | |||
|
395 | available.add(rev) | |||
|
396 | else: | |||
|
397 | delta = revdifffn(baserev, rev) | |||
|
398 | available.add(rev) | |||
|
399 | ||||
|
400 | yield resultcls( | |||
|
401 | node=node, | |||
|
402 | p1node=fnode(p1rev), | |||
|
403 | p2node=fnode(p2rev), | |||
|
404 | basenode=fnode(baserev), | |||
|
405 | flags=flagsfn(rev), | |||
|
406 | baserevisionsize=baserevisionsize, | |||
|
407 | revision=revision, | |||
|
408 | delta=delta) | |||
|
409 | ||||
|
410 | prevrev = rev |
General Comments 0
You need to be logged in to leave comments.
Login now