view tests/test-import-eol.t @ 42743:8c9a6adec67a

rust-discovery: using the children cache in add_missing The DAG range computation often needs to get back to very old revisions, and turns out to be disproportionately long, given that the end goal is to remove the descendents of the given missing revisons from the undecided set. The fast iteration capabilities available in the Rust case make it possible to avoid the DAG range entirely, at the cost of precomputing the children cache, and to simply iterate on children of the given missing revisions. This is a case where staying on the same side of the interface between the two languages has clear benefits. On discoveries with initial undecided sets small enough to bypass sampling entirely, the total cost of computing the children cache and the subsequent iteration becomes better than the Python + C counterpart, which relies on reachableroots2. For example, on a repo with more than one million revisions with an initial undecided set of 11 elements, we get these figures: Rust version with simple iteration addcommons: 57.287us first undecided computation: 184.278334ms first children cache computation: 131.056us addmissings iteration: 42.766us first addinfo total: 185.24 ms Python + C version first addcommons: 0.29 ms addcommons 0.21 ms first undecided computation 191.35 ms addmissings 45.75 ms first addinfo total: 237.77 ms On discoveries with large undecided sets, the initial price paid makes the first addinfo slower than the Python + C version, but that's more than compensated by the gain in sampling and subsequent iterations. Here's an extreme example with an undecided set of a million revisions: Rust version: first undecided computation: 293.842629ms first children cache computation: 407.911297ms addmissings iteration: 34.312869ms first addinfo total: 776.02 ms taking initial sample query 2: sampling time: 1318.38 ms query 2; still undecided: 1005013, sample size is: 200 addmissings: 143.062us Python + C version: first undecided computation 298.13 ms addmissings 80.13 ms first addinfo total: 399.62 ms taking initial sample query 2: sampling time: 3957.23 ms query 2; still undecided: 1005013, sample size is: 200 addmissings 52.88 ms Differential Revision: https://phab.mercurial-scm.org/D6428
author Georges Racinet <georges.racinet@octobus.net>
date Tue, 16 Apr 2019 01:16:39 +0200
parents 140b542b0e59
children
line wrap: on
line source

  $ cat > makepatch.py <<EOF
  > import sys
  > f = open(sys.argv[2], 'wb')
  > w = f.write
  > w(b'test message\n')
  > w(b'diff --git a/a b/a\n')
  > w(b'--- a/a\n')
  > w(b'+++ b/a\n')
  > w(b'@@ -1,5 +1,5 @@\n')
  > w(b' a\n')
  > w(b'-bbb\r\n')
  > w(b'+yyyy\r\n')
  > w(b' cc\r\n')
  > w({'empty:lf': b' \n',
  >    'empty:crlf': b' \r\n',
  >    'empty:stripped-lf': b'\n',
  >    'empty:stripped-crlf': b'\r\n'}[sys.argv[1]])
  > w(b' d\n')
  > w(b'-e\n')
  > w(b'\\\\ No newline at end of file\n')
  > w(b'+z\r\n')
  > w(b'\\\\ No newline at end of file\r\n')
  > EOF

  $ hg init repo
  $ cd repo
  $ echo '\.diff' > .hgignore


Test different --eol values

  $ "$PYTHON" -c 'open("a", "wb").write(b"a\nbbb\ncc\n\nd\ne")'
  $ hg ci -Am adda
  adding .hgignore
  adding a
  $ "$PYTHON" ../makepatch.py empty:lf eol.diff
  $ "$PYTHON" ../makepatch.py empty:crlf eol-empty-crlf.diff
  $ "$PYTHON" ../makepatch.py empty:stripped-lf eol-empty-stripped-lf.diff
  $ "$PYTHON" ../makepatch.py empty:stripped-crlf eol-empty-stripped-crlf.diff

invalid eol

  $ hg --config patch.eol='LFCR' import eol.diff
  applying eol.diff
  abort: unsupported line endings type: LFCR
  [255]
  $ hg revert -a


force LF

  $ hg --traceback --config patch.eol='LF' import eol.diff
  applying eol.diff
  $ hg id
  9e4ef7b3d4af tip
  $ cat a
  a
  yyyy
  cc
  
  d
  e (no-eol)
  $ hg st

 (test empty-line variants: all of them should generate the same revision)

  $ hg up -qC 0
  $ hg --config patch.eol='LF' import eol-empty-crlf.diff
  applying eol-empty-crlf.diff
  $ hg id
  9e4ef7b3d4af tip

  $ hg up -qC 0
  $ hg --config patch.eol='LF' import eol-empty-stripped-lf.diff
  applying eol-empty-stripped-lf.diff
  $ hg id
  9e4ef7b3d4af tip

  $ hg up -qC 0
  $ hg --config patch.eol='LF' import eol-empty-stripped-crlf.diff
  applying eol-empty-stripped-crlf.diff
  $ hg id
  9e4ef7b3d4af tip

force CRLF

  $ hg up -C 0
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  $ hg --traceback --config patch.eol='CRLF' import eol.diff
  applying eol.diff
  $ cat a
  a\r (esc)
  yyyy\r (esc)
  cc\r (esc)
  \r (esc)
  d\r (esc)
  e (no-eol)
  $ hg st


auto EOL on LF file

  $ hg up -C 0
  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  $ hg --traceback --config patch.eol='auto' import eol.diff
  applying eol.diff
  $ cat a
  a
  yyyy
  cc
  
  d
  e (no-eol)
  $ hg st


auto EOL on CRLF file

  $ "$PYTHON" -c 'open("a", "wb").write(b"a\r\nbbb\r\ncc\r\n\r\nd\r\ne")'
  $ hg commit -m 'switch EOLs in a'
  $ hg --traceback --config patch.eol='auto' import eol.diff
  applying eol.diff
  $ cat a
  a\r (esc)
  yyyy\r (esc)
  cc\r (esc)
  \r (esc)
  d\r (esc)
  e (no-eol)
  $ hg st


auto EOL on new file or source without any EOL

  $ "$PYTHON" -c 'open("noeol", "wb").write(b"noeol")'
  $ hg add noeol
  $ hg commit -m 'add noeol'
  $ "$PYTHON" -c 'open("noeol", "wb").write(b"noeol\r\nnoeol\n")'
  $ "$PYTHON" -c 'open("neweol", "wb").write(b"neweol\nneweol\r\n")'
  $ hg add neweol
  $ hg diff --git > noeol.diff
  $ hg revert --no-backup noeol neweol
  $ rm neweol
  $ hg --traceback --config patch.eol='auto' import -m noeol noeol.diff
  applying noeol.diff
  $ cat noeol
  noeol\r (esc)
  noeol
  $ cat neweol
  neweol
  neweol\r (esc)
  $ hg st


Test --eol and binary patches

  $ "$PYTHON" -c 'open("b", "wb").write(b"a\x00\nb\r\nd")'
  $ hg ci -Am addb
  adding b
  $ "$PYTHON" -c 'open("b", "wb").write(b"a\x00\nc\r\nd")'
  $ hg diff --git > bin.diff
  $ hg revert --no-backup b

binary patch with --eol

  $ hg import --config patch.eol='CRLF' -m changeb bin.diff
  applying bin.diff
  $ cat b
  a\x00 (esc)
  c\r (esc)
  d (no-eol)
  $ hg st
  $ cd ..