Mercurial > hg
annotate mercurial/cffi/bdiff.py @ 50317:af776c3d5c3e stable
debugdeltachain: stop summing the same chain over and over
Before this patch, delta chain size was computed from scratch for each chain,
disregarding the fact very likely already computed the same of length-1 prefix
for another revisions.
We not cache delta chain size and shortcut the computation when we see them.
Just for my mercurial-devel clone, this move the computation from about 17.5
second to about 4.8 seconds.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 21 Mar 2023 15:44:38 +0000 |
parents | 594fc56c0af7 |
children | ecc3a893979d |
rev | line source |
---|---|
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
1 # bdiff.py - CFFI implementation of bdiff.c |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
2 # |
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
3 # Copyright 2016 Maciej Fijalkowski <fijall@gmail.com> |
7703
9044d3567f6d
pure Python implementation of bdiff.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:
7944
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. |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
7 |
27335
c4e3ff497f89
bdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
15530
diff
changeset
|
8 |
c4e3ff497f89
bdiff: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
15530
diff
changeset
|
9 import struct |
7944
e9b48afd0e78
pure/bdiff: fix circular import
Matt Mackall <mpm@selenic.com>
parents:
7703
diff
changeset
|
10 |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
11 from typing import ( |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
12 List, |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
13 Tuple, |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
14 ) |
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
15 |
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
16 from ..pure.bdiff import * |
46785
521ac0d7047f
typing: disable import error warnings that are already handled
Matt Harbison <matt_harbison@yahoo.com>
parents:
43077
diff
changeset
|
17 from . import _bdiff # pytype: disable=import-error |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
18 |
32512
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
19 ffi = _bdiff.ffi |
0e8b0b9a7acc
cffi: split modules from pure
Yuya Nishihara <yuya@tcha.org>
parents:
32506
diff
changeset
|
20 lib = _bdiff.lib |
7703
9044d3567f6d
pure Python implementation of bdiff.c
Martin Geisler <mg@daimi.au.dk>
parents:
diff
changeset
|
21 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
22 |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
23 def blocks(sa: bytes, sb: bytes) -> List[Tuple[int, int, int, int]]: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
24 a = ffi.new(b"struct bdiff_line**") |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
25 b = ffi.new(b"struct bdiff_line**") |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
26 ac = ffi.new(b"char[]", str(sa)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
27 bc = ffi.new(b"char[]", str(sb)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
28 l = ffi.new(b"struct bdiff_hunk*") |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
29 try: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
30 an = lib.bdiff_splitlines(ac, len(sa), a) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
31 bn = lib.bdiff_splitlines(bc, len(sb), b) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
32 if not a[0] or not b[0]: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
33 raise MemoryError |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
34 count = lib.bdiff_diff(a[0], an, b[0], bn, l) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
35 if count < 0: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
36 raise MemoryError |
49597
b2666e767029
cffi: adjust the list returned by bdiff.blocks to never have a None entry
Matt Harbison <matt_harbison@yahoo.com>
parents:
48875
diff
changeset
|
37 rl = [(0, 0, 0, 0)] * count |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
38 h = l.next |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
39 i = 0 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
40 while h: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
41 rl[i] = (h.a1, h.a2, h.b1, h.b2) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
42 h = h.next |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
43 i += 1 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
44 finally: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
45 lib.free(a[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
46 lib.free(b[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
47 lib.bdiff_freehunks(l.next) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
48 return rl |
29834
1ea77b75d266
bdiff: implement cffi version of bdiff
Maciej Fijalkowski <fijall@gmail.com>
parents:
29833
diff
changeset
|
49 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
50 |
49598
594fc56c0af7
typing: add type hints to bdiff implementations
Matt Harbison <matt_harbison@yahoo.com>
parents:
49597
diff
changeset
|
51 def bdiff(sa: bytes, sb: bytes) -> bytes: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
52 a = ffi.new(b"struct bdiff_line**") |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
53 b = ffi.new(b"struct bdiff_line**") |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
54 ac = ffi.new(b"char[]", str(sa)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
55 bc = ffi.new(b"char[]", str(sb)) |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
56 l = ffi.new(b"struct bdiff_hunk*") |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
57 try: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
58 an = lib.bdiff_splitlines(ac, len(sa), a) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
59 bn = lib.bdiff_splitlines(bc, len(sb), b) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
60 if not a[0] or not b[0]: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
61 raise MemoryError |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
62 count = lib.bdiff_diff(a[0], an, b[0], bn, l) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
63 if count < 0: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
64 raise MemoryError |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
65 rl = [] |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
66 h = l.next |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
67 la = lb = 0 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
68 while h: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
69 if h.a1 != la or h.b1 != lb: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
70 lgt = (b[0] + h.b1).l - (b[0] + lb).l |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
71 rl.append( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
72 struct.pack( |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
73 b">lll", |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
74 (a[0] + la).l - a[0].l, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
75 (a[0] + h.a1).l - a[0].l, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
76 lgt, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
77 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
33572
diff
changeset
|
78 ) |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
79 rl.append(str(ffi.buffer((b[0] + lb).l, lgt))) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
80 la = h.a2 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
81 lb = h.b2 |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
82 h = h.next |
29834
1ea77b75d266
bdiff: implement cffi version of bdiff
Maciej Fijalkowski <fijall@gmail.com>
parents:
29833
diff
changeset
|
83 |
32513
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
84 finally: |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
85 lib.free(a[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
86 lib.free(b[0]) |
25b37900d6e0
cffi: remove superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
32512
diff
changeset
|
87 lib.bdiff_freehunks(l.next) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
88 return b"".join(rl) |