mercurial/debugcommands.py
changeset 51067 d7f975e49f20
parent 51056 47d43efda8b7
child 51069 810446d2d5ef
equal deleted inserted replaced
51066:a63e1f7987a7 51067: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',