Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlogutils/debug.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 | edc44ab7437a |
children | 793a058f64bd |
comparison
equal
deleted
inserted
replaced
51074:a63e1f7987a7 | 51075:d7f975e49f20 |
---|---|
708 fm.write(b'revlog.inline', b' %-3s', b'yes' if inline else b'no') | 708 fm.write(b'revlog.inline', b' %-3s', b'yes' if inline else b'no') |
709 fm.write(b'revlog.type', b' %-9s', revlog_type) | 709 fm.write(b'revlog.type', b' %-9s', revlog_type) |
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 |