Show More
@@ -105,9 +105,7 b' from .utils import (' | |||||
105 |
) |
|
105 | ) | |
106 |
|
106 | |||
107 |
from .revlogutils import ( |
|
107 | from .revlogutils import ( | |
108 | constants as revlog_constants, |
|
|||
109 |
debug as revlog_debug, |
|
108 | debug as revlog_debug, | |
110 | deltas as deltautil, |
|
|||
111 |
nodemap, |
|
109 | nodemap, | |
112 |
rewrite, |
|
110 | rewrite, | |
113 |
sidedata, |
|
111 | sidedata, | |
@@ -799,200 +797,23 b' def debugdeltachain(ui, repo, file_=None' | |||||
799 |
|
797 | |||
800 |
The sparse read can be enabled with experimental.sparse-read = True |
|
798 | The sparse read can be enabled with experimental.sparse-read = True | |
801 |
""" |
|
799 | """ | |
802 |
r = cmdutil.openrevlog( |
|
800 | revlog = cmdutil.openrevlog( | |
803 |
repo, b'debugdeltachain', file_, pycompat.byteskwargs(opts) |
|
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 |
fm = ui.formatter(b'debugdeltachain', pycompat.byteskwargs(opts)) |
|
803 | fm = ui.formatter(b'debugdeltachain', pycompat.byteskwargs(opts)) | |
895 |
|
804 | |||
896 | fm.plain( |
|
805 | lines = revlog_debug.debug_delta_chain(revlog) | |
897 | b' rev p1 p2 chain# chainlen prev delta ' |
|
806 | # first entry is the header | |
898 | b'size rawsize chainsize ratio lindist extradist ' |
|
807 | header = next(lines) | |
899 | b'extraratio' |
|
808 | fm.plain(header) | |
900 | ) |
|
809 | for entry in lines: | |
901 | if withsparseread: |
|
810 | label = b' '.join(e[0] for e in entry) | |
902 | fm.plain(b' readsize largestblk rddensity srchunks') |
|
811 | format = b' '.join(e[1] for e in entry) | |
903 | fm.plain(b'\n') |
|
812 | values = [e[3] for e in entry] | |
904 |
|
813 | data = dict((e[2], e[3]) for e in entry) | ||
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 |
|
||||
929 |
fm.startitem() |
|
814 | fm.startitem() | |
930 | fm.write( |
|
815 | fm.write(label, format, *values, **data) | |
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 |
|
||||
994 |
fm.plain(b'\n') |
|
816 | fm.plain(b'\n') | |
995 |
|
||||
996 |
fm.end() |
|
817 | fm.end() | |
997 |
|
818 | |||
998 |
|
819 |
@@ -710,3 +710,175 b' def debug_revlog_stats(' | |||||
710 | fm.write(b'revlog.target', b' %s', revlog_target) |
|
710 | fm.write(b'revlog.target', b' %s', revlog_target) | |
711 |
|
711 | |||
712 | fm.plain(b'\n') |
|
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