comparison mercurial/revlog.py @ 43133:3de4d13f22be

revlog: add a way to control sidedata changes during revlog.clone We introduce a new argument to pass a callable dealing with the side data logic. Since the side data are usually associated to higher level logic, the revlog code itself is unlikely to know that to do itself. As a result the higher level upgrade code will be responsible to decide what needs to changes. The lower level revlog.clone just get simple instructions to apply. Differential Revision: https://phab.mercurial-scm.org/D6941
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sun, 06 Oct 2019 23:36:51 -0400
parents 8ff1ecfadcd1
children ec7ba79bf3db
comparison
equal deleted inserted replaced
43132:8f807a83d53b 43133:3de4d13f22be
2540 tr, 2540 tr,
2541 destrevlog, 2541 destrevlog,
2542 addrevisioncb=None, 2542 addrevisioncb=None,
2543 deltareuse=DELTAREUSESAMEREVS, 2543 deltareuse=DELTAREUSESAMEREVS,
2544 forcedeltabothparents=None, 2544 forcedeltabothparents=None,
2545 sidedatacompanion=None,
2545 ): 2546 ):
2546 """Copy this revlog to another, possibly with format changes. 2547 """Copy this revlog to another, possibly with format changes.
2547 2548
2548 The destination revlog will contain the same revisions and nodes. 2549 The destination revlog will contain the same revisions and nodes.
2549 However, it may not be bit-for-bit identical due to e.g. delta encoding 2550 However, it may not be bit-for-bit identical due to e.g. delta encoding
2581 revision. 2582 revision.
2582 2583
2583 In addition to the delta policy, the ``forcedeltabothparents`` 2584 In addition to the delta policy, the ``forcedeltabothparents``
2584 argument controls whether to force compute deltas against both parents 2585 argument controls whether to force compute deltas against both parents
2585 for merges. By default, the current default is used. 2586 for merges. By default, the current default is used.
2587
2588 If not None, the `sidedatacompanion` is callable that accept two
2589 arguments:
2590
2591 (srcrevlog, rev)
2592
2593 and return a triplet that control changes to sidedata content from the
2594 old revision to the new clone result:
2595
2596 (dropall, filterout, update)
2597
2598 * if `dropall` is True, all sidedata should be dropped
2599 * `filterout` is a set of sidedata keys that should be dropped
2600 * `update` is a mapping of additionnal/new key -> value
2586 """ 2601 """
2587 if deltareuse not in self.DELTAREUSEALL: 2602 if deltareuse not in self.DELTAREUSEALL:
2588 raise ValueError( 2603 raise ValueError(
2589 _(b'value for deltareuse invalid: %s') % deltareuse 2604 _(b'value for deltareuse invalid: %s') % deltareuse
2590 ) 2605 )
2615 destrevlog._lazydelta = False 2630 destrevlog._lazydelta = False
2616 2631
2617 destrevlog._deltabothparents = forcedeltabothparents or oldamd 2632 destrevlog._deltabothparents = forcedeltabothparents or oldamd
2618 2633
2619 self._clone( 2634 self._clone(
2620 tr, destrevlog, addrevisioncb, deltareuse, forcedeltabothparents 2635 tr,
2636 destrevlog,
2637 addrevisioncb,
2638 deltareuse,
2639 forcedeltabothparents,
2640 sidedatacompanion,
2621 ) 2641 )
2622 2642
2623 finally: 2643 finally:
2624 destrevlog._lazydelta = oldlazydelta 2644 destrevlog._lazydelta = oldlazydelta
2625 destrevlog._lazydeltabase = oldlazydeltabase 2645 destrevlog._lazydeltabase = oldlazydeltabase
2626 destrevlog._deltabothparents = oldamd 2646 destrevlog._deltabothparents = oldamd
2627 2647
2628 def _clone( 2648 def _clone(
2629 self, tr, destrevlog, addrevisioncb, deltareuse, forcedeltabothparents 2649 self,
2650 tr,
2651 destrevlog,
2652 addrevisioncb,
2653 deltareuse,
2654 forcedeltabothparents,
2655 sidedatacompanion,
2630 ): 2656 ):
2631 """perform the core duty of `revlog.clone` after parameter processing""" 2657 """perform the core duty of `revlog.clone` after parameter processing"""
2632 deltacomputer = deltautil.deltacomputer(destrevlog) 2658 deltacomputer = deltautil.deltacomputer(destrevlog)
2633 index = self.index 2659 index = self.index
2634 for rev in self: 2660 for rev in self:
2640 linkrev = entry[4] 2666 linkrev = entry[4]
2641 p1 = index[entry[5]][7] 2667 p1 = index[entry[5]][7]
2642 p2 = index[entry[6]][7] 2668 p2 = index[entry[6]][7]
2643 node = entry[7] 2669 node = entry[7]
2644 2670
2671 sidedataactions = (False, [], {})
2672 if sidedatacompanion is not None:
2673 sidedataactions = sidedatacompanion(self, rev)
2674
2645 # (Possibly) reuse the delta from the revlog if allowed and 2675 # (Possibly) reuse the delta from the revlog if allowed and
2646 # the revlog chunk is a delta. 2676 # the revlog chunk is a delta.
2647 cachedelta = None 2677 cachedelta = None
2648 rawtext = None 2678 rawtext = None
2649 if deltareuse == self.DELTAREUSEFULLADD: 2679 if any(sidedataactions) or deltareuse == self.DELTAREUSEFULLADD:
2650 text = self.revision(rev) 2680 dropall, filterout, update = sidedataactions
2681 text, sidedata = self._revisiondata(rev)
2682 if dropall:
2683 sidedata = {}
2684 for key in filterout:
2685 sidedata.pop(key, None)
2686 sidedata.update(update)
2687 if not sidedata:
2688 sidedata = None
2651 destrevlog.addrevision( 2689 destrevlog.addrevision(
2652 text, 2690 text,
2653 tr, 2691 tr,
2654 linkrev, 2692 linkrev,
2655 p1, 2693 p1,
2656 p2, 2694 p2,
2657 cachedelta=cachedelta, 2695 cachedelta=cachedelta,
2658 node=node, 2696 node=node,
2659 flags=flags, 2697 flags=flags,
2660 deltacomputer=deltacomputer, 2698 deltacomputer=deltacomputer,
2699 sidedata=sidedata,
2661 ) 2700 )
2662 else: 2701 else:
2663 if destrevlog._lazydelta: 2702 if destrevlog._lazydelta:
2664 dp = self.deltaparent(rev) 2703 dp = self.deltaparent(rev)
2665 if dp != nullrev: 2704 if dp != nullrev: