##// END OF EJS Templates
storageutil: extract most of emitrevisions() to standalone function...
Gregory Szorc -
r40044:842ffcf1 default
parent child Browse files
Show More
@@ -2193,7 +2193,6 b' class revlog(object):'
2193 2193 nodesorder = 'storage'
2194 2194
2195 2195 frev = self.rev
2196 fnode = self.node
2197 2196
2198 2197 if nodesorder == 'nodes':
2199 2198 revs = [frev(n) for n in nodes]
@@ -2204,100 +2203,17 b' class revlog(object):'
2204 2203 revs = set(frev(n) for n in nodes)
2205 2204 revs = dagop.linearize(revs, self.parentrevs)
2206 2205
2207 prevrev = None
2208
2209 if deltaprevious or assumehaveparentrevisions:
2210 prevrev = self.parentrevs(revs[0])[0]
2211
2212 # Set of revs available to delta against.
2213 available = set()
2214
2215 for rev in revs:
2216 if rev == nullrev:
2217 continue
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
2206 return storageutil.emitrevisions(
2207 self, revs, revlogrevisiondelta,
2208 deltaparentfn=self.deltaparent,
2209 candeltafn=self.candelta,
2210 rawsizefn=self.rawsize,
2211 revdifffn=self.revdiff,
2212 flagsfn=self.flags,
2213 sendfulltext=not self._storedeltachains,
2214 revisiondata=revisiondata,
2215 assumehaveparentrevisions=assumehaveparentrevisions,
2216 deltaprevious=deltaprevious)
2301 2217
2302 2218 DELTAREUSEALWAYS = 'always'
2303 2219 DELTAREUSESAMEREVS = 'samerevs'
@@ -262,3 +262,149 b' def resolvestripinfo(minlinkrev, tiprev,'
262 262 futurelargelinkrevs.add(plinkrev)
263 263
264 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