mercurial/revlogutils/debug.py
changeset 51067 d7f975e49f20
parent 51014 edc44ab7437a
child 51068 793a058f64bd
equal deleted inserted replaced
51066:a63e1f7987a7 51067: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