Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/utils/storageutil.py @ 49611:f463eb675e85 stable
emitrevision: consider ancestors revision to emit as available base
This should make more delta base valid. This notably affects:
* case where we skipped some parent with empty delta to directly delta against
an ancestors
* case where an intermediate snapshots is stored.
This change means we could sent largish intermediate snapshots over the wire.
However this is actually a sub goal here. Sending snapshots over the wire means
the client have a high odd of simply storing the pre-computed delta instead of
doing a lengthy process that will? end up doing the same intermediate snapshot.
In addition the overall size of snapshot (or any level) is "only" some or the
overall delta size. (0.17% for my mercurial clone, 20% for my clone of Mozilla
try). So Sending them other the wire is unlikely to change large impact on the
bandwidth used.
If we decide that minimising the bandwidth is an explicit goal, we should
introduce new logic to filter-out snapshot as delta. The current code has no
notion explicite of snapshot so far, they just tended to fall into the wobbly
filtering options.
In some cases, this patch can yield large improvement to the bundling time:
### data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
# benchmark.name = perf-bundle
# benchmark.variants.revs = last-100000
before: 68.787066 seconds
after: 47.552677 seconds (-30.87%)
That translate to large improvement to the pull time :
### data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
# benchmark.name = pull
# benchmark.variants.issue6528 = disabled
# benchmark.variants.revs = last-100000
before: 142.186625 seconds
after: 75.897745 seconds (-46.62%)
No significant negative impact have been observed.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Sat, 12 Nov 2022 00:18:41 +0100 |
parents | 31b4675ca998 |
children | e0c0545e2e55 |
comparison
equal
deleted
inserted
replaced
49610:df750b81272f | 49611:f463eb675e85 |
---|---|
372 See `revlogutil.sidedata.get_sidedata_helpers`. | 372 See `revlogutil.sidedata.get_sidedata_helpers`. |
373 """ | 373 """ |
374 | 374 |
375 fnode = store.node | 375 fnode = store.node |
376 frev = store.rev | 376 frev = store.rev |
377 parents = store.parentrevs | |
377 | 378 |
378 if nodesorder == b'nodes': | 379 if nodesorder == b'nodes': |
379 revs = [frev(n) for n in nodes] | 380 revs = [frev(n) for n in nodes] |
380 elif nodesorder == b'linear': | 381 elif nodesorder == b'linear': |
381 revs = {frev(n) for n in nodes} | 382 revs = {frev(n) for n in nodes} |
384 revs = sorted(frev(n) for n in nodes) | 385 revs = sorted(frev(n) for n in nodes) |
385 | 386 |
386 prevrev = None | 387 prevrev = None |
387 | 388 |
388 if deltamode == repository.CG_DELTAMODE_PREV or assumehaveparentrevisions: | 389 if deltamode == repository.CG_DELTAMODE_PREV or assumehaveparentrevisions: |
389 prevrev = store.parentrevs(revs[0])[0] | 390 prevrev = parents(revs[0])[0] |
390 | 391 |
391 # Set of revs available to delta against. | 392 # Sets of revs available to delta against. |
393 emitted = set() | |
392 available = set() | 394 available = set() |
393 parents = [] | 395 if assumehaveparentrevisions: |
396 common_heads = set(p for r in revs for p in parents(r)) | |
397 common_heads.difference_update(revs) | |
398 available = store.ancestors(common_heads, inclusive=True) | |
394 | 399 |
395 def is_usable_base(rev): | 400 def is_usable_base(rev): |
396 """Is a delta against this revision usable over the wire""" | 401 """Is a delta against this revision usable over the wire""" |
397 if rev == nullrev: | 402 if rev == nullrev: |
398 return False | 403 return False |
399 # Base revision was already emitted in this group. | 404 return rev in emitted or rev in available |
400 if rev in available: | |
401 return True | |
402 # Base revision is a parent that hasn't been emitted already. | |
403 if assumehaveparentrevisions and rev in parents: | |
404 return True | |
405 return False | |
406 | 405 |
407 for rev in revs: | 406 for rev in revs: |
408 if rev == nullrev: | 407 if rev == nullrev: |
409 continue | 408 continue |
410 | 409 |
411 node = fnode(rev) | 410 node = fnode(rev) |
412 parents[:] = p1rev, p2rev = store.parentrevs(rev) | 411 p1rev, p2rev = parents(rev) |
413 | 412 |
414 if deltaparentfn: | 413 if deltaparentfn: |
415 deltaparentrev = deltaparentfn(rev) | 414 deltaparentrev = deltaparentfn(rev) |
416 else: | 415 else: |
417 deltaparentrev = nullrev | 416 deltaparentrev = nullrev |
479 | 478 |
480 elif ( | 479 elif ( |
481 baserev == nullrev and deltamode != repository.CG_DELTAMODE_PREV | 480 baserev == nullrev and deltamode != repository.CG_DELTAMODE_PREV |
482 ): | 481 ): |
483 revision = store.rawdata(node) | 482 revision = store.rawdata(node) |
484 available.add(rev) | 483 emitted.add(rev) |
485 else: | 484 else: |
486 if revdifffn: | 485 if revdifffn: |
487 delta = revdifffn(baserev, rev) | 486 delta = revdifffn(baserev, rev) |
488 else: | 487 else: |
489 delta = mdiff.textdiff( | 488 delta = mdiff.textdiff( |
490 store.rawdata(baserev), store.rawdata(rev) | 489 store.rawdata(baserev), store.rawdata(rev) |
491 ) | 490 ) |
492 | 491 |
493 available.add(rev) | 492 emitted.add(rev) |
494 | 493 |
495 serialized_sidedata = None | 494 serialized_sidedata = None |
496 sidedata_flags = (0, 0) | 495 sidedata_flags = (0, 0) |
497 if sidedata_helpers: | 496 if sidedata_helpers: |
498 try: | 497 try: |