##// END OF EJS Templates
delta-chain: move the debugdeltachain command in revlogutils...
marmoute -
r51963:d7f975e4 default
parent child Browse files
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