Show More
@@ -105,9 +105,7 b' from .utils import (' | |||
|
105 | 105 |
) |
|
106 | 106 | |
|
107 | 107 |
from .revlogutils import ( |
|
108 | constants as revlog_constants, | |
|
109 | 108 |
debug as revlog_debug, |
|
110 | deltas as deltautil, | |
|
111 | 109 |
nodemap, |
|
112 | 110 |
rewrite, |
|
113 | 111 |
sidedata, |
@@ -799,200 +797,23 b' def debugdeltachain(ui, repo, file_=None' | |||
|
799 | 797 | |
|
800 | 798 |
The sparse read can be enabled with experimental.sparse-read = True |
|
801 | 799 |
""" |
|
802 |
r = cmdutil.openrevlog( |
|
|
800 | revlog = cmdutil.openrevlog( | |
|
803 | 801 |
repo, b'debugdeltachain', file_, pycompat.byteskwargs(opts) |
|
804 | 802 |
) |
|
805 | index = r.index | |
|
806 | start = r.start | |
|
807 | length = r.length | |
|
808 | generaldelta = r.delta_config.general_delta | |
|
809 | withsparseread = r.data_config.with_sparse_read | |
|
810 | ||
|
811 | # security to avoid crash on corrupted revlogs | |
|
812 | total_revs = len(index) | |
|
813 | ||
|
814 | chain_size_cache = {} | |
|
815 | ||
|
816 | def revinfo(rev): | |
|
817 | e = index[rev] | |
|
818 | compsize = e[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] | |
|
819 | uncompsize = e[revlog_constants.ENTRY_DATA_UNCOMPRESSED_LENGTH] | |
|
820 | ||
|
821 | base = e[revlog_constants.ENTRY_DELTA_BASE] | |
|
822 | p1 = e[revlog_constants.ENTRY_PARENT_1] | |
|
823 | p2 = e[revlog_constants.ENTRY_PARENT_2] | |
|
824 | ||
|
825 | # If the parents of a revision has an empty delta, we never try to delta | |
|
826 | # against that parent, but directly against the delta base of that | |
|
827 | # parent (recursively). It avoids adding a useless entry in the chain. | |
|
828 | # | |
|
829 | # However we need to detect that as a special case for delta-type, that | |
|
830 | # is not simply "other". | |
|
831 | p1_base = p1 | |
|
832 | if p1 != nullrev and p1 < total_revs: | |
|
833 | e1 = index[p1] | |
|
834 | while e1[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0: | |
|
835 | new_base = e1[revlog_constants.ENTRY_DELTA_BASE] | |
|
836 | if ( | |
|
837 | new_base == p1_base | |
|
838 | or new_base == nullrev | |
|
839 | or new_base >= total_revs | |
|
840 | ): | |
|
841 | break | |
|
842 | p1_base = new_base | |
|
843 | e1 = index[p1_base] | |
|
844 | p2_base = p2 | |
|
845 | if p2 != nullrev and p2 < total_revs: | |
|
846 | e2 = index[p2] | |
|
847 | while e2[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0: | |
|
848 | new_base = e2[revlog_constants.ENTRY_DELTA_BASE] | |
|
849 | if ( | |
|
850 | new_base == p2_base | |
|
851 | or new_base == nullrev | |
|
852 | or new_base >= total_revs | |
|
853 | ): | |
|
854 | break | |
|
855 | p2_base = new_base | |
|
856 | e2 = index[p2_base] | |
|
857 | ||
|
858 | if generaldelta: | |
|
859 | if base == p1: | |
|
860 | deltatype = b'p1' | |
|
861 | elif base == p2: | |
|
862 | deltatype = b'p2' | |
|
863 | elif base == rev: | |
|
864 | deltatype = b'base' | |
|
865 | elif base == p1_base: | |
|
866 | deltatype = b'skip1' | |
|
867 | elif base == p2_base: | |
|
868 | deltatype = b'skip2' | |
|
869 | elif r.issnapshot(rev): | |
|
870 | deltatype = b'snap' | |
|
871 | elif base == rev - 1: | |
|
872 | deltatype = b'prev' | |
|
873 | else: | |
|
874 | deltatype = b'other' | |
|
875 | else: | |
|
876 | if base == rev: | |
|
877 | deltatype = b'base' | |
|
878 | else: | |
|
879 | deltatype = b'prev' | |
|
880 | ||
|
881 | chain = r._deltachain(rev)[0] | |
|
882 | chain_size = 0 | |
|
883 | for iter_rev in reversed(chain): | |
|
884 | cached = chain_size_cache.get(iter_rev) | |
|
885 | if cached is not None: | |
|
886 | chain_size += cached | |
|
887 | break | |
|
888 | e = index[iter_rev] | |
|
889 | chain_size += e[revlog_constants.ENTRY_DATA_COMPRESSED_LENGTH] | |
|
890 | chain_size_cache[rev] = chain_size | |
|
891 | ||
|
892 | return p1, p2, compsize, uncompsize, deltatype, chain, chain_size | |
|
893 | ||
|
894 | 803 |
fm = ui.formatter(b'debugdeltachain', pycompat.byteskwargs(opts)) |
|
895 | 804 | |
|
896 | fm.plain( | |
|
897 | b' rev p1 p2 chain# chainlen prev delta ' | |
|
898 | b'size rawsize chainsize ratio lindist extradist ' | |
|
899 | b'extraratio' | |
|
900 | ) | |
|
901 | if withsparseread: | |
|
902 | fm.plain(b' readsize largestblk rddensity srchunks') | |
|
903 | fm.plain(b'\n') | |
|
904 | ||
|
905 | chainbases = {} | |
|
906 | for rev in r: | |
|
907 | p1, p2, comp, uncomp, deltatype, chain, chainsize = revinfo(rev) | |
|
908 | chainbase = chain[0] | |
|
909 | chainid = chainbases.setdefault(chainbase, len(chainbases) + 1) | |
|
910 | basestart = start(chainbase) | |
|
911 | revstart = start(rev) | |
|
912 | lineardist = revstart + comp - basestart | |
|
913 | extradist = lineardist - chainsize | |
|
914 | try: | |
|
915 | prevrev = chain[-2] | |
|
916 | except IndexError: | |
|
917 | prevrev = -1 | |
|
918 | ||
|
919 | if uncomp != 0: | |
|
920 | chainratio = float(chainsize) / float(uncomp) | |
|
921 | else: | |
|
922 | chainratio = chainsize | |
|
923 | ||
|
924 | if chainsize != 0: | |
|
925 | extraratio = float(extradist) / float(chainsize) | |
|
926 | else: | |
|
927 | extraratio = extradist | |
|
928 | ||
|
805 | lines = revlog_debug.debug_delta_chain(revlog) | |
|
806 | # first entry is the header | |
|
807 | header = next(lines) | |
|
808 | fm.plain(header) | |
|
809 | for entry in lines: | |
|
810 | label = b' '.join(e[0] for e in entry) | |
|
811 | format = b' '.join(e[1] for e in entry) | |
|
812 | values = [e[3] for e in entry] | |
|
813 | data = dict((e[2], e[3]) for e in entry) | |
|
929 | 814 |
fm.startitem() |
|
930 | fm.write( | |
|
931 | b'rev p1 p2 chainid chainlen prevrev deltatype compsize ' | |
|
932 | b'uncompsize chainsize chainratio lindist extradist ' | |
|
933 | b'extraratio', | |
|
934 | b'%7d %7d %7d %7d %8d %8d %7s %10d %10d %10d %9.5f %9d %9d %10.5f', | |
|
935 | rev, | |
|
936 | p1, | |
|
937 | p2, | |
|
938 | chainid, | |
|
939 | len(chain), | |
|
940 | prevrev, | |
|
941 | deltatype, | |
|
942 | comp, | |
|
943 | uncomp, | |
|
944 | chainsize, | |
|
945 | chainratio, | |
|
946 | lineardist, | |
|
947 | extradist, | |
|
948 | extraratio, | |
|
949 | rev=rev, | |
|
950 | chainid=chainid, | |
|
951 | chainlen=len(chain), | |
|
952 | prevrev=prevrev, | |
|
953 | deltatype=deltatype, | |
|
954 | compsize=comp, | |
|
955 | uncompsize=uncomp, | |
|
956 | chainsize=chainsize, | |
|
957 | chainratio=chainratio, | |
|
958 | lindist=lineardist, | |
|
959 | extradist=extradist, | |
|
960 | extraratio=extraratio, | |
|
961 | ) | |
|
962 | if withsparseread: | |
|
963 | readsize = 0 | |
|
964 | largestblock = 0 | |
|
965 | srchunks = 0 | |
|
966 | ||
|
967 | for revschunk in deltautil.slicechunk(r, chain): | |
|
968 | srchunks += 1 | |
|
969 | blkend = start(revschunk[-1]) + length(revschunk[-1]) | |
|
970 | blksize = blkend - start(revschunk[0]) | |
|
971 | ||
|
972 | readsize += blksize | |
|
973 | if largestblock < blksize: | |
|
974 | largestblock = blksize | |
|
975 | ||
|
976 | if readsize: | |
|
977 | readdensity = float(chainsize) / float(readsize) | |
|
978 | else: | |
|
979 | readdensity = 1 | |
|
980 | ||
|
981 | fm.write( | |
|
982 | b'readsize largestblock readdensity srchunks', | |
|
983 | b' %10d %10d %9.5f %8d', | |
|
984 | readsize, | |
|
985 | largestblock, | |
|
986 | readdensity, | |
|
987 | srchunks, | |
|
988 | readsize=readsize, | |
|
989 | largestblock=largestblock, | |
|
990 | readdensity=readdensity, | |
|
991 | srchunks=srchunks, | |
|
992 | ) | |
|
993 | ||
|
815 | fm.write(label, format, *values, **data) | |
|
994 | 816 |
fm.plain(b'\n') |
|
995 | ||
|
996 | 817 |
fm.end() |
|
997 | 818 | |
|
998 | 819 |
@@ -710,3 +710,175 b' def debug_revlog_stats(' | |||
|
710 | 710 | fm.write(b'revlog.target', b' %s', revlog_target) |
|
711 | 711 | |
|
712 | 712 | fm.plain(b'\n') |
|
713 | ||
|
714 | ||
|
715 | def debug_delta_chain(revlog): | |
|
716 | r = revlog | |
|
717 | index = r.index | |
|
718 | start = r.start | |
|
719 | length = r.length | |
|
720 | generaldelta = r.delta_config.general_delta | |
|
721 | withsparseread = r.data_config.with_sparse_read | |
|
722 | ||
|
723 | # security to avoid crash on corrupted revlogs | |
|
724 | total_revs = len(index) | |
|
725 | ||
|
726 | chain_size_cache = {} | |
|
727 | ||
|
728 | def revinfo(rev): | |
|
729 | e = index[rev] | |
|
730 | compsize = e[constants.ENTRY_DATA_COMPRESSED_LENGTH] | |
|
731 | uncompsize = e[constants.ENTRY_DATA_UNCOMPRESSED_LENGTH] | |
|
732 | ||
|
733 | base = e[constants.ENTRY_DELTA_BASE] | |
|
734 | p1 = e[constants.ENTRY_PARENT_1] | |
|
735 | p2 = e[constants.ENTRY_PARENT_2] | |
|
736 | ||
|
737 | # If the parents of a revision has an empty delta, we never try to | |
|
738 | # delta against that parent, but directly against the delta base of | |
|
739 | # that parent (recursively). It avoids adding a useless entry in the | |
|
740 | # chain. | |
|
741 | # | |
|
742 | # However we need to detect that as a special case for delta-type, that | |
|
743 | # is not simply "other". | |
|
744 | p1_base = p1 | |
|
745 | if p1 != nodemod.nullrev and p1 < total_revs: | |
|
746 | e1 = index[p1] | |
|
747 | while e1[constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0: | |
|
748 | new_base = e1[constants.ENTRY_DELTA_BASE] | |
|
749 | if ( | |
|
750 | new_base == p1_base | |
|
751 | or new_base == nodemod.nullrev | |
|
752 | or new_base >= total_revs | |
|
753 | ): | |
|
754 | break | |
|
755 | p1_base = new_base | |
|
756 | e1 = index[p1_base] | |
|
757 | p2_base = p2 | |
|
758 | if p2 != nodemod.nullrev and p2 < total_revs: | |
|
759 | e2 = index[p2] | |
|
760 | while e2[constants.ENTRY_DATA_COMPRESSED_LENGTH] == 0: | |
|
761 | new_base = e2[constants.ENTRY_DELTA_BASE] | |
|
762 | if ( | |
|
763 | new_base == p2_base | |
|
764 | or new_base == nodemod.nullrev | |
|
765 | or new_base >= total_revs | |
|
766 | ): | |
|
767 | break | |
|
768 | p2_base = new_base | |
|
769 | e2 = index[p2_base] | |
|
770 | ||
|
771 | if generaldelta: | |
|
772 | if base == p1: | |
|
773 | deltatype = b'p1' | |
|
774 | elif base == p2: | |
|
775 | deltatype = b'p2' | |
|
776 | elif base == rev: | |
|
777 | deltatype = b'base' | |
|
778 | elif base == p1_base: | |
|
779 | deltatype = b'skip1' | |
|
780 | elif base == p2_base: | |
|
781 | deltatype = b'skip2' | |
|
782 | elif r.issnapshot(rev): | |
|
783 | deltatype = b'snap' | |
|
784 | elif base == rev - 1: | |
|
785 | deltatype = b'prev' | |
|
786 | else: | |
|
787 | deltatype = b'other' | |
|
788 | else: | |
|
789 | if base == rev: | |
|
790 | deltatype = b'base' | |
|
791 | else: | |
|
792 | deltatype = b'prev' | |
|
793 | ||
|
794 | chain = r._deltachain(rev)[0] | |
|
795 | chain_size = 0 | |
|
796 | for iter_rev in reversed(chain): | |
|
797 | cached = chain_size_cache.get(iter_rev) | |
|
798 | if cached is not None: | |
|
799 | chain_size += cached | |
|
800 | break | |
|
801 | e = index[iter_rev] | |
|
802 | chain_size += e[constants.ENTRY_DATA_COMPRESSED_LENGTH] | |
|
803 | chain_size_cache[rev] = chain_size | |
|
804 | ||
|
805 | return p1, p2, compsize, uncompsize, deltatype, chain, chain_size | |
|
806 | ||
|
807 | header = ( | |
|
808 | b' rev p1 p2 chain# chainlen prev delta ' | |
|
809 | b'size rawsize chainsize ratio lindist extradist ' | |
|
810 | b'extraratio' | |
|
811 | ) | |
|
812 | if withsparseread: | |
|
813 | header += b' readsize largestblk rddensity srchunks' | |
|
814 | header += b'\n' | |
|
815 | yield header | |
|
816 | ||
|
817 | chainbases = {} | |
|
818 | for rev in r: | |
|
819 | p1, p2, comp, uncomp, deltatype, chain, chainsize = revinfo(rev) | |
|
820 | chainbase = chain[0] | |
|
821 | chainid = chainbases.setdefault(chainbase, len(chainbases) + 1) | |
|
822 | basestart = start(chainbase) | |
|
823 | revstart = start(rev) | |
|
824 | lineardist = revstart + comp - basestart | |
|
825 | extradist = lineardist - chainsize | |
|
826 | try: | |
|
827 | prevrev = chain[-2] | |
|
828 | except IndexError: | |
|
829 | prevrev = -1 | |
|
830 | ||
|
831 | if uncomp != 0: | |
|
832 | chainratio = float(chainsize) / float(uncomp) | |
|
833 | else: | |
|
834 | chainratio = chainsize | |
|
835 | ||
|
836 | if chainsize != 0: | |
|
837 | extraratio = float(extradist) / float(chainsize) | |
|
838 | else: | |
|
839 | extraratio = extradist | |
|
840 | ||
|
841 | # label, display-format, data-key, value | |
|
842 | entry = [ | |
|
843 | (b'rev', b'%7d', 'rev', rev), | |
|
844 | (b'p1', b'%7d', 'p1', p1), | |
|
845 | (b'p2', b'%7d', 'p2', p2), | |
|
846 | (b'chainid', b'%7d', 'chainid', chainid), | |
|
847 | (b'chainlen', b'%8d', 'chainlen', len(chain)), | |
|
848 | (b'prevrev', b'%8d', 'prevrev', prevrev), | |
|
849 | (b'deltatype', b'%7s', 'deltatype', deltatype), | |
|
850 | (b'compsize', b'%10d', 'compsize', comp), | |
|
851 | (b'uncompsize', b'%10d', 'uncompsize', uncomp), | |
|
852 | (b'chainsize', b'%10d', 'chainsize', chainsize), | |
|
853 | (b'chainratio', b'%9.5f', 'chainratio', chainratio), | |
|
854 | (b'lindist', b'%9d', 'lindist', lineardist), | |
|
855 | (b'extradist', b'%9d', 'extradist', extradist), | |
|
856 | (b'extraratio', b'%10.5f', 'extraratio', extraratio), | |
|
857 | ] | |
|
858 | if withsparseread: | |
|
859 | readsize = 0 | |
|
860 | largestblock = 0 | |
|
861 | srchunks = 0 | |
|
862 | ||
|
863 | for revschunk in deltautil.slicechunk(r, chain): | |
|
864 | srchunks += 1 | |
|
865 | blkend = start(revschunk[-1]) + length(revschunk[-1]) | |
|
866 | blksize = blkend - start(revschunk[0]) | |
|
867 | ||
|
868 | readsize += blksize | |
|
869 | if largestblock < blksize: | |
|
870 | largestblock = blksize | |
|
871 | ||
|
872 | if readsize: | |
|
873 | readdensity = float(chainsize) / float(readsize) | |
|
874 | else: | |
|
875 | readdensity = 1 | |
|
876 | entry.extend( | |
|
877 | [ | |
|
878 | (b'readsize', b'%10d', 'readsize', readsize), | |
|
879 | (b'largestblock', b'%10d', 'largestblock', largestblock), | |
|
880 | (b'readdensity', b'%9.5f', 'readdensity', readdensity), | |
|
881 | (b'srchunks', b'%8d', 'srchunks', srchunks), | |
|
882 | ] | |
|
883 | ) | |
|
884 | yield entry |
General Comments 0
You need to be logged in to leave comments.
Login now