Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mercurial/mercurial-devel
1 result
Show changes
Commits on Source (14)
Showing
with 813 additions and 104 deletions
...@@ -299,6 +299,7 @@ ...@@ -299,6 +299,7 @@
deltaprevious=False, deltaprevious=False,
deltamode=None, deltamode=None,
sidedata_helpers=None, sidedata_helpers=None,
debug_info=None,
): ):
# we don't use any of these parameters here # we don't use any of these parameters here
del nodesorder, revisiondata, assumehaveparentrevisions, deltaprevious del nodesorder, revisiondata, assumehaveparentrevisions, deltaprevious
......
...@@ -589,6 +589,7 @@ ...@@ -589,6 +589,7 @@
assumehaveparentrevisions=False, assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD, deltamode=repository.CG_DELTAMODE_STD,
sidedata_helpers=None, sidedata_helpers=None,
debug_info=None,
): ):
if nodesorder not in (b'nodes', b'storage', b'linear', None): if nodesorder not in (b'nodes', b'storage', b'linear', None):
raise error.ProgrammingError( raise error.ProgrammingError(
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
version: int version: int
def bdiff(a: bytes, b: bytes): bytes def bdiff(a: bytes, b: bytes) -> bytes: ...
def blocks(a: bytes, b: bytes) -> List[Tuple[int, int, int, int]]: ... def blocks(a: bytes, b: bytes) -> List[Tuple[int, int, int, int]]: ...
def fixws(s: bytes, allws: bool) -> bytes: ... def fixws(s: bytes, allws: bool) -> bytes: ...
def splitnewlines(text: bytes) -> List[bytes]: ... def splitnewlines(text: bytes) -> List[bytes]: ...
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
AnyStr, AnyStr,
IO, IO,
List, List,
Optional,
Sequence, Sequence,
) )
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
st_mtime: int st_mtime: int
st_ctime: int st_ctime: int
def listdir(path: bytes, st: bool, skip: bool) -> List[stat]: ... def listdir(path: bytes, st: bool, skip: Optional[bool]) -> List[stat]: ...
def posixfile(name: AnyStr, mode: bytes, buffering: int) -> IO: ... def posixfile(name: AnyStr, mode: bytes, buffering: int) -> IO: ...
def statfiles(names: Sequence[bytes]) -> List[stat]: ... def statfiles(names: Sequence[bytes]) -> List[stat]: ...
def setprocname(name: bytes) -> None: ... def setprocname(name: bytes) -> None: ...
......
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
import struct import struct
from typing import (
List,
Tuple,
)
from ..pure.bdiff import * from ..pure.bdiff import *
from . import _bdiff # pytype: disable=import-error from . import _bdiff # pytype: disable=import-error
...@@ -15,7 +20,7 @@ ...@@ -15,7 +20,7 @@
lib = _bdiff.lib lib = _bdiff.lib
def blocks(sa, sb): def blocks(sa: bytes, sb: bytes) -> List[Tuple[int, int, int, int]]:
a = ffi.new(b"struct bdiff_line**") a = ffi.new(b"struct bdiff_line**")
b = ffi.new(b"struct bdiff_line**") b = ffi.new(b"struct bdiff_line**")
ac = ffi.new(b"char[]", str(sa)) ac = ffi.new(b"char[]", str(sa))
...@@ -29,7 +34,7 @@ ...@@ -29,7 +34,7 @@
count = lib.bdiff_diff(a[0], an, b[0], bn, l) count = lib.bdiff_diff(a[0], an, b[0], bn, l)
if count < 0: if count < 0:
raise MemoryError raise MemoryError
rl = [None] * count rl = [(0, 0, 0, 0)] * count
h = l.next h = l.next
i = 0 i = 0
while h: while h:
...@@ -43,7 +48,7 @@ ...@@ -43,7 +48,7 @@
return rl return rl
def bdiff(sa, sb): def bdiff(sa: bytes, sb: bytes) -> bytes:
a = ffi.new(b"struct bdiff_line**") a = ffi.new(b"struct bdiff_line**")
b = ffi.new(b"struct bdiff_line**") b = ffi.new(b"struct bdiff_line**")
ac = ffi.new(b"char[]", str(sa)) ac = ffi.new(b"char[]", str(sa))
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
# GNU General Public License version 2 or any later version. # GNU General Public License version 2 or any later version.
from typing import List
from ..pure.mpatch import * from ..pure.mpatch import *
from ..pure.mpatch import mpatchError # silence pyflakes from ..pure.mpatch import mpatchError # silence pyflakes
from . import _mpatch # pytype: disable=import-error from . import _mpatch # pytype: disable=import-error
...@@ -26,7 +28,7 @@ ...@@ -26,7 +28,7 @@
return container[0] return container[0]
def patches(text, bins): def patches(text: bytes, bins: List[bytes]) -> bytes:
lgt = len(bins) lgt = len(bins)
all = [] all = []
if not lgt: if not lgt:
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
ofs = cur.name_info.attr_dataoffset ofs = cur.name_info.attr_dataoffset
str_lgt = cur.name_info.attr_length str_lgt = cur.name_info.attr_length
base_ofs = ffi.offsetof(b'val_attrs_t', b'name_info') base_ofs = ffi.offsetof(b'val_attrs_t', b'name_info')
name = str( name = bytes(
ffi.buffer( ffi.buffer(
ffi.cast(b"char*", cur) + base_ofs + ofs, str_lgt - 1 ffi.cast(b"char*", cur) + base_ofs + ofs, str_lgt - 1
) )
......
This diff is collapsed.
...@@ -588,6 +588,18 @@ ...@@ -588,6 +588,18 @@
b'revlog.debug-delta', b'revlog.debug-delta',
default=False, default=False,
) )
# display extra information about the bundling process
coreconfigitem(
b'debug',
b'bundling-stats',
default=False,
)
# display extra information about the unbundling process
coreconfigitem(
b'debug',
b'unbundling-stats',
default=False,
)
coreconfigitem( coreconfigitem(
b'defaults', b'defaults',
b'.*', b'.*',
......
...@@ -111,6 +111,7 @@ ...@@ -111,6 +111,7 @@
assumehaveparentrevisions=False, assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD, deltamode=repository.CG_DELTAMODE_STD,
sidedata_helpers=None, sidedata_helpers=None,
debug_info=None,
): ):
return self._revlog.emitrevisions( return self._revlog.emitrevisions(
nodes, nodes,
...@@ -119,6 +120,7 @@ ...@@ -119,6 +120,7 @@
assumehaveparentrevisions=assumehaveparentrevisions, assumehaveparentrevisions=assumehaveparentrevisions,
deltamode=deltamode, deltamode=deltamode,
sidedata_helpers=sidedata_helpers, sidedata_helpers=sidedata_helpers,
debug_info=debug_info,
) )
def addrevision( def addrevision(
...@@ -151,6 +153,7 @@ ...@@ -151,6 +153,7 @@
addrevisioncb=None, addrevisioncb=None,
duplicaterevisioncb=None, duplicaterevisioncb=None,
maybemissingparents=False, maybemissingparents=False,
debug_info=None,
): ):
if maybemissingparents: if maybemissingparents:
raise error.Abort( raise error.Abort(
...@@ -171,6 +174,7 @@ ...@@ -171,6 +174,7 @@
transaction, transaction,
addrevisioncb=addrevisioncb, addrevisioncb=addrevisioncb,
duplicaterevisioncb=duplicaterevisioncb, duplicaterevisioncb=duplicaterevisioncb,
debug_info=debug_info,
) )
def getstrippoint(self, minlink): def getstrippoint(self, minlink):
......
...@@ -1836,6 +1836,7 @@ ...@@ -1836,6 +1836,7 @@
assumehaveparentrevisions=False, assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD, deltamode=repository.CG_DELTAMODE_STD,
sidedata_helpers=None, sidedata_helpers=None,
debug_info=None,
): ):
return self._revlog.emitrevisions( return self._revlog.emitrevisions(
nodes, nodes,
...@@ -1844,6 +1845,7 @@ ...@@ -1844,6 +1845,7 @@
assumehaveparentrevisions=assumehaveparentrevisions, assumehaveparentrevisions=assumehaveparentrevisions,
deltamode=deltamode, deltamode=deltamode,
sidedata_helpers=sidedata_helpers, sidedata_helpers=sidedata_helpers,
debug_info=debug_info,
) )
def addgroup( def addgroup(
...@@ -1854,6 +1856,7 @@ ...@@ -1854,6 +1856,7 @@
alwayscache=False, alwayscache=False,
addrevisioncb=None, addrevisioncb=None,
duplicaterevisioncb=None, duplicaterevisioncb=None,
debug_info=None,
): ):
return self._revlog.addgroup( return self._revlog.addgroup(
deltas, deltas,
...@@ -1862,6 +1865,7 @@ ...@@ -1862,6 +1865,7 @@
alwayscache=alwayscache, alwayscache=alwayscache,
addrevisioncb=addrevisioncb, addrevisioncb=addrevisioncb,
duplicaterevisioncb=duplicaterevisioncb, duplicaterevisioncb=duplicaterevisioncb,
debug_info=debug_info,
) )
def rawsize(self, rev): def rawsize(self, rev):
......
...@@ -10,4 +10,8 @@ ...@@ -10,4 +10,8 @@
import re import re
import struct import struct
from typing import (
List,
Tuple,
)
...@@ -13,5 +17,6 @@ ...@@ -13,5 +17,6 @@
def splitnewlines(text):
def splitnewlines(text: bytes) -> List[bytes]:
'''like str.splitlines, but only split on newlines.''' '''like str.splitlines, but only split on newlines.'''
lines = [l + b'\n' for l in text.split(b'\n')] lines = [l + b'\n' for l in text.split(b'\n')]
if lines: if lines:
...@@ -22,7 +27,9 @@ ...@@ -22,7 +27,9 @@
return lines return lines
def _normalizeblocks(a, b, blocks): def _normalizeblocks(
a: List[bytes], b: List[bytes], blocks
) -> List[Tuple[int, int, int]]:
prev = None prev = None
r = [] r = []
for curr in blocks: for curr in blocks:
...@@ -57,7 +64,7 @@ ...@@ -57,7 +64,7 @@
return r return r
def bdiff(a, b): def bdiff(a: bytes, b: bytes) -> bytes:
a = bytes(a).splitlines(True) a = bytes(a).splitlines(True)
b = bytes(b).splitlines(True) b = bytes(b).splitlines(True)
...@@ -84,7 +91,7 @@ ...@@ -84,7 +91,7 @@
return b"".join(bin) return b"".join(bin)
def blocks(a, b): def blocks(a: bytes, b: bytes) -> List[Tuple[int, int, int, int]]:
an = splitnewlines(a) an = splitnewlines(a)
bn = splitnewlines(b) bn = splitnewlines(b)
d = difflib.SequenceMatcher(None, an, bn).get_matching_blocks() d = difflib.SequenceMatcher(None, an, bn).get_matching_blocks()
...@@ -92,7 +99,7 @@ ...@@ -92,7 +99,7 @@
return [(i, i + n, j, j + n) for (i, j, n) in d] return [(i, i + n, j, j + n) for (i, j, n) in d]
def fixws(text, allws): def fixws(text: bytes, allws: bool) -> bytes:
if allws: if allws:
text = re.sub(b'[ \t\r]+', b'', text) text = re.sub(b'[ \t\r]+', b'', text)
else: else:
......
...@@ -9,6 +9,11 @@ ...@@ -9,6 +9,11 @@
import io import io
import struct import struct
from typing import (
List,
Tuple,
)
stringio = io.BytesIO stringio = io.BytesIO
...@@ -28,7 +33,9 @@ ...@@ -28,7 +33,9 @@
# temporary string buffers. # temporary string buffers.
def _pull(dst, src, l): # pull l bytes from src def _pull(
dst: List[Tuple[int, int]], src: List[Tuple[int, int]], l: int
) -> None: # pull l bytes from src
while l: while l:
f = src.pop() f = src.pop()
if f[0] > l: # do we need to split? if f[0] > l: # do we need to split?
...@@ -39,7 +46,7 @@ ...@@ -39,7 +46,7 @@
l -= f[0] l -= f[0]
def _move(m, dest, src, count): def _move(m: stringio, dest: int, src: int, count: int) -> None:
"""move count bytes from src to dest """move count bytes from src to dest
The file pointer is left at the end of dest. The file pointer is left at the end of dest.
...@@ -50,7 +57,9 @@ ...@@ -50,7 +57,9 @@
m.write(buf) m.write(buf)
def _collect(m, buf, list): def _collect(
m: stringio, buf: int, list: List[Tuple[int, int]]
) -> Tuple[int, int]:
start = buf start = buf
for l, p in reversed(list): for l, p in reversed(list):
_move(m, buf, p, l) _move(m, buf, p, l)
...@@ -58,7 +67,7 @@ ...@@ -58,7 +67,7 @@
return (buf - start, start) return (buf - start, start)
def patches(a, bins): def patches(a: bytes, bins: List[bytes]) -> bytes:
if not bins: if not bins:
return a return a
...@@ -111,7 +120,7 @@ ...@@ -111,7 +120,7 @@
return m.read(t[0]) return m.read(t[0])
def patchedsize(orig, delta): def patchedsize(orig: int, delta: bytes) -> int:
outlen, last, bin = 0, 0, 0 outlen, last, bin = 0, 0, 0
binend = len(delta) binend = len(delta)
data = 12 data = 12
......
...@@ -2640,6 +2640,7 @@ ...@@ -2640,6 +2640,7 @@
alwayscache=False, alwayscache=False,
addrevisioncb=None, addrevisioncb=None,
duplicaterevisioncb=None, duplicaterevisioncb=None,
debug_info=None,
): ):
""" """
add a delta group add a delta group
...@@ -2665,6 +2666,7 @@ ...@@ -2665,6 +2666,7 @@
deltacomputer = deltautil.deltacomputer( deltacomputer = deltautil.deltacomputer(
self, self,
write_debug=write_debug, write_debug=write_debug,
debug_info=debug_info,
) )
# loop through our set of deltas # loop through our set of deltas
for data in deltas: for data in deltas:
...@@ -2889,6 +2891,7 @@ ...@@ -2889,6 +2891,7 @@
assumehaveparentrevisions=False, assumehaveparentrevisions=False,
deltamode=repository.CG_DELTAMODE_STD, deltamode=repository.CG_DELTAMODE_STD,
sidedata_helpers=None, sidedata_helpers=None,
debug_info=None,
): ):
if nodesorder not in (b'nodes', b'storage', b'linear', None): if nodesorder not in (b'nodes', b'storage', b'linear', None):
raise error.ProgrammingError( raise error.ProgrammingError(
...@@ -2918,6 +2921,7 @@ ...@@ -2918,6 +2921,7 @@
revisiondata=revisiondata, revisiondata=revisiondata,
assumehaveparentrevisions=assumehaveparentrevisions, assumehaveparentrevisions=assumehaveparentrevisions,
sidedata_helpers=sidedata_helpers, sidedata_helpers=sidedata_helpers,
debug_info=debug_info,
) )
DELTAREUSEALWAYS = b'always' DELTAREUSEALWAYS = b'always'
......
...@@ -655,7 +655,15 @@ ...@@ -655,7 +655,15 @@
LIMIT_BASE2TEXT = 500 LIMIT_BASE2TEXT = 500
def _candidategroups(revlog, textlen, p1, p2, cachedelta): def _candidategroups(
revlog,
textlen,
p1,
p2,
cachedelta,
excluded_bases=None,
target_rev=None,
):
"""Provides group of revision to be tested as delta base """Provides group of revision to be tested as delta base
This top level function focus on emitting groups with unique and worthwhile This top level function focus on emitting groups with unique and worthwhile
...@@ -674,7 +682,12 @@ ...@@ -674,7 +682,12 @@
deltas_limit = textlen * LIMIT_DELTA2TEXT deltas_limit = textlen * LIMIT_DELTA2TEXT
tested = {nullrev} tested = {nullrev}
candidates = _refinedgroups(revlog, p1, p2, cachedelta) candidates = _refinedgroups(
revlog,
p1,
p2,
cachedelta,
)
while True: while True:
temptative = candidates.send(good) temptative = candidates.send(good)
if temptative is None: if temptative is None:
...@@ -694,6 +707,14 @@ ...@@ -694,6 +707,14 @@
# filter out revision we tested already # filter out revision we tested already
if rev in tested: if rev in tested:
continue continue
tested.add(rev) # an higher authority deamed the base unworthy (e.g. censored)
if excluded_bases is not None and rev in excluded_bases:
tested.add(rev)
continue
# We are in some recomputation cases and that rev is too high in
# the revlog
if target_rev is not None and rev >= target_rev:
tested.add(rev)
continue
# filter out delta base that will never produce good delta # filter out delta base that will never produce good delta
if deltas_limit < revlog.length(rev): if deltas_limit < revlog.length(rev):
...@@ -698,4 +719,5 @@ ...@@ -698,4 +719,5 @@
# filter out delta base that will never produce good delta # filter out delta base that will never produce good delta
if deltas_limit < revlog.length(rev): if deltas_limit < revlog.length(rev):
tested.add(rev)
continue continue
if sparse and revlog.rawsize(rev) < (textlen // LIMIT_BASE2TEXT): if sparse and revlog.rawsize(rev) < (textlen // LIMIT_BASE2TEXT):
...@@ -700,5 +722,6 @@ ...@@ -700,5 +722,6 @@
continue continue
if sparse and revlog.rawsize(rev) < (textlen // LIMIT_BASE2TEXT): if sparse and revlog.rawsize(rev) < (textlen // LIMIT_BASE2TEXT):
tested.add(rev)
continue continue
# no delta for rawtext-changing revs (see "candelta" for why) # no delta for rawtext-changing revs (see "candelta" for why)
if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS: if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
...@@ -702,4 +725,5 @@ ...@@ -702,4 +725,5 @@
continue continue
# no delta for rawtext-changing revs (see "candelta" for why) # no delta for rawtext-changing revs (see "candelta" for why)
if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS: if revlog.flags(rev) & REVIDX_RAWTEXT_CHANGING_FLAGS:
tested.add(rev)
continue continue
...@@ -705,4 +729,5 @@ ...@@ -705,4 +729,5 @@
continue continue
# If we reach here, we are about to build and test a delta. # If we reach here, we are about to build and test a delta.
# The delta building process will compute the chaininfo in all # The delta building process will compute the chaininfo in all
# case, since that computation is cached, it is fine to access it # case, since that computation is cached, it is fine to access it
...@@ -710,6 +735,7 @@ ...@@ -710,6 +735,7 @@
chainlen, chainsize = revlog._chaininfo(rev) chainlen, chainsize = revlog._chaininfo(rev)
# if chain will be too long, skip base # if chain will be too long, skip base
if revlog._maxchainlen and chainlen >= revlog._maxchainlen: if revlog._maxchainlen and chainlen >= revlog._maxchainlen:
tested.add(rev)
continue continue
# if chain already have too much data, skip base # if chain already have too much data, skip base
if deltas_limit < chainsize: if deltas_limit < chainsize:
...@@ -713,6 +739,7 @@ ...@@ -713,6 +739,7 @@
continue continue
# if chain already have too much data, skip base # if chain already have too much data, skip base
if deltas_limit < chainsize: if deltas_limit < chainsize:
tested.add(rev)
continue continue
if sparse and revlog.upperboundcomp is not None: if sparse and revlog.upperboundcomp is not None:
maxcomp = revlog.upperboundcomp maxcomp = revlog.upperboundcomp
...@@ -731,9 +758,10 @@ ...@@ -731,9 +758,10 @@
snapshotlimit = textlen >> snapshotdepth snapshotlimit = textlen >> snapshotdepth
if snapshotlimit < lowestrealisticdeltalen: if snapshotlimit < lowestrealisticdeltalen:
# delta lower bound is larger than accepted upper bound # delta lower bound is larger than accepted upper bound
tested.add(rev)
continue continue
# check the relative constraint on the delta size # check the relative constraint on the delta size
revlength = revlog.length(rev) revlength = revlog.length(rev)
if revlength < lowestrealisticdeltalen: if revlength < lowestrealisticdeltalen:
# delta probable lower bound is larger than target base # delta probable lower bound is larger than target base
...@@ -734,9 +762,10 @@ ...@@ -734,9 +762,10 @@
continue continue
# check the relative constraint on the delta size # check the relative constraint on the delta size
revlength = revlog.length(rev) revlength = revlog.length(rev)
if revlength < lowestrealisticdeltalen: if revlength < lowestrealisticdeltalen:
# delta probable lower bound is larger than target base # delta probable lower bound is larger than target base
tested.add(rev)
continue continue
group.append(rev) group.append(rev)
...@@ -744,6 +773,7 @@ ...@@ -744,6 +773,7 @@
# XXX: in the sparse revlog case, group can become large, # XXX: in the sparse revlog case, group can become large,
# impacting performances. Some bounding or slicing mecanism # impacting performances. Some bounding or slicing mecanism
# would help to reduce this impact. # would help to reduce this impact.
tested.update(group)
good = yield tuple(group) good = yield tuple(group)
yield None yield None
...@@ -768,6 +798,7 @@ ...@@ -768,6 +798,7 @@
# This logic only applies to general delta repositories and can be disabled # This logic only applies to general delta repositories and can be disabled
# through configuration. Disabling reuse source delta is useful when # through configuration. Disabling reuse source delta is useful when
# we want to make sure we recomputed "optimal" deltas. # we want to make sure we recomputed "optimal" deltas.
debug_info = None
if cachedelta and revlog._generaldelta and revlog._lazydeltabase: if cachedelta and revlog._generaldelta and revlog._lazydeltabase:
# Assume what we received from the server is a good choice # Assume what we received from the server is a good choice
# build delta will reuse the cache # build delta will reuse the cache
...@@ -771,5 +802,7 @@ ...@@ -771,5 +802,7 @@
if cachedelta and revlog._generaldelta and revlog._lazydeltabase: if cachedelta and revlog._generaldelta and revlog._lazydeltabase:
# Assume what we received from the server is a good choice # Assume what we received from the server is a good choice
# build delta will reuse the cache # build delta will reuse the cache
if debug_info is not None:
debug_info['cached-delta.tested'] += 1
good = yield (cachedelta[0],) good = yield (cachedelta[0],)
if good is not None: if good is not None:
...@@ -774,4 +807,6 @@ ...@@ -774,4 +807,6 @@
good = yield (cachedelta[0],) good = yield (cachedelta[0],)
if good is not None: if good is not None:
if debug_info is not None:
debug_info['cached-delta.accepted'] += 1
yield None yield None
return return
...@@ -776,3 +811,4 @@ ...@@ -776,3 +811,4 @@
yield None yield None
return return
# XXX cache me higher
snapshots = collections.defaultdict(list) snapshots = collections.defaultdict(list)
...@@ -778,5 +814,12 @@ ...@@ -778,5 +814,12 @@
snapshots = collections.defaultdict(list) snapshots = collections.defaultdict(list)
for candidates in _rawgroups(revlog, p1, p2, cachedelta, snapshots): groups = _rawgroups(
revlog,
p1,
p2,
cachedelta,
snapshots,
)
for candidates in groups:
good = yield candidates good = yield candidates
if good is not None: if good is not None:
break break
...@@ -805,7 +848,10 @@ ...@@ -805,7 +848,10 @@
children = tuple(sorted(c for c in snapshots[good])) children = tuple(sorted(c for c in snapshots[good]))
good = yield children good = yield children
# we have found nothing if debug_info is not None:
if good is None:
debug_info['no-solution'] += 1
yield None yield None
...@@ -841,7 +887,7 @@ ...@@ -841,7 +887,7 @@
if sparse and parents: if sparse and parents:
if snapshots is None: if snapshots is None:
# map: base-rev: snapshot-rev # map: base-rev: [snapshot-revs]
snapshots = collections.defaultdict(list) snapshots = collections.defaultdict(list)
# See if we can use an existing snapshot in the parent chains to use as # See if we can use an existing snapshot in the parent chains to use as
# a base for a new intermediate-snapshot # a base for a new intermediate-snapshot
...@@ -879,6 +925,6 @@ ...@@ -879,6 +925,6 @@
# chain. # chain.
max_depth = max(parents_snaps.keys()) max_depth = max(parents_snaps.keys())
chain = deltachain(other) chain = deltachain(other)
for idx, s in enumerate(chain): for depth, s in enumerate(chain):
if s < snapfloor: if s < snapfloor:
continue continue
...@@ -883,6 +929,6 @@ ...@@ -883,6 +929,6 @@
if s < snapfloor: if s < snapfloor:
continue continue
if max_depth < idx: if max_depth < depth:
break break
if not revlog.issnapshot(s): if not revlog.issnapshot(s):
break break
...@@ -886,7 +932,7 @@ ...@@ -886,7 +932,7 @@
break break
if not revlog.issnapshot(s): if not revlog.issnapshot(s):
break break
parents_snaps[idx].add(s) parents_snaps[depth].add(s)
# Test them as possible intermediate snapshot base # Test them as possible intermediate snapshot base
# We test them from highest to lowest level. High level one are more # We test them from highest to lowest level. High level one are more
# likely to result in small delta # likely to result in small delta
...@@ -931,7 +977,13 @@ ...@@ -931,7 +977,13 @@
class deltacomputer: class deltacomputer:
def __init__(self, revlog, write_debug=None, debug_search=False): def __init__(
self,
revlog,
write_debug=None,
debug_search=False,
debug_info=None,
):
self.revlog = revlog self.revlog = revlog
self._write_debug = write_debug self._write_debug = write_debug
self._debug_search = debug_search self._debug_search = debug_search
...@@ -935,6 +987,7 @@ ...@@ -935,6 +987,7 @@
self.revlog = revlog self.revlog = revlog
self._write_debug = write_debug self._write_debug = write_debug
self._debug_search = debug_search self._debug_search = debug_search
self._debug_info = debug_info
def buildtext(self, revinfo, fh): def buildtext(self, revinfo, fh):
"""Builds a fulltext version of a revision """Builds a fulltext version of a revision
...@@ -1103,6 +1156,11 @@ ...@@ -1103,6 +1156,11 @@
if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS: if revinfo.flags & REVIDX_RAWTEXT_CHANGING_FLAGS:
return self._fullsnapshotinfo(fh, revinfo, target_rev) return self._fullsnapshotinfo(fh, revinfo, target_rev)
if self._write_debug is not None: gather_debug = (
self._write_debug is not None or self._debug_info is not None
)
debug_search = self._write_debug is not None and self._debug_search
if gather_debug:
start = util.timer() start = util.timer()
...@@ -1107,7 +1165,5 @@ ...@@ -1107,7 +1165,5 @@
start = util.timer() start = util.timer()
debug_search = self._write_debug is not None and self._debug_search
# count the number of different delta we tried (for debug purpose) # count the number of different delta we tried (for debug purpose)
dbg_try_count = 0 dbg_try_count = 0
# count the number of "search round" we did. (for debug purpose) # count the number of "search round" we did. (for debug purpose)
...@@ -1122,7 +1178,7 @@ ...@@ -1122,7 +1178,7 @@
deltainfo = None deltainfo = None
p1r, p2r = revlog.rev(p1), revlog.rev(p2) p1r, p2r = revlog.rev(p1), revlog.rev(p2)
if self._write_debug is not None: if gather_debug:
if p1r != nullrev: if p1r != nullrev:
p1_chain_len = revlog._chaininfo(p1r)[0] p1_chain_len = revlog._chaininfo(p1r)[0]
else: else:
...@@ -1137,7 +1193,13 @@ ...@@ -1137,7 +1193,13 @@
self._write_debug(msg) self._write_debug(msg)
groups = _candidategroups( groups = _candidategroups(
self.revlog, revinfo.textlen, p1r, p2r, cachedelta self.revlog,
revinfo.textlen,
p1r,
p2r,
cachedelta,
excluded_bases,
target_rev,
) )
candidaterevs = next(groups) candidaterevs = next(groups)
while candidaterevs is not None: while candidaterevs is not None:
...@@ -1147,7 +1209,13 @@ ...@@ -1147,7 +1209,13 @@
if deltainfo is not None: if deltainfo is not None:
prev = deltainfo.base prev = deltainfo.base
if p1 in candidaterevs or p2 in candidaterevs: if (
cachedelta is not None
and len(candidaterevs) == 1
and cachedelta[0] in candidaterevs
):
round_type = b"cached-delta"
elif p1 in candidaterevs or p2 in candidaterevs:
round_type = b"parents" round_type = b"parents"
elif prev is not None and all(c < prev for c in candidaterevs): elif prev is not None and all(c < prev for c in candidaterevs):
round_type = b"refine-down" round_type = b"refine-down"
...@@ -1195,16 +1263,7 @@ ...@@ -1195,16 +1263,7 @@
msg = b"DBG-DELTAS-SEARCH: base=%d\n" msg = b"DBG-DELTAS-SEARCH: base=%d\n"
msg %= self.revlog.deltaparent(candidaterev) msg %= self.revlog.deltaparent(candidaterev)
self._write_debug(msg) self._write_debug(msg)
if candidaterev in excluded_bases:
if debug_search:
msg = b"DBG-DELTAS-SEARCH: EXCLUDED\n"
self._write_debug(msg)
continue
if candidaterev >= target_rev:
if debug_search:
msg = b"DBG-DELTAS-SEARCH: TOO-HIGH\n"
self._write_debug(msg)
continue
dbg_try_count += 1 dbg_try_count += 1
if debug_search: if debug_search:
...@@ -1244,5 +1303,5 @@ ...@@ -1244,5 +1303,5 @@
else: else:
dbg_type = b"delta" dbg_type = b"delta"
if self._write_debug is not None: if gather_debug:
end = util.timer() end = util.timer()
...@@ -1248,4 +1307,10 @@ ...@@ -1248,4 +1307,10 @@
end = util.timer() end = util.timer()
used_cached = (
cachedelta is not None
and dbg_try_rounds == 1
and dbg_try_count == 1
and deltainfo.base == cachedelta[0]
)
dbg = { dbg = {
'duration': end - start, 'duration': end - start,
'revision': target_rev, 'revision': target_rev,
...@@ -1249,4 +1314,5 @@ ...@@ -1249,4 +1314,5 @@
dbg = { dbg = {
'duration': end - start, 'duration': end - start,
'revision': target_rev, 'revision': target_rev,
'delta-base': deltainfo.base, # pytype: disable=attribute-error
'search_round_count': dbg_try_rounds, 'search_round_count': dbg_try_rounds,
...@@ -1252,4 +1318,5 @@ ...@@ -1252,4 +1318,5 @@
'search_round_count': dbg_try_rounds, 'search_round_count': dbg_try_rounds,
'using-cached-base': used_cached,
'delta_try_count': dbg_try_count, 'delta_try_count': dbg_try_count,
'type': dbg_type, 'type': dbg_type,
'p1-chain-len': p1_chain_len, 'p1-chain-len': p1_chain_len,
...@@ -1279,31 +1346,39 @@ ...@@ -1279,31 +1346,39 @@
target_revlog += b'%s:' % target_key target_revlog += b'%s:' % target_key
dbg['target-revlog'] = target_revlog dbg['target-revlog'] = target_revlog
msg = ( if self._debug_info is not None:
b"DBG-DELTAS:" self._debug_info.append(dbg)
b" %-12s"
b" rev=%d:" if self._write_debug is not None:
b" search-rounds=%d" msg = (
b" try-count=%d" b"DBG-DELTAS:"
b" - delta-type=%-6s" b" %-12s"
b" snap-depth=%d" b" rev=%d:"
b" - p1-chain-length=%d" b" delta-base=%d"
b" p2-chain-length=%d" b" is-cached=%d"
b" - duration=%f" b" - search-rounds=%d"
b"\n" b" try-count=%d"
) b" - delta-type=%-6s"
msg %= ( b" snap-depth=%d"
dbg["target-revlog"], b" - p1-chain-length=%d"
dbg["revision"], b" p2-chain-length=%d"
dbg["search_round_count"], b" - duration=%f"
dbg["delta_try_count"], b"\n"
dbg["type"], )
dbg["snapshot-depth"], msg %= (
dbg["p1-chain-len"], dbg["target-revlog"],
dbg["p2-chain-len"], dbg["revision"],
dbg["duration"], dbg["delta-base"],
) dbg["using-cached-base"],
self._write_debug(msg) dbg["search_round_count"],
dbg["delta_try_count"],
dbg["type"],
dbg["snapshot-depth"],
dbg["p1-chain-len"],
dbg["p2-chain-len"],
dbg["duration"],
)
self._write_debug(msg)
return deltainfo return deltainfo
......
...@@ -305,6 +305,7 @@ ...@@ -305,6 +305,7 @@
revisiondata=False, revisiondata=False,
assumehaveparentrevisions=False, assumehaveparentrevisions=False,
sidedata_helpers=None, sidedata_helpers=None,
debug_info=None,
): ):
"""Generic implementation of ifiledata.emitrevisions(). """Generic implementation of ifiledata.emitrevisions().
...@@ -370,6 +371,10 @@ ...@@ -370,6 +371,10 @@
``sidedata_helpers`` (optional) ``sidedata_helpers`` (optional)
If not None, means that sidedata should be included. If not None, means that sidedata should be included.
See `revlogutil.sidedata.get_sidedata_helpers`. See `revlogutil.sidedata.get_sidedata_helpers`.
``debug_info`
An optionnal dictionnary to gather information about the bundling
process (if present, see config: debug.bundling.stats.
""" """
fnode = store.node fnode = store.node
...@@ -395,6 +400,10 @@ ...@@ -395,6 +400,10 @@
if rev == nullrev: if rev == nullrev:
continue continue
debug_delta_source = None
if debug_info is not None:
debug_info['revision-total'] += 1
node = fnode(rev) node = fnode(rev)
p1rev, p2rev = store.parentrevs(rev) p1rev, p2rev = store.parentrevs(rev)
...@@ -398,5 +407,9 @@ ...@@ -398,5 +407,9 @@
node = fnode(rev) node = fnode(rev)
p1rev, p2rev = store.parentrevs(rev) p1rev, p2rev = store.parentrevs(rev)
if debug_info is not None:
if p1rev != p2rev and p1rev != nullrev and p2rev != nullrev:
debug_info['merge-total'] += 1
if deltaparentfn: if deltaparentfn:
deltaparentrev = deltaparentfn(rev) deltaparentrev = deltaparentfn(rev)
...@@ -401,7 +414,13 @@ ...@@ -401,7 +414,13 @@
if deltaparentfn: if deltaparentfn:
deltaparentrev = deltaparentfn(rev) deltaparentrev = deltaparentfn(rev)
if debug_info is not None:
if deltaparentrev == nullrev:
debug_info['available-full'] += 1
else:
debug_info['available-delta'] += 1
else: else:
deltaparentrev = nullrev deltaparentrev = nullrev
# Forced delta against previous mode. # Forced delta against previous mode.
if deltamode == repository.CG_DELTAMODE_PREV: if deltamode == repository.CG_DELTAMODE_PREV:
...@@ -403,9 +422,11 @@ ...@@ -403,9 +422,11 @@
else: else:
deltaparentrev = nullrev deltaparentrev = nullrev
# Forced delta against previous mode. # Forced delta against previous mode.
if deltamode == repository.CG_DELTAMODE_PREV: if deltamode == repository.CG_DELTAMODE_PREV:
if debug_info is not None:
debug_delta_source = "prev"
baserev = prevrev baserev = prevrev
# We're instructed to send fulltext. Honor that. # We're instructed to send fulltext. Honor that.
elif deltamode == repository.CG_DELTAMODE_FULL: elif deltamode == repository.CG_DELTAMODE_FULL:
...@@ -408,7 +429,9 @@ ...@@ -408,7 +429,9 @@
baserev = prevrev baserev = prevrev
# We're instructed to send fulltext. Honor that. # We're instructed to send fulltext. Honor that.
elif deltamode == repository.CG_DELTAMODE_FULL: elif deltamode == repository.CG_DELTAMODE_FULL:
if debug_info is not None:
debug_delta_source = "full"
baserev = nullrev baserev = nullrev
# We're instructed to use p1. Honor that # We're instructed to use p1. Honor that
elif deltamode == repository.CG_DELTAMODE_P1: elif deltamode == repository.CG_DELTAMODE_P1:
...@@ -412,6 +435,8 @@ ...@@ -412,6 +435,8 @@
baserev = nullrev baserev = nullrev
# We're instructed to use p1. Honor that # We're instructed to use p1. Honor that
elif deltamode == repository.CG_DELTAMODE_P1: elif deltamode == repository.CG_DELTAMODE_P1:
if debug_info is not None:
debug_delta_source = "p1"
baserev = p1rev baserev = p1rev
# There is a delta in storage. We try to use that because it # There is a delta in storage. We try to use that because it
...@@ -421,8 +446,10 @@ ...@@ -421,8 +446,10 @@
# Base revision was already emitted in this group. We can # Base revision was already emitted in this group. We can
# always safely use the delta. # always safely use the delta.
if deltaparentrev in available: if deltaparentrev in available:
if debug_info is not None:
debug_delta_source = "storage"
baserev = deltaparentrev baserev = deltaparentrev
# Base revision is a parent that hasn't been emitted already. # Base revision is a parent that hasn't been emitted already.
# Use it if we can assume the receiver has the parent revision. # Use it if we can assume the receiver has the parent revision.
elif assumehaveparentrevisions and deltaparentrev in (p1rev, p2rev): elif assumehaveparentrevisions and deltaparentrev in (p1rev, p2rev):
...@@ -424,6 +451,8 @@ ...@@ -424,6 +451,8 @@
baserev = deltaparentrev baserev = deltaparentrev
# Base revision is a parent that hasn't been emitted already. # Base revision is a parent that hasn't been emitted already.
# Use it if we can assume the receiver has the parent revision. # Use it if we can assume the receiver has the parent revision.
elif assumehaveparentrevisions and deltaparentrev in (p1rev, p2rev): elif assumehaveparentrevisions and deltaparentrev in (p1rev, p2rev):
if debug_info is not None:
debug_delta_source = "storage"
baserev = deltaparentrev baserev = deltaparentrev
...@@ -429,7 +458,6 @@ ...@@ -429,7 +458,6 @@
baserev = deltaparentrev baserev = deltaparentrev
# No guarantee the receiver has the delta parent. Send delta # No guarantee the receiver has the delta parent. Send delta
# against last revision (if possible), which in the common case # against last revision (if possible), which in the common case
# should be similar enough to this revision that the delta is # should be similar enough to this revision that the delta is
# reasonable. # reasonable.
elif prevrev is not None: elif prevrev is not None:
...@@ -431,7 +459,10 @@ ...@@ -431,7 +459,10 @@
# No guarantee the receiver has the delta parent. Send delta # No guarantee the receiver has the delta parent. Send delta
# against last revision (if possible), which in the common case # against last revision (if possible), which in the common case
# should be similar enough to this revision that the delta is # should be similar enough to this revision that the delta is
# reasonable. # reasonable.
elif prevrev is not None: elif prevrev is not None:
if debug_info is not None:
debug_info['denied-base-not-available'] += 1
debug_delta_source = "prev"
baserev = prevrev baserev = prevrev
else: else:
...@@ -436,5 +467,8 @@ ...@@ -436,5 +467,8 @@
baserev = prevrev baserev = prevrev
else: else:
if debug_info is not None:
debug_info['denied-base-not-available'] += 1
debug_delta_source = "full"
baserev = nullrev baserev = nullrev
# Storage has a fulltext revision. # Storage has a fulltext revision.
...@@ -442,5 +476,7 @@ ...@@ -442,5 +476,7 @@
# Let's use the previous revision, which is as good a guess as any. # Let's use the previous revision, which is as good a guess as any.
# There is definitely room to improve this logic. # There is definitely room to improve this logic.
elif prevrev is not None: elif prevrev is not None:
if debug_info is not None:
debug_delta_source = "prev"
baserev = prevrev baserev = prevrev
else: else:
...@@ -445,6 +481,8 @@ ...@@ -445,6 +481,8 @@
baserev = prevrev baserev = prevrev
else: else:
if debug_info is not None:
debug_delta_source = "full"
baserev = nullrev baserev = nullrev
# But we can't actually use our chosen delta base for whatever # But we can't actually use our chosen delta base for whatever
# reason. Reset to fulltext. # reason. Reset to fulltext.
...@@ -447,8 +485,15 @@ ...@@ -447,8 +485,15 @@
baserev = nullrev baserev = nullrev
# But we can't actually use our chosen delta base for whatever # But we can't actually use our chosen delta base for whatever
# reason. Reset to fulltext. # reason. Reset to fulltext.
if baserev != nullrev and (candeltafn and not candeltafn(baserev, rev)): if (
baserev != nullrev
and candeltafn is not None
and not candeltafn(baserev, rev)
):
if debug_info is not None:
debug_delta_source = "full"
debug_info['denied-delta-candeltafn'] += 1
baserev = nullrev baserev = nullrev
revision = None revision = None
...@@ -460,6 +505,9 @@ ...@@ -460,6 +505,9 @@
try: try:
revision = store.rawdata(node) revision = store.rawdata(node)
except error.CensoredNodeError as e: except error.CensoredNodeError as e:
if debug_info is not None:
debug_delta_source = "full"
debug_info['denied-delta-not-available'] += 1
revision = e.tombstone revision = e.tombstone
if baserev != nullrev: if baserev != nullrev:
...@@ -471,7 +519,10 @@ ...@@ -471,7 +519,10 @@
elif ( elif (
baserev == nullrev and deltamode != repository.CG_DELTAMODE_PREV baserev == nullrev and deltamode != repository.CG_DELTAMODE_PREV
): ):
if debug_info is not None:
debug_info['computed-delta'] += 1 # close enough
debug_info['delta-full'] += 1
revision = store.rawdata(node) revision = store.rawdata(node)
available.add(rev) available.add(rev)
else: else:
if revdifffn: if revdifffn:
...@@ -474,6 +525,21 @@ ...@@ -474,6 +525,21 @@
revision = store.rawdata(node) revision = store.rawdata(node)
available.add(rev) available.add(rev)
else: else:
if revdifffn: if revdifffn:
if debug_info is not None:
if debug_delta_source == "full":
debug_info['computed-delta'] += 1
debug_info['delta-full'] += 1
elif debug_delta_source == "prev":
debug_info['computed-delta'] += 1
debug_info['delta-against-prev'] += 1
elif debug_delta_source == "p1":
debug_info['computed-delta'] += 1
debug_info['delta-against-p1'] += 1
elif debug_delta_source == "storage":
debug_info['reused-storage-delta'] += 1
else:
assert False, 'unreachable'
delta = revdifffn(baserev, rev) delta = revdifffn(baserev, rev)
else: else:
...@@ -478,5 +544,21 @@ ...@@ -478,5 +544,21 @@
delta = revdifffn(baserev, rev) delta = revdifffn(baserev, rev)
else: else:
if debug_info is not None:
if debug_delta_source == "full":
debug_info['computed-delta'] += 1
debug_info['delta-full'] += 1
elif debug_delta_source == "prev":
debug_info['computed-delta'] += 1
debug_info['delta-against-prev'] += 1
elif debug_delta_source == "p1":
debug_info['computed-delta'] += 1
debug_info['delta-against-p1'] += 1
elif debug_delta_source == "storage":
# seem quite unlikelry to happens
debug_info['computed-delta'] += 1
debug_info['reused-storage-delta'] += 1
else:
assert False, 'unreachable'
delta = mdiff.textdiff( delta = mdiff.textdiff(
store.rawdata(baserev), store.rawdata(rev) store.rawdata(baserev), store.rawdata(rev)
) )
......
...@@ -1039,6 +1039,24 @@ ...@@ -1039,6 +1039,24 @@
$ hg bundle -a --config devel.bundle.delta=full ./full.hg $ hg bundle -a --config devel.bundle.delta=full ./full.hg
3 changesets found 3 changesets found
Test the debug statistic when building a bundle
-----------------------------------------------
$ hg bundle -a ./default.hg --config debug.bundling-stats=yes
3 changesets found
DEBUG-BUNDLING: revisions: 9
DEBUG-BUNDLING: changelog: 3
DEBUG-BUNDLING: manifest: 3
DEBUG-BUNDLING: files: 3 (for 3 revlogs)
DEBUG-BUNDLING: deltas:
DEBUG-BUNDLING: from-storage: 2 (100% of available 2)
DEBUG-BUNDLING: computed: 7
DEBUG-BUNDLING: full: 7 (100% of native 7)
DEBUG-BUNDLING: changelog: 3 (100% of native 3)
DEBUG-BUNDLING: manifests: 1 (100% of native 1)
DEBUG-BUNDLING: files: 3 (100% of native 3)
Test the debug output when applying delta Test the debug output when applying delta
----------------------------------------- -----------------------------------------
...@@ -1048,7 +1066,7 @@ ...@@ -1048,7 +1066,7 @@
> --config storage.revlog.reuse-external-delta=no \ > --config storage.revlog.reuse-external-delta=no \
> --config storage.revlog.reuse-external-delta-parent=no > --config storage.revlog.reuse-external-delta-parent=no
adding changesets adding changesets
DBG-DELTAS: CHANGELOG: rev=0: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: CHANGELOG: rev=0: delta-base=0 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob)
DBG-DELTAS: CHANGELOG: rev=1: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=0 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: CHANGELOG: rev=1: delta-base=1 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=0 p2-chain-length=-1 - duration=* (glob)
DBG-DELTAS: CHANGELOG: rev=2: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=0 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: CHANGELOG: rev=2: delta-base=2 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=0 p2-chain-length=-1 - duration=* (glob)
adding manifests adding manifests
...@@ -1054,5 +1072,5 @@ ...@@ -1054,5 +1072,5 @@
adding manifests adding manifests
DBG-DELTAS: MANIFESTLOG: rev=0: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: MANIFESTLOG: rev=0: delta-base=0 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob)
DBG-DELTAS: MANIFESTLOG: rev=1: search-rounds=1 try-count=1 - delta-type=delta snap-depth=0 - p1-chain-length=0 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: MANIFESTLOG: rev=1: delta-base=0 is-cached=1 - search-rounds=1 try-count=1 - delta-type=delta snap-depth=0 - p1-chain-length=0 p2-chain-length=-1 - duration=* (glob)
DBG-DELTAS: MANIFESTLOG: rev=2: search-rounds=1 try-count=1 - delta-type=delta snap-depth=0 - p1-chain-length=1 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: MANIFESTLOG: rev=2: delta-base=1 is-cached=1 - search-rounds=1 try-count=1 - delta-type=delta snap-depth=0 - p1-chain-length=1 p2-chain-length=-1 - duration=* (glob)
adding file changes adding file changes
...@@ -1058,8 +1076,8 @@ ...@@ -1058,8 +1076,8 @@
adding file changes adding file changes
DBG-DELTAS: FILELOG:a: rev=0: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:a: rev=0: delta-base=0 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob)
DBG-DELTAS: FILELOG:b: rev=0: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:b: rev=0: delta-base=0 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob)
DBG-DELTAS: FILELOG:c: rev=0: search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:c: rev=0: delta-base=0 is-cached=0 - search-rounds=0 try-count=0 - delta-type=full snap-depth=0 - p1-chain-length=-1 p2-chain-length=-1 - duration=* (glob)
added 3 changesets with 3 changes to 3 files added 3 changesets with 3 changes to 3 files
new changesets 4fe08cd4693e:4652c276ac4f (3 drafts) new changesets 4fe08cd4693e:4652c276ac4f (3 drafts)
(run 'hg update' to get a working copy) (run 'hg update' to get a working copy)
...@@ -1062,4 +1080,48 @@ ...@@ -1062,4 +1080,48 @@
added 3 changesets with 3 changes to 3 files added 3 changesets with 3 changes to 3 files
new changesets 4fe08cd4693e:4652c276ac4f (3 drafts) new changesets 4fe08cd4693e:4652c276ac4f (3 drafts)
(run 'hg update' to get a working copy) (run 'hg update' to get a working copy)
Test the debug statistic when applying a bundle
-----------------------------------------------
$ hg init bar
$ hg -R bar unbundle ./default.hg --config debug.unbundling-stats=yes
adding changesets
adding manifests
adding file changes
DEBUG-UNBUNDLING: revisions: 9
DEBUG-UNBUNDLING: changelog: 3 ( 33%)
DEBUG-UNBUNDLING: manifests: 3 ( 33%)
DEBUG-UNBUNDLING: files: 3 ( 33%)
DEBUG-UNBUNDLING: total-time: ?????????????? seconds (glob)
DEBUG-UNBUNDLING: changelog: ?????????????? seconds (???%) (glob)
DEBUG-UNBUNDLING: manifests: ?????????????? seconds (???%) (glob)
DEBUG-UNBUNDLING: files: ?????????????? seconds (???%) (glob)
DEBUG-UNBUNDLING: type-count:
DEBUG-UNBUNDLING: changelog:
DEBUG-UNBUNDLING: full: 3
DEBUG-UNBUNDLING: cached: 0 ( 0%)
DEBUG-UNBUNDLING: manifests:
DEBUG-UNBUNDLING: full: 1
DEBUG-UNBUNDLING: cached: 0 ( 0%)
DEBUG-UNBUNDLING: delta: 2
DEBUG-UNBUNDLING: cached: 2 (100%)
DEBUG-UNBUNDLING: files:
DEBUG-UNBUNDLING: full: 3
DEBUG-UNBUNDLING: cached: 0 ( 0%)
DEBUG-UNBUNDLING: type-time:
DEBUG-UNBUNDLING: changelog:
DEBUG-UNBUNDLING: full: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: cached: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: manifests:
DEBUG-UNBUNDLING: full: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: cached: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: delta: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: cached: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: files:
DEBUG-UNBUNDLING: full: ?????????????? seconds (???% of total) (glob)
DEBUG-UNBUNDLING: cached: ?????????????? seconds (???% of total) (glob)
added 3 changesets with 3 changes to 3 files
new changesets 4fe08cd4693e:4652c276ac4f (3 drafts)
(run 'hg update' to get a working copy)
...@@ -159,7 +159,7 @@ ...@@ -159,7 +159,7 @@
4971 4970 -1 3 5 4930 snap 19179 346472 427596 1.23414 15994877 15567281 36.40652 427596 179288 1.00000 5 4971 4970 -1 3 5 4930 snap 19179 346472 427596 1.23414 15994877 15567281 36.40652 427596 179288 1.00000 5
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down DBG-DELTAS-SEARCH: ROUND #1 - 1 candidates - search-down
DBG-DELTAS-SEARCH: CANDIDATE: rev=4962 DBG-DELTAS-SEARCH: CANDIDATE: rev=4962
DBG-DELTAS-SEARCH: type=snapshot-4 DBG-DELTAS-SEARCH: type=snapshot-4
DBG-DELTAS-SEARCH: size=18296 DBG-DELTAS-SEARCH: size=18296
...@@ -167,11 +167,6 @@ ...@@ -167,11 +167,6 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=30377 DBG-DELTAS-SEARCH: uncompressed-delta-size=30377
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=16872 (BAD) DBG-DELTAS-SEARCH: DELTA: length=16872 (BAD)
DBG-DELTAS-SEARCH: CANDIDATE: rev=4971
DBG-DELTAS-SEARCH: type=snapshot-4
DBG-DELTAS-SEARCH: size=19179
DBG-DELTAS-SEARCH: base=4930
DBG-DELTAS-SEARCH: TOO-HIGH
DBG-DELTAS-SEARCH: ROUND #2 - 1 candidates - search-down DBG-DELTAS-SEARCH: ROUND #2 - 1 candidates - search-down
DBG-DELTAS-SEARCH: CANDIDATE: rev=4930 DBG-DELTAS-SEARCH: CANDIDATE: rev=4930
DBG-DELTAS-SEARCH: type=snapshot-3 DBG-DELTAS-SEARCH: type=snapshot-3
...@@ -189,7 +184,7 @@ ...@@ -189,7 +184,7 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=82661 DBG-DELTAS-SEARCH: uncompressed-delta-size=82661
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD) DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD)
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=0 - search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ cat << EOF >>.hg/hgrc $ cat << EOF >>.hg/hgrc
> [storage] > [storage]
...@@ -198,7 +193,7 @@ ...@@ -198,7 +193,7 @@
> EOF > EOF
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --quiet $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --quiet
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=0 - search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source full $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source full
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down
...@@ -231,6 +226,6 @@ ...@@ -231,6 +226,6 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=82661 DBG-DELTAS-SEARCH: uncompressed-delta-size=82661
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD) DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD)
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=0 - search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source storage $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source storage
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
...@@ -235,6 +230,6 @@ ...@@ -235,6 +230,6 @@
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source storage $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source storage
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
DBG-DELTAS-SEARCH: ROUND #1 - 1 candidates - search-down DBG-DELTAS-SEARCH: ROUND #1 - 1 candidates - cached-delta
DBG-DELTAS-SEARCH: CANDIDATE: rev=4930 DBG-DELTAS-SEARCH: CANDIDATE: rev=4930
DBG-DELTAS-SEARCH: type=snapshot-3 DBG-DELTAS-SEARCH: type=snapshot-3
DBG-DELTAS-SEARCH: size=39228 DBG-DELTAS-SEARCH: size=39228
...@@ -242,7 +237,7 @@ ...@@ -242,7 +237,7 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=33050 DBG-DELTAS-SEARCH: uncompressed-delta-size=33050
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=19179 (GOOD) DBG-DELTAS-SEARCH: DELTA: length=19179 (GOOD)
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=1 try-count=1 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=1 - search-rounds=1 try-count=1 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source p1 $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source p1
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down
...@@ -275,7 +270,7 @@ ...@@ -275,7 +270,7 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=82661 DBG-DELTAS-SEARCH: uncompressed-delta-size=82661
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD) DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD)
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=0 - search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source p2 $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source p2
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down
...@@ -308,7 +303,7 @@ ...@@ -308,7 +303,7 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=82661 DBG-DELTAS-SEARCH: uncompressed-delta-size=82661
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD) DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD)
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=0 - search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source prev $ hg debug-delta-find SPARSE-REVLOG-TEST-FILE 4971 --source prev
DBG-DELTAS-SEARCH: SEARCH rev=4971 DBG-DELTAS-SEARCH: SEARCH rev=4971
DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down DBG-DELTAS-SEARCH: ROUND #1 - 2 candidates - search-down
...@@ -341,6 +336,6 @@ ...@@ -341,6 +336,6 @@
DBG-DELTAS-SEARCH: uncompressed-delta-size=82661 DBG-DELTAS-SEARCH: uncompressed-delta-size=82661
DBG-DELTAS-SEARCH: delta-search-time=* (glob) DBG-DELTAS-SEARCH: delta-search-time=* (glob)
DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD) DBG-DELTAS-SEARCH: DELTA: length=49132 (BAD)
DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob) DBG-DELTAS: FILELOG:SPARSE-REVLOG-TEST-FILE: rev=4971: delta-base=4930 is-cached=0 - search-rounds=3 try-count=3 - delta-type=snapshot snap-depth=4 - p1-chain-length=15 p2-chain-length=-1 - duration=* (glob)
$ cd .. $ cd ..