Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/debugcommands.py @ 51075:d7f975e49f20
delta-chain: move the debugdeltachain command in revlogutils
There is a dedicated `mercurial.revlogutils.debug` module were this code fits
well.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 18 Sep 2023 23:26:00 +0200 |
parents | 47d43efda8b7 |
children | 810446d2d5ef |
comparison
equal
deleted
inserted
replaced
51074:a63e1f7987a7 | 51075:d7f975e49f20 |
---|---|
103 stringutil, | 103 stringutil, |
104 urlutil, | 104 urlutil, |
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, |
114 ) | 112 ) |
115 | 113 |
797 :``readdensity``: density of useful bytes in the data read from the disk | 795 :``readdensity``: density of useful bytes in the data read from the disk |
798 :``srchunks``: in how many data hunks the whole revision would be read | 796 :``srchunks``: in how many data hunks the whole revision would be read |
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 |
999 @command( | 820 @command( |
1000 b'debug-delta-find', | 821 b'debug-delta-find', |