mercurial/diffhelper.py
author Georges Racinet <georges.racinet@octobus.net>
Tue, 18 Feb 2020 19:11:15 +0100
changeset 44386 8f7c6656ac79
parent 43077 687b865b95ad
child 45154 10f48720ef95
permissions -rw-r--r--
rust-nodemap: pure Rust example To run, use `cargo run --release --example nodemap` This demonstrates that simple scenarios entirely written in Rust can content themselves with `NodeTree<T>`. The example mmaps both the nodemap file and the changelog index. We had of course to include an implementation of `RevlogIndex` directly, which isn't much at this stage. It felt a bit prematurate to include it in the lib. Here are some first performance measurements, obtained with this example, on a clone of mozilla-central with 440000 changesets: (create) Nodemap constructed in RAM in 153.638305ms (query CAE63161B68962) found in 22.362us: Ok(Some(269489)) (bench) Did 3 queries in 36.418µs (mean 12.139µs) (bench) Did 50 queries in 184.318µs (mean 3.686µs) (bench) Did 100000 queries in 31.053461ms (mean 310ns) To be fair, even between bench runs, results tend to depend whether the file is still in kernel caches, and it's not so easy to get back to a real cold start. The worst we've seen was in the 50us ballpark. In any busy server setting, the pages would always be in RAM. We hope it's good enough not to be significantly slower on any concrete Mercurial operation than the C nodetree when fully in RAM, and of course this implementation has the serious headstart advantage of persistence. Differential Revision: https://phab.mercurial-scm.org/D7797
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
#
f6bb40554e34 pure Python implementation of diffhelpers.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff changeset
     3
# Copyright 2009 Matt Mackall <mpm@selenic.com> and others
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 8225
diff changeset
     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
from __future__ import absolute_import
80214358ac88 diffhelpers: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 12387
diff changeset
     9
37573
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37572
diff changeset
    10
from .i18n import _
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37572
diff changeset
    11
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37572
diff changeset
    12
from . import (
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37572
diff changeset
    13
    error,
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37836
diff changeset
    14
    pycompat,
37573
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37572
diff changeset
    15
)
49b82cdb5983 patch: error out if reached to EOF while reading hunk
Yuya Nishihara <yuya@tcha.org>
parents: 37572
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
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37836
diff changeset
    31
        for i in pycompat.xrange(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'))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43075
diff changeset
    35
            if s == b"\\ No newline at end of file\n":
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
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 37836
diff changeset
    78
    for i in pycompat.xrange(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