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 |