comparison mercurial/interfaces/repository.py @ 52488:8c89e978375c

interfaces: convert `repository.ifilestorage` to a Protocol class Same as cdd4bc69bfc1 for `imanifestrevisionstored`, but also make the methods in the super classes abstract as well.
author Matt Harbison <matt_harbison@yahoo.com>
date Wed, 11 Dec 2024 00:33:49 -0500
parents 3daaa5195a30
children ef119f914fc1
comparison
equal deleted inserted replaced
52487:3daaa5195a30 52488:8c89e978375c
608 """ 608 """
609 609
610 nullid: bytes 610 nullid: bytes
611 """node for the null revision for use as delta base.""" 611 """node for the null revision for use as delta base."""
612 612
613 @abc.abstractmethod
613 def __len__(self) -> int: 614 def __len__(self) -> int:
614 """Obtain the number of revisions stored for this file.""" 615 """Obtain the number of revisions stored for this file."""
615 616
617 @abc.abstractmethod
616 def __iter__(self) -> Iterator[int]: 618 def __iter__(self) -> Iterator[int]:
617 """Iterate over revision numbers for this file.""" 619 """Iterate over revision numbers for this file."""
618 620
621 @abc.abstractmethod
619 def hasnode(self, node): 622 def hasnode(self, node):
620 """Returns a bool indicating if a node is known to this store. 623 """Returns a bool indicating if a node is known to this store.
621 624
622 Implementations must only return True for full, binary node values: 625 Implementations must only return True for full, binary node values:
623 hex nodes, revision numbers, and partial node matches must be 626 hex nodes, revision numbers, and partial node matches must be
624 rejected. 627 rejected.
625 628
626 The null node is never present. 629 The null node is never present.
627 """ 630 """
628 631
632 @abc.abstractmethod
629 def revs(self, start=0, stop=None): 633 def revs(self, start=0, stop=None):
630 """Iterate over revision numbers for this file, with control.""" 634 """Iterate over revision numbers for this file, with control."""
631 635
636 @abc.abstractmethod
632 def parents(self, node): 637 def parents(self, node):
633 """Returns a 2-tuple of parent nodes for a revision. 638 """Returns a 2-tuple of parent nodes for a revision.
634 639
635 Values will be ``nullid`` if the parent is empty. 640 Values will be ``nullid`` if the parent is empty.
636 """ 641 """
637 642
643 @abc.abstractmethod
638 def parentrevs(self, rev): 644 def parentrevs(self, rev):
639 """Like parents() but operates on revision numbers.""" 645 """Like parents() but operates on revision numbers."""
640 646
647 @abc.abstractmethod
641 def rev(self, node): 648 def rev(self, node):
642 """Obtain the revision number given a node. 649 """Obtain the revision number given a node.
643 650
644 Raises ``error.LookupError`` if the node is not known. 651 Raises ``error.LookupError`` if the node is not known.
645 """ 652 """
646 653
654 @abc.abstractmethod
647 def node(self, rev): 655 def node(self, rev):
648 """Obtain the node value given a revision number. 656 """Obtain the node value given a revision number.
649 657
650 Raises ``IndexError`` if the node is not known. 658 Raises ``IndexError`` if the node is not known.
651 """ 659 """
652 660
661 @abc.abstractmethod
653 def lookup(self, node): 662 def lookup(self, node):
654 """Attempt to resolve a value to a node. 663 """Attempt to resolve a value to a node.
655 664
656 Value can be a binary node, hex node, revision number, or a string 665 Value can be a binary node, hex node, revision number, or a string
657 that can be converted to an integer. 666 that can be converted to an integer.
658 667
659 Raises ``error.LookupError`` if a node could not be resolved. 668 Raises ``error.LookupError`` if a node could not be resolved.
660 """ 669 """
661 670
671 @abc.abstractmethod
662 def linkrev(self, rev): 672 def linkrev(self, rev):
663 """Obtain the changeset revision number a revision is linked to.""" 673 """Obtain the changeset revision number a revision is linked to."""
664 674
675 @abc.abstractmethod
665 def iscensored(self, rev): 676 def iscensored(self, rev):
666 """Return whether a revision's content has been censored.""" 677 """Return whether a revision's content has been censored."""
667 678
679 @abc.abstractmethod
668 def commonancestorsheads(self, node1, node2): 680 def commonancestorsheads(self, node1, node2):
669 """Obtain an iterable of nodes containing heads of common ancestors. 681 """Obtain an iterable of nodes containing heads of common ancestors.
670 682
671 See ``ancestor.commonancestorsheads()``. 683 See ``ancestor.commonancestorsheads()``.
672 """ 684 """
673 685
686 @abc.abstractmethod
674 def descendants(self, revs): 687 def descendants(self, revs):
675 """Obtain descendant revision numbers for a set of revision numbers. 688 """Obtain descendant revision numbers for a set of revision numbers.
676 689
677 If ``nullrev`` is in the set, this is equivalent to ``revs()``. 690 If ``nullrev`` is in the set, this is equivalent to ``revs()``.
678 """ 691 """
679 692
693 @abc.abstractmethod
680 def heads(self, start=None, stop=None): 694 def heads(self, start=None, stop=None):
681 """Obtain a list of nodes that are DAG heads, with control. 695 """Obtain a list of nodes that are DAG heads, with control.
682 696
683 The set of revisions examined can be limited by specifying 697 The set of revisions examined can be limited by specifying
684 ``start`` and ``stop``. ``start`` is a node. ``stop`` is an 698 ``start`` and ``stop``. ``start`` is a node. ``stop`` is an
685 iterable of nodes. DAG traversal starts at earlier revision 699 iterable of nodes. DAG traversal starts at earlier revision
686 ``start`` and iterates forward until any node in ``stop`` is 700 ``start`` and iterates forward until any node in ``stop`` is
687 encountered. 701 encountered.
688 """ 702 """
689 703
704 @abc.abstractmethod
690 def children(self, node): 705 def children(self, node):
691 """Obtain nodes that are children of a node. 706 """Obtain nodes that are children of a node.
692 707
693 Returns a list of nodes. 708 Returns a list of nodes.
694 """ 709 """
699 714
700 This complements ``ifileindex`` and provides an interface for accessing 715 This complements ``ifileindex`` and provides an interface for accessing
701 data for a tracked file. 716 data for a tracked file.
702 """ 717 """
703 718
719 @abc.abstractmethod
704 def size(self, rev): 720 def size(self, rev):
705 """Obtain the fulltext size of file data. 721 """Obtain the fulltext size of file data.
706 722
707 Any metadata is excluded from size measurements. 723 Any metadata is excluded from size measurements.
708 """ 724 """
709 725
726 @abc.abstractmethod
710 def revision(self, node): 727 def revision(self, node):
711 """Obtain fulltext data for a node. 728 """Obtain fulltext data for a node.
712 729
713 By default, any storage transformations are applied before the data 730 By default, any storage transformations are applied before the data
714 is returned. If ``raw`` is True, non-raw storage transformations 731 is returned. If ``raw`` is True, non-raw storage transformations
716 733
717 The fulltext data may contain a header containing metadata. Most 734 The fulltext data may contain a header containing metadata. Most
718 consumers should use ``read()`` to obtain the actual file data. 735 consumers should use ``read()`` to obtain the actual file data.
719 """ 736 """
720 737
738 @abc.abstractmethod
721 def rawdata(self, node): 739 def rawdata(self, node):
722 """Obtain raw data for a node.""" 740 """Obtain raw data for a node."""
723 741
742 @abc.abstractmethod
724 def read(self, node): 743 def read(self, node):
725 """Resolve file fulltext data. 744 """Resolve file fulltext data.
726 745
727 This is similar to ``revision()`` except any metadata in the data 746 This is similar to ``revision()`` except any metadata in the data
728 headers is stripped. 747 headers is stripped.
729 """ 748 """
730 749
750 @abc.abstractmethod
731 def renamed(self, node): 751 def renamed(self, node):
732 """Obtain copy metadata for a node. 752 """Obtain copy metadata for a node.
733 753
734 Returns ``False`` if no copy metadata is stored or a 2-tuple of 754 Returns ``False`` if no copy metadata is stored or a 2-tuple of
735 (path, node) from which this revision was copied. 755 (path, node) from which this revision was copied.
736 """ 756 """
737 757
758 @abc.abstractmethod
738 def cmp(self, node, fulltext): 759 def cmp(self, node, fulltext):
739 """Compare fulltext to another revision. 760 """Compare fulltext to another revision.
740 761
741 Returns True if the fulltext is different from what is stored. 762 Returns True if the fulltext is different from what is stored.
742 763
743 This takes copy metadata into account. 764 This takes copy metadata into account.
744 765
745 TODO better document the copy metadata and censoring logic. 766 TODO better document the copy metadata and censoring logic.
746 """ 767 """
747 768
769 @abc.abstractmethod
748 def emitrevisions( 770 def emitrevisions(
749 self, 771 self,
750 nodes, 772 nodes,
751 nodesorder=None, 773 nodesorder=None,
752 revisiondata=False, 774 revisiondata=False,
803 825
804 826
805 class ifilemutation(Protocol): 827 class ifilemutation(Protocol):
806 """Storage interface for mutation events of a tracked file.""" 828 """Storage interface for mutation events of a tracked file."""
807 829
830 @abc.abstractmethod
808 def add(self, filedata, meta, transaction, linkrev, p1, p2): 831 def add(self, filedata, meta, transaction, linkrev, p1, p2):
809 """Add a new revision to the store. 832 """Add a new revision to the store.
810 833
811 Takes file data, dictionary of metadata, a transaction, linkrev, 834 Takes file data, dictionary of metadata, a transaction, linkrev,
812 and parent nodes. 835 and parent nodes.
814 Returns the node that was added. 837 Returns the node that was added.
815 838
816 May no-op if a revision matching the supplied data is already stored. 839 May no-op if a revision matching the supplied data is already stored.
817 """ 840 """
818 841
842 @abc.abstractmethod
819 def addrevision( 843 def addrevision(
820 self, 844 self,
821 revisiondata, 845 revisiondata,
822 transaction, 846 transaction,
823 linkrev, 847 linkrev,
841 directory. ``addrevision()`` is often called by ``add()`` and for 865 directory. ``addrevision()`` is often called by ``add()`` and for
842 scenarios where revision data has already been computed, such as when 866 scenarios where revision data has already been computed, such as when
843 applying raw data from a peer repo. 867 applying raw data from a peer repo.
844 """ 868 """
845 869
870 @abc.abstractmethod
846 def addgroup( 871 def addgroup(
847 self, 872 self,
848 deltas, 873 deltas,
849 linkmapper, 874 linkmapper,
850 transaction, 875 transaction,
879 904
880 Returns a list of nodes that were processed. A node will be in the list 905 Returns a list of nodes that were processed. A node will be in the list
881 even if it existed in the store previously. 906 even if it existed in the store previously.
882 """ 907 """
883 908
909 @abc.abstractmethod
884 def censorrevision(self, tr, node, tombstone=b''): 910 def censorrevision(self, tr, node, tombstone=b''):
885 """Remove the content of a single revision. 911 """Remove the content of a single revision.
886 912
887 The specified ``node`` will have its content purged from storage. 913 The specified ``node`` will have its content purged from storage.
888 Future attempts to access the revision data for this node will 914 Future attempts to access the revision data for this node will
896 in this revision. As part of censoring a revision, these storage 922 in this revision. As part of censoring a revision, these storage
897 backends are expected to rewrite any internally stored deltas such 923 backends are expected to rewrite any internally stored deltas such
898 that they no longer reference the deleted content. 924 that they no longer reference the deleted content.
899 """ 925 """
900 926
927 @abc.abstractmethod
901 def getstrippoint(self, minlink): 928 def getstrippoint(self, minlink):
902 """Find the minimum revision that must be stripped to strip a linkrev. 929 """Find the minimum revision that must be stripped to strip a linkrev.
903 930
904 Returns a 2-tuple containing the minimum revision number and a set 931 Returns a 2-tuple containing the minimum revision number and a set
905 of all revisions numbers that would be broken by this strip. 932 of all revisions numbers that would be broken by this strip.
906 933
907 TODO this is highly revlog centric and should be abstracted into 934 TODO this is highly revlog centric and should be abstracted into
908 a higher-level deletion API. ``repair.strip()`` relies on this. 935 a higher-level deletion API. ``repair.strip()`` relies on this.
909 """ 936 """
910 937
938 @abc.abstractmethod
911 def strip(self, minlink, transaction): 939 def strip(self, minlink, transaction):
912 """Remove storage of items starting at a linkrev. 940 """Remove storage of items starting at a linkrev.
913 941
914 This uses ``getstrippoint()`` to determine the first node to remove. 942 This uses ``getstrippoint()`` to determine the first node to remove.
915 Then it effectively truncates storage for all revisions after that. 943 Then it effectively truncates storage for all revisions after that.
917 TODO this is highly revlog centric and should be abstracted into a 945 TODO this is highly revlog centric and should be abstracted into a
918 higher-level deletion API. 946 higher-level deletion API.
919 """ 947 """
920 948
921 949
922 class ifilestorage(ifileindex, ifiledata, ifilemutation): 950 class ifilestorage(ifileindex, ifiledata, ifilemutation, Protocol):
923 """Complete storage interface for a single tracked file.""" 951 """Complete storage interface for a single tracked file."""
924 952
953 @abc.abstractmethod
925 def files(self): 954 def files(self):
926 """Obtain paths that are backing storage for this file. 955 """Obtain paths that are backing storage for this file.
927 956
928 TODO this is used heavily by verify code and there should probably 957 TODO this is used heavily by verify code and there should probably
929 be a better API for that. 958 be a better API for that.
930 """ 959 """
931 960
961 @abc.abstractmethod
932 def storageinfo( 962 def storageinfo(
933 self, 963 self,
934 exclusivefiles=False, 964 exclusivefiles=False,
935 sharedfiles=False, 965 sharedfiles=False,
936 revisionscount=False, 966 revisionscount=False,
967 Not all storage backends may support all queries are have a reasonable 997 Not all storage backends may support all queries are have a reasonable
968 value to use. In that case, the value should be set to ``None`` and 998 value to use. In that case, the value should be set to ``None`` and
969 callers are expected to handle this special value. 999 callers are expected to handle this special value.
970 """ 1000 """
971 1001
1002 @abc.abstractmethod
972 def verifyintegrity(self, state) -> Iterable[iverifyproblem]: 1003 def verifyintegrity(self, state) -> Iterable[iverifyproblem]:
973 """Verifies the integrity of file storage. 1004 """Verifies the integrity of file storage.
974 1005
975 ``state`` is a dict holding state of the verifier process. It can be 1006 ``state`` is a dict holding state of the verifier process. It can be
976 used to communicate data between invocations of multiple storage 1007 used to communicate data between invocations of multiple storage