##// END OF EJS Templates
match: match explicit file using a set...
match: match explicit file using a set The matcher as all the logic to do quick comparison against explicit patterns, however the pattern matcher was shadowing the code using that set and used the compiled regex pattern in all cases, which is quite slow. We restore the usage of the set based matching to boost performance. Building the regexp is still consuming a large amount of time (actually, the majority of the time), which is still silly. Maybe using re2 would help that, but this is a quest for another adventure. Another path to improve this is to have a pattern type dedicated to match the exact path to a file only (not a directory). This pattern could use the set matching only and be skipped in the regex all together. Benchmarks ========== In the following benchmark we are comparing the `hg cat` and `hg files` run time when matching against all files in the repository. They are run: - without the rust extensions - with the standard python engine (so without re2) Performance improvement in this series -------------------------------------- ###### hg files ############################################################### ### mercurial-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 0.230092 seconds prev-changeset: 0.230069 seconds this-changeset: 0.211425 seconds (-8.36%) ### mercurial-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 0.234235 seconds prev-changeset: 0.231165 seconds (-1.38%) this-changeset: 0.212300 seconds (-9.43%) ### pypy-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 0.613567 seconds prev-changeset: 0.616799 seconds this-changeset: 0.510852 seconds (-16.82%) ### pypy-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 0.801880 seconds prev-changeset: 0.616393 seconds (-23.22%) this-changeset: 0.511903 seconds (-36.23%) ### netbeans-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 21.541828 seconds prev-changeset: 21.586773 seconds this-changeset: 13.648347 seconds (-36.76%) ### netbeans-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 172.759857 seconds prev-changeset: 21.908197 seconds (-87.32%) this-changeset: 13.945110 seconds (-91.93%) ### mozilla-central-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 62.474221 seconds prev-changeset: 61.279490 seconds (-1.22%) this-changeset: 29.529469 seconds (-52.40%) ### mozilla-central-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 1364.180218 seconds prev-changeset: 62.473549 seconds (-95.40%) this-changeset: 30.625249 seconds (-97.75%) ###### hg cat ################################################################# ### mercurial-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 0.764407 seconds prev-changeset: 0.763883 seconds this-changeset: 0.737326 seconds (-3.68%) ### mercurial-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 0.768924 seconds prev-changeset: 0.765848 seconds this-changeset: 0.174d0b seconds (-4.44%) ### pypy-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 2.065220 seconds prev-changeset: 2.070498 seconds this-changeset: 1.939482 seconds (-6.08%) ### pypy-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 2.276388 seconds prev-changeset: 2.069197 seconds (-9.15%) this-changeset: 1.931746 seconds (-15.19%) ### netbeans-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 40.967983 seconds prev-changeset: 41.392423 seconds this-changeset: 32.181681 seconds (-22.20%) ### netbeans-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 216.388709 seconds prev-changeset: 41.648689 seconds (-80.88%) this-changeset: 32.580817 seconds (-85.04%) ### mozilla-central-2018-08-01-zstd-sparse-revlog ### sorted base-changeset: 105.228510 seconds prev-changeset: 103.315670 seconds (-1.23%) this-changeset: 69.416118 seconds (-33.64%) ### mozilla-central-2018-08-01-zstd-sparse-revlog ### shuffled base-changeset: 1448.722784 seconds prev-changeset: 104.369358 seconds (-92.80%) this-changeset: 70.554789 seconds (-95.13%) Different way to list the same data with this revision ------------------------------------------------------ ###### hg files ############################################################### ### mercurial-2018-08-01-zstd-sparse-revlog root: 0.119182 seconds glob: 0.120697 seconds (+1.27%) sorted: 0.211425 seconds (+77.40%) shuffled: 0.212300 seconds (+78.13%) ### pypy-2018-08-01-zstd-sparse-revlog root: 0.121986 seconds glob: 0.124822 seconds (+2.32%) sorted: 0.510852 seconds (+318.78%) shuffled: 0.511903 seconds (+319.64%) ### netbeans-2018-08-01-zstd-sparse-revlog root: 0.173984 seconds glob: 0.227203 seconds (+30.59%) sorted: 13.648347 seconds (+7744.59%) shuffled: 13.945110 seconds (+7915.16%) ### mozilla-central-2018-08-01-zstd-sparse-revlog root: 0.366463 seconds glob: 0.491030 seconds (+33.99%) sorted: 29.529469 seconds (+7957.96%) shuffled: 30.625249 seconds (+8256.97%) ###### hg cat ################################################################# ### mercurial-2018-08-01-zstd-sparse-revlog glob: 0.647471 seconds root: 0.643120 seconds shuffled: 0.174d0b seconds (+13.92%) sorted: 0.737326 seconds (+13.88%) ### mozilla-central-2018-08-01-zstd-sparse-revlog glob: 40.596983 seconds root: 40.129136 seconds shuffled: 70.554789 seconds (+73.79%) sorted: 69.416118 seconds (+70.99%) ### netbeans-2018-08-01-zstd-sparse-revlog glob: 18.777924 seconds root: 18.613905 seconds shuffled: 32.580817 seconds (+73.51%) sorted: 32.181681 seconds (+71.38%) ### pypy-2018-08-01-zstd-sparse-revlog glob: 1.555319 seconds root: 1.536534 seconds shuffled: 1.931746 seconds (+24.20%) sorted: 1.939482 seconds (+24.70%)

File last commit:

r47575:d4ba4d51 default
r51286:81c7d04f stable
Show More
bdiff.c
345 lines | 7.1 KiB | text/x-c | CLexer
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 /*
bdiff.c - efficient binary diff extension for Mercurial
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
This software may be used and distributed according to the terms of
the GNU General Public License, incorporated herein by reference.
Based roughly on Python difflib
*/
Augie Fackler
bdiff: sort includes using clang-format...
r34627 #include <limits.h>
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 #include <stdlib.h>
#include <string.h>
tksoh@users.sourceforge.net
Allow Mercurial to build on HP-UX 11...
r867
Augie Fackler
bdiff: sort includes using clang-format...
r34627 #include "bdiff.h"
#include "bitmanipulation.h"
Maciej Fijalkowski
bdiff: use ssize_t in favor of Py_ssize_t in cpython-unaware locations...
r29539 #include "compat.h"
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Gregory Szorc
bdiff: replace hash algorithm...
r30318 /* Hash implementation from diffutils */
#define ROL(v, n) ((v) << (n) | (v) >> (sizeof(v) * CHAR_BIT - (n)))
Augie Fackler
bdiff: fix misplaced comma in macro definition with clang-format...
r34629 #define HASH(h, c) ((c) + ROL(h, 7))
Gregory Szorc
bdiff: replace hash algorithm...
r30318
mpm@selenic.com
Minor speed improvements for bdiff...
r474 struct pos {
int pos, len;
};
Maciej Fijalkowski
bdiff: split bdiff into cpy-aware and cpy-agnostic part
r29541 int bdiff_splitlines(const char *a, ssize_t len, struct bdiff_line **lr)
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 {
Markus F.X.J. Oberhumer
bdiff.c: rename all variables which hold a hash value to "hash"
r13732 unsigned hash;
Markus F.X.J. Oberhumer
bdiff.c: use unsigned arithmetic for hash computation...
r13731 int i;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 const char *p, *b = a;
Augie Fackler
bdiff: remove extra space after * per clang-format...
r34630 const char *const plast = a + len - 1;
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 struct bdiff_line *l;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* count the lines */
i = 1; /* extra line for sentinel */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 for (p = a; p < plast; p++) {
if (*p == '\n') {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 i++;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
}
if (p == plast) {
Gregory Szorc
bdiff: don't check border condition in loop...
r30308 i++;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Alex Gaynor
bdiff: handle the possibility of an integer overflow when allocating...
r35695 *lr = l = (struct bdiff_line *)calloc(i, sizeof(struct bdiff_line));
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!l) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* build the line array and calculate hashes */
Markus F.X.J. Oberhumer
bdiff.c: rename all variables which hold a hash value to "hash"
r13732 hash = 0;
Gregory Szorc
bdiff: don't check border condition in loop...
r30461 for (p = a; p < plast; p++) {
Gregory Szorc
bdiff: replace hash algorithm...
r30318 hash = HASH(hash, *p);
Matt Mackall
bdiff: switch to lyhash...
r5342
Gregory Szorc
bdiff: don't check border condition in loop...
r30461 if (*p == '\n') {
Markus F.X.J. Oberhumer
bdiff.c: rename all variables which hold a hash value to "hash"
r13732 l->hash = hash;
hash = 0;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 l->len = p - b + 1;
l->l = b;
Matt Mackall
bdiff: use INT_MAX to avoid some inner loop comparisons
r5341 l->n = INT_MAX;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 l++;
b = p + 1;
}
}
Gregory Szorc
bdiff: don't check border condition in loop...
r30461 if (p == plast) {
hash = HASH(hash, *p);
l->hash = hash;
l->len = p - b + 1;
l->l = b;
l->n = INT_MAX;
l++;
}
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 /* set up a sentinel */
Markus F.X.J. Oberhumer
bdiff.c: rename all variables which hold a hash value to "hash"
r13732 l->hash = 0;
Markus F.X.J. Oberhumer
bdiff.c: use unsigned arithmetic for hash computation...
r13731 l->len = 0;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 l->l = a + len;
return i - 1;
}
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 static inline int cmp(struct bdiff_line *a, struct bdiff_line *b)
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 {
Augie Fackler
bdiff: re-wrap lines per clang-format...
r34631 return a->hash != b->hash || a->len != b->len ||
memcmp(a->l, b->l, a->len);
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 }
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 static int equatelines(struct bdiff_line *a, int an, struct bdiff_line *b,
Augie Fackler
bdiff: rewrap function prototypes per clang-format...
r34632 int bn)
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 {
Matt Mackall
bdiff: tweaks for large files...
r5452 int i, j, buckets = 1, t, scale;
struct pos *h = NULL;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* build a hash table of the next highest power of 2 */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 while (buckets < bn + 1) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 buckets *= 2;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Christoph Spiel
I have spotted the biggest bottleneck in "bdiff.c". Actually it was...
r5339 /* try to allocate a large hash table to avoid collisions */
Matt Mackall
bdiff: tweaks for large files...
r5452 for (scale = 4; scale; scale /= 2) {
Alex Gaynor
bdiff: handle the possibility of overflow when computing allocation size...
r35741 h = (struct pos *)calloc(buckets, scale * sizeof(struct pos));
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (h) {
Matt Mackall
bdiff: tweaks for large files...
r5452 break;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: tweaks for large files...
r5452 }
Christoph Spiel
I have spotted the biggest bottleneck in "bdiff.c". Actually it was...
r5339
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!h) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 return 0;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Christoph Spiel
I have spotted the biggest bottleneck in "bdiff.c". Actually it was...
r5339 buckets = buckets * scale - 1;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 /* clear the hash table */
mpm@selenic.com
Minor speed improvements for bdiff...
r474 for (i = 0; i <= buckets; i++) {
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 h[i].pos = -1;
mpm@selenic.com
Minor speed improvements for bdiff...
r474 h[i].len = 0;
}
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* add lines to the hash table chains */
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 for (i = 0; i < bn; i++) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 /* find the equivalence class */
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 for (j = b[i].hash & buckets; h[j].pos != -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 j = (j + 1) & buckets) {
if (!cmp(b + i, b + h[j].pos)) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 break;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
}
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* add to the head of the equivalence class */
mpm@selenic.com
Minor speed improvements for bdiff...
r474 b[i].n = h[j].pos;
mpm@selenic.com
Add bdiff.blocks / minor performance tweaks...
r433 b[i].e = j;
mpm@selenic.com
Minor speed improvements for bdiff...
r474 h[j].pos = i;
h[j].len++; /* keep track of popularity */
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 }
/* compute popularity threshold */
Benoit Boissinot
bdiff: gradually enable the popularity hack...
r9534 t = (bn >= 31000) ? bn / 1000 : 1000000 / (bn + 1);
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* match items in a to their equivalence class in b */
for (i = 0; i < an; i++) {
/* find the equivalence class */
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 for (j = a[i].hash & buckets; h[j].pos != -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 j = (j + 1) & buckets) {
if (!cmp(a + i, b + h[j].pos)) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 break;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
}
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
mpm@selenic.com
Add bdiff.blocks / minor performance tweaks...
r433 a[i].e = j; /* use equivalence class for quick compare */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (h[j].len <= t) {
mpm@selenic.com
Minor speed improvements for bdiff...
r474 a[i].n = h[j].pos; /* point to head of match list */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 } else {
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 a[i].n = -1; /* too popular */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 }
/* discard hash tables */
free(h);
return 1;
}
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 static int longest_match(struct bdiff_line *a, struct bdiff_line *b,
Augie Fackler
bdiff: rewrap function prototypes per clang-format...
r34632 struct pos *pos, int a1, int a2, int b1, int b2,
int *omi, int *omj)
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 {
Mads Kiilerich
bdiff: give slight preference to longest matches in the middle of the B side...
r30431 int mi = a1, mj = b1, mk = 0, i, j, k, half, bhalf;
Matt Mackall
bdiff: further restrain potential quadratic performance...
r29015
/* window our search on large regions to better bound
worst-case performance. by choosing a window at the end, we
reduce skipping overhead on the b chains. */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (a2 - a1 > 30000) {
Matt Mackall
bdiff: further restrain potential quadratic performance...
r29015 a1 = a2 - 30000;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: further restrain potential quadratic performance...
r29015
Mads Kiilerich
bdiff: adjust criteria for getting optimal longest match in the A side middle...
r30429 half = (a1 + a2 - 1) / 2;
Mads Kiilerich
bdiff: give slight preference to longest matches in the middle of the B side...
r30431 bhalf = (b1 + b2 - 1) / 2;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
for (i = a1; i < a2; i++) {
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 /* skip all lines in b after the current block */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 for (j = a[i].n; j >= b2; j = b[j].n) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 ;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
/* loop through all lines match a[i] in b */
Matt Mackall
bdiff: deal better with duplicate lines...
r29013 for (; j >= b1; j = b[j].n) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 /* does this extend an earlier match? */
Matt Mackall
bdiff: extend matches across popular lines...
r29322 for (k = 1; j - k >= b1 && i - k >= a1; k++) {
/* reached an earlier match? */
if (pos[j - k].pos == i - k) {
k += pos[j - k].len;
break;
}
/* previous line mismatch? */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (a[i - k].e != b[j - k].e) {
Matt Mackall
bdiff: extend matches across popular lines...
r29322 break;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: extend matches across popular lines...
r29322 }
mpm@selenic.com
Minor speed improvements for bdiff...
r474 pos[j].pos = i;
pos[j].len = k;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Matt Mackall
bdiff: balance recursion to avoid quadratic behavior (issue4704)...
r29014 /* best match so far? we prefer matches closer
to the middle to balance recursion */
Mads Kiilerich
bdiff: rearrange the "better longest match" code...
r30430 if (k > mk) {
/* a longer match */
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 mi = i;
mj = j;
mk = k;
Mads Kiilerich
bdiff: rearrange the "better longest match" code...
r30430 } else if (k == mk) {
Mads Kiilerich
bdiff: give slight preference to removing trailing lines...
r30433 if (i > mi && i <= half && j > b1) {
Mads Kiilerich
bdiff: rearrange the "better longest match" code...
r30430 /* same match but closer to half */
mi = i;
mj = j;
Mads Kiilerich
bdiff: give slight preference to appending lines...
r30432 } else if (i == mi && (mj > bhalf || i == a1)) {
Mads Kiilerich
bdiff: give slight preference to longest matches in the middle of the B side...
r30431 /* same i but best earlier j */
Mads Kiilerich
bdiff: rearrange the "better longest match" code...
r30430 mj = j;
}
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 }
}
}
if (mk) {
mi = mi - mk + 1;
mj = mj - mk + 1;
}
Matt Mackall
bdiff: remove effectively dead code...
r29323 /* expand match to include subsequent popular lines */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 while (mi + mk < a2 && mj + mk < b2 && a[mi + mk].e == b[mj + mk].e) {
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 mk++;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Matt Mackall
bdiff: remove effectively dead code...
r29323 *omi = mi;
*omj = mj;
Matt Mackall
bdiff: use INT_MAX to avoid some inner loop comparisons
r5341
Matt Mackall
bdiff: remove effectively dead code...
r29323 return mk;
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 }
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 static struct bdiff_hunk *recurse(struct bdiff_line *a, struct bdiff_line *b,
Augie Fackler
bdiff: rewrap function prototypes per clang-format...
r34632 struct pos *pos, int a1, int a2, int b1,
int b2, struct bdiff_hunk *l)
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 {
int i, j, k;
Alistair Bell
bdiff: do not use recursion / avoid stackoverflow (issue1940)
r10500 while (1) {
/* find the longest match in this chunk */
k = longest_match(a, b, pos, a1, a2, b1, b2, &i, &j);
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!k) {
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 return l;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400
Alistair Bell
bdiff: do not use recursion / avoid stackoverflow (issue1940)
r10500 /* and recurse on the remaining chunks on either side */
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 l = recurse(a, b, pos, a1, i, b1, j, l);
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!l) {
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 return NULL;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: dynamically allocate hunks...
r13089
Augie Fackler
bdiff: re-wrap lines per clang-format...
r34631 l->next =
(struct bdiff_hunk *)malloc(sizeof(struct bdiff_hunk));
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!l->next) {
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 return NULL;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: dynamically allocate hunks...
r13089
l = l->next;
l->a1 = i;
l->a2 = i + k;
l->b1 = j;
l->b2 = j + k;
l->next = NULL;
/* tail-recursion didn't happen, so do equivalent iteration */
Alistair Bell
bdiff: do not use recursion / avoid stackoverflow (issue1940)
r10500 a1 = i + k;
b1 = j + k;
}
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 }
Augie Fackler
bdiff: rewrap function prototypes per clang-format...
r34632 int bdiff_diff(struct bdiff_line *a, int an, struct bdiff_line *b, int bn,
struct bdiff_hunk *base)
mpm@selenic.com
Add a fast binary diff extension (not yet used)...
r400 {
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 struct bdiff_hunk *curr;
mpm@selenic.com
Minor speed improvements for bdiff...
r474 struct pos *pos;
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 int t, count = 0;
mpm@selenic.com
Add bdiff.blocks / minor performance tweaks...
r433
/* allocate and fill arrays */
t = equatelines(a, an, b, bn);
Jim Hague
fix calloc(0, ...) issue
r5571 pos = (struct pos *)calloc(bn ? bn : 1, sizeof(struct pos));
Matt Mackall
bdiff: dynamically allocate hunks...
r13089
if (pos && t) {
/* generate the matching block list */
curr = recurse(a, b, pos, 0, an, 0, bn, base);
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!curr) {
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
mpm@selenic.com
Add bdiff.blocks / minor performance tweaks...
r433
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 /* sentinel end hunk */
Augie Fackler
bdiff: re-wrap lines per clang-format...
r34631 curr->next =
(struct bdiff_hunk *)malloc(sizeof(struct bdiff_hunk));
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!curr->next) {
Matt Mackall
bdiff: Fix bogus NULL return
r13090 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 curr = curr->next;
curr->a1 = curr->a2 = an;
curr->b1 = curr->b2 = bn;
curr->next = NULL;
mpm@selenic.com
Add bdiff.blocks / minor performance tweaks...
r433 }
mpm@selenic.com
Minor speed improvements for bdiff...
r474 free(pos);
Benoit Boissinot
bdiff: normalize the diff (issue1295)...
r7104
Benoit Boissinot
bdiff: add comment about normalization
r7625 /* normalize the hunk list, try to push each hunk towards the end */
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 for (curr = base->next; curr; curr = curr->next) {
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 struct bdiff_hunk *next = curr->next;
Benoit Boissinot
bdiff: normalize the diff (issue1295)...
r7104
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (!next) {
Benoit Boissinot
bdiff: normalize the diff (issue1295)...
r7104 break;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Benoit Boissinot
bdiff: normalize the diff (issue1295)...
r7104
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (curr->a2 == next->a1 || curr->b2 == next->b1) {
Augie Fackler
bdiff: re-wrap lines per clang-format...
r34631 while (curr->a2 < an && curr->b2 < bn &&
next->a1 < next->a2 && next->b1 < next->b2 &&
!cmp(a + curr->a2, b + curr->b2)) {
Matt Mackall
bdiff: fold in shift calculation in normalize...
r29011 curr->a2++;
next->a1++;
curr->b2++;
next->b1++;
}
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Benoit Boissinot
bdiff: normalize the diff (issue1295)...
r7104 }
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 for (curr = base->next; curr; curr = curr->next) {
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 count++;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 return count;
}
Yuya Nishihara
bdiff: document that bdiff_freehunks() accepts NULL...
r38327 /* deallocate list of hunks; l may be NULL */
Maciej Fijalkowski
bdiff: split bdiff into cpy-aware and cpy-agnostic part
r29541 void bdiff_freehunks(struct bdiff_hunk *l)
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 {
Maciej Fijalkowski
bdiff: rename functions and structs to be amenable for later exporting
r29540 struct bdiff_hunk *n;
Matt Mackall
bdiff: dynamically allocate hunks...
r13089 for (; l; l = n) {
n = l->next;
free(l);
}
mpm@selenic.com
Add bdiff.blocks / minor performance tweaks...
r433 }