Mercurial > hg
annotate mercurial/diffhelper.py @ 51594:e3a5ec2d236a
outgoing: rework the handling of the `missingroots` case to be faster
The previous implementation was slow, to the point it was taking a significant
amount of `hg bundle --type none-streamv2` call. We rework the code to compute
the same value much faster, making the operation disappear from the `hg bundle
--type none-streamv2` profile. Someone would remark that producing a streamclone
does not requires an `outgoing` object. However that is a matter for another
day. There is other user of `missingroots` (non stream `hg bundle` call for
example), and they will also benefit from this rework.
We implement an old TODO in the process, directly computing the missing and
common attribute as we have most element at hand already.
### benchmark.name = hg.command.bundle
# bin-env-vars.hg.flavor = default
# bin-env-vars.hg.py-re2-module = default
# benchmark.variants.revs = all
# benchmark.variants.type = none-streamv2
## data-env-vars.name = heptapod-public-2024-03-25-zstd-sparse-revlog
before: 7.750458
after: 6.665565 (-14.00%, -1.08)
## data-env-vars.name = mercurial-public-2024-03-22-zstd-sparse-revlog
before: 0.700229
after: 0.496050 (-29.16%, -0.20)
## data-env-vars.name = mozilla-try-2023-03-22-zstd-sparse-revlog
before: 346.508952
after: 316.749699 (-8.59%, -29.76)
## data-env-vars.name = pypy-2024-03-22-zstd-sparse-revlog
before: 3.401700
after: 2.915810 (-14.28%, -0.49)
## data-env-vars.name = tryton-public-2024-03-22-zstd-sparse-revlog
before: 1.870798
after: 1.461583 (-21.87%, -0.41)
note: this whole `missingroots` of outgoing has a limited number of callers and
could likely be replace by something simpler (like taking an explicit
"missing_revs" set for example). However this is a wider change and we focus on
a small impact, quick rework that does not change the API for now.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 09 Apr 2024 22:36:35 +0200 |
parents | d44e3c45f0e4 |
children | f4733654f144 |
rev | line source |
---|---|
37803
72f6498c040b
diffhelper: rename module to avoid conflicts with ancient C module (issue5846)
Yuya Nishihara <yuya@tcha.org>
parents:
37802
diff
changeset
|
1 # diffhelper.py - helper routines for patch |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
2 # |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
45154
diff
changeset
|
3 # Copyright 2009 Olivia Mackall <olivia@selenic.com> and others |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7702
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
7 |
27336
80214358ac88
diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
12387
diff
changeset
|
8 |
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
9 from .i18n import _ |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
10 |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
11 from . import ( |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
12 error, |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
13 ) |
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
14 |
45154
10f48720ef95
diff: move no-eol text constant to a common location
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents:
43077
diff
changeset
|
15 MISSING_NEWLINE_MARKER = b'\\ No newline at end of file\n' |
10f48720ef95
diff: move no-eol text constant to a common location
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents:
43077
diff
changeset
|
16 |
43075
57875cf423c9
style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents:
38783
diff
changeset
|
17 |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
18 def addlines(fp, hunk, lena, lenb, a, b): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
19 """Read lines from fp into the hunk |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
20 |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
21 The hunk is parsed into two arrays, a and b. a gets the old state of |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
22 the text, b gets the new state. The control char from the hunk is saved |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
23 when inserting into a, but not b (for performance while deleting files.) |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
24 """ |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
25 while True: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
26 todoa = lena - len(a) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
27 todob = lenb - len(b) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
28 num = max(todoa, todob) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
29 if num == 0: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
30 break |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48875
diff
changeset
|
31 for i in range(num): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
32 s = fp.readline() |
37573
49b82cdb5983
patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents:
37572
diff
changeset
|
33 if not s: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
34 raise error.ParseError(_(b'incomplete hunk')) |
45154
10f48720ef95
diff: move no-eol text constant to a common location
Rodrigo Damazio Bovendorp <rdamazio@google.com>
parents:
43077
diff
changeset
|
35 if s == MISSING_NEWLINE_MARKER: |
37570
c4c8d0d1267f
diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents:
37567
diff
changeset
|
36 fixnewline(hunk, a, b) |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
37 continue |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
38 if s == b'\n' or s == b'\r\n': |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
39 # Some patches may be missing the control char |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
40 # on empty lines. Supply a leading space. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
41 s = b' ' + s |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
42 hunk.append(s) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
43 if s.startswith(b'+'): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
44 b.append(s[1:]) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
45 elif s.startswith(b'-'): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
46 a.append(s) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
47 else: |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
48 b.append(s[1:]) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
49 a.append(s) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
50 |
43075
57875cf423c9
style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents:
38783
diff
changeset
|
51 |
37570
c4c8d0d1267f
diffhelpers: naming and whitespace cleanup
Yuya Nishihara <yuya@tcha.org>
parents:
37567
diff
changeset
|
52 def fixnewline(hunk, a, b): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
53 """Fix up the last lines of a and b when the patch has no newline at EOF""" |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
54 l = hunk[-1] |
10551
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
55 # tolerate CRLF in last line |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
56 if l.endswith(b'\r\n'): |
10551
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
57 hline = l[:-2] |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
58 else: |
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
59 hline = l[:-1] |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
60 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
61 if hline.startswith((b' ', b'+')): |
10551
f61dced1367a
fix test-mq-eol under --pure (mimic diffhelper.c behaviour)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
10263
diff
changeset
|
62 b[-1] = hline[1:] |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43075
diff
changeset
|
63 if hline.startswith((b' ', b'-')): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
64 a[-1] = hline |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
65 hunk[-1] = hline |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
66 |
43075
57875cf423c9
style: run a patched black on a subset of mercurial
Augie Fackler <augie@google.com>
parents:
38783
diff
changeset
|
67 |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
68 def testhunk(a, b, bstart): |
37567
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
69 """Compare the lines in a with the lines in b |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
70 |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
71 a is assumed to have a control char at the start of each line, this char |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
72 is ignored in the compare. |
53021c4ef0b2
diffhelpers: port docstrings from cext to pure
Yuya Nishihara <yuya@tcha.org>
parents:
37566
diff
changeset
|
73 """ |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
74 alen = len(a) |
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
75 blen = len(b) |
37802
090c89a8db32
diffhelpers: backport 9e40bc4c1bde from C implementation
Yuya Nishihara <yuya@tcha.org>
parents:
37575
diff
changeset
|
76 if alen > blen - bstart or bstart < 0: |
37574
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
77 return False |
49284
d44e3c45f0e4
py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents:
48875
diff
changeset
|
78 for i in range(alen): |
7702
f6bb40554e34
pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
79 if a[i][1:] != b[i + bstart]: |
37574
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
80 return False |
a1bcc7ff0eac
diffhelpers: make return value of testhunk() more Pythonic
Yuya Nishihara <yuya@tcha.org>
parents:
37573
diff
changeset
|
81 return True |