596 return True |
596 return True |
597 return False |
597 return False |
598 |
598 |
599 |
599 |
600 def _is_revision_affected_fast(repo, fl, filerev, metadata_cache): |
600 def _is_revision_affected_fast(repo, fl, filerev, metadata_cache): |
|
601 rl = fl._revlog |
|
602 is_censored = lambda: rl.iscensored(filerev) |
|
603 delta_base = lambda: rl.deltaparent(filerev) |
|
604 delta = lambda: rl._chunk(filerev) |
|
605 full_text = lambda: rl.rawdata(filerev) |
|
606 parent_revs = lambda: rl.parentrevs(filerev) |
|
607 return _is_revision_affected_fast_inner( |
|
608 is_censored, |
|
609 delta_base, |
|
610 delta, |
|
611 full_text, |
|
612 parent_revs, |
|
613 filerev, |
|
614 metadata_cache, |
|
615 ) |
|
616 |
|
617 |
|
618 def _is_revision_affected_fast_inner( |
|
619 is_censored, |
|
620 delta_base, |
|
621 delta, |
|
622 full_text, |
|
623 parent_revs, |
|
624 filerev, |
|
625 metadata_cache, |
|
626 ): |
601 """Optimization fast-path for `_is_revision_affected`. |
627 """Optimization fast-path for `_is_revision_affected`. |
602 |
628 |
603 `metadata_cache` is a dict of `{rev: has_metadata}` which allows any |
629 `metadata_cache` is a dict of `{rev: has_metadata}` which allows any |
604 revision to check if its base has metadata, saving computation of the full |
630 revision to check if its base has metadata, saving computation of the full |
605 text, instead looking at the current delta. |
631 text, instead looking at the current delta. |
606 |
632 |
607 This optimization only works if the revisions are looked at in order.""" |
633 This optimization only works if the revisions are looked at in order.""" |
608 rl = fl._revlog |
634 |
609 |
635 if is_censored(): |
610 if rl.iscensored(filerev): |
|
611 # Censored revisions don't contain metadata, so they cannot be affected |
636 # Censored revisions don't contain metadata, so they cannot be affected |
612 metadata_cache[filerev] = False |
637 metadata_cache[filerev] = False |
613 return False |
638 return False |
614 |
639 |
615 p1, p2 = rl.parentrevs(filerev) |
640 p1, p2 = parent_revs() |
616 if p1 == nullrev or p2 != nullrev: |
641 if p1 == nullrev or p2 != nullrev: |
617 return False |
642 return False |
618 |
643 |
619 delta_parent = rl.deltaparent(filerev) |
644 delta_parent = delta_base() |
620 parent_has_metadata = metadata_cache.get(delta_parent) |
645 parent_has_metadata = metadata_cache.get(delta_parent) |
621 if parent_has_metadata is None: |
646 if parent_has_metadata is None: |
622 is_affected = _is_revision_affected(fl, filerev, metadata_cache) |
647 return _is_revision_affected_inner( |
623 return is_affected |
648 full_text, |
624 |
649 parent_revs, |
625 chunk = rl._chunk(filerev) |
650 filerev, |
|
651 metadata_cache, |
|
652 ) |
|
653 |
|
654 chunk = delta() |
626 if not len(chunk): |
655 if not len(chunk): |
627 # No diff for this revision |
656 # No diff for this revision |
628 return parent_has_metadata |
657 return parent_has_metadata |
629 |
658 |
630 header_length = 12 |
659 header_length = 12 |
634 start, _end, _length = struct.unpack(b">lll", chunk[:header_length]) |
663 start, _end, _length = struct.unpack(b">lll", chunk[:header_length]) |
635 |
664 |
636 if start < 2: # len(b'\x01\n') == 2 |
665 if start < 2: # len(b'\x01\n') == 2 |
637 # This delta does *something* to the metadata marker (if any). |
666 # This delta does *something* to the metadata marker (if any). |
638 # Check it the slow way |
667 # Check it the slow way |
639 is_affected = _is_revision_affected(fl, filerev, metadata_cache) |
668 is_affected = _is_revision_affected_inner( |
|
669 full_text, |
|
670 parent_revs, |
|
671 filerev, |
|
672 metadata_cache, |
|
673 ) |
640 return is_affected |
674 return is_affected |
641 |
675 |
642 # The diff did not remove or add the metadata header, it's then in the same |
676 # The diff did not remove or add the metadata header, it's then in the same |
643 # situation as its parent |
677 # situation as its parent |
644 metadata_cache[filerev] = parent_has_metadata |
678 metadata_cache[filerev] = parent_has_metadata |