mercurial/thirdparty/xdiff/xdiffi.c
author Jun Wu <quark@fb.com>
Wed, 07 Mar 2018 14:45:31 -0800
changeset 36828 f33a87cf60cc
parent 36771 90f8fe72446c
child 36830 882657a9f768
permissions -rw-r--r--
xdiff: add a preprocessing step that trims files xdiff has a `xdl_trim_ends` step that removes common lines, unmatchable lines. That is in theory good, but happens too late - after splitting, hashing, and adjusting the hash values so they are unique. Those splitting, hashing and adjusting hash values steps could have noticeable overhead. Diffing two large files with minor (one-line-ish) changes are not uncommon. In that case, the raw performance of those preparation steps seriously matter. Even allocating an O(N) array and storing line offsets to it is expensive. Therefore my previous attempts [1] [2] cannot be good enough since they do not remove the O(N) array assignment. This patch adds a preprocessing step - `xdl_trim_files` that runs before other preprocessing steps. It counts common prefix and suffix and lines in them (needed for displaying line number), without doing anything else. Testing with a crafted large (169MB) file, with minor change: ``` open('a','w').write(''.join('%s\n' % (i % 100000) for i in xrange(30000000) if i != 6000000)) open('b','w').write(''.join('%s\n' % (i % 100000) for i in xrange(30000000) if i != 6003000)) ``` Running xdiff by a simple binary [3], this patch improves the xdiff perf by more than 10x for the above case: ``` # xdiff before this patch 2.41s user 1.13s system 98% cpu 3.592 total # xdiff after this patch 0.14s user 0.16s system 98% cpu 0.309 total # gnu diffutils 0.12s user 0.15s system 98% cpu 0.272 total # (best of 20 runs) ``` It's still slightly slower than GNU diffutils. But it's pretty close now. Testing with real repo data: For the whole repo, this patch makes xdiff 25% faster: ``` # hg perfbdiff --count 100 --alldata -c d334afc585e2 --blocks [--xdiff] # xdiff, after ! wall 0.058861 comb 0.050000 user 0.050000 sys 0.000000 (best of 100) # xdiff, before ! wall 0.077816 comb 0.080000 user 0.080000 sys 0.000000 (best of 91) # bdiff ! wall 0.117473 comb 0.120000 user 0.120000 sys 0.000000 (best of 67) ``` For files that are long (ex. commands.py), the speedup is more than 3x, very significant: ``` # hg perfbdiff --count 3000 --blocks commands.py.i 1 [--xdiff] # xdiff, after ! wall 0.690583 comb 0.690000 user 0.690000 sys 0.000000 (best of 12) # xdiff, before ! wall 2.240361 comb 2.210000 user 2.210000 sys 0.000000 (best of 4) # bdiff ! wall 2.469852 comb 2.440000 user 2.440000 sys 0.000000 (best of 4) ``` [1]: https://phab.mercurial-scm.org/D2631 [2]: https://phab.mercurial-scm.org/D2634 [3]: ``` // Code to run xdiff from command line. No proper error handling. #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "mercurial/thirdparty/xdiff/xdiff.h" #define ensure(x) if (!(x)) exit(255); mmfile_t readfile(const char *path) { struct stat st; int fd = open(path, O_RDONLY); fstat(fd, &st); mmfile_t file = { malloc(st.st_size), st.st_size }; ensure(read(fd, file.ptr, st.st_size) == st.st_size); close(fd); return file; } int main(int argc, char const *argv[]) { mmfile_t a = readfile(argv[1]), b = readfile(argv[2]); xpparam_t xpp = {0}; xdemitconf_t xecfg = {0}; xdemitcb_t ecb = {0}; xdl_diff(&a, &b, &xpp, &xecfg, &ecb); return 0; } ``` Differential Revision: https://phab.mercurial-scm.org/D2686
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     1
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     2
 *  LibXDiff by Davide Libenzi ( File Differential Library )
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     3
 *  Copyright (C) 2003	Davide Libenzi
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     4
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     5
 *  This library is free software; you can redistribute it and/or
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     6
 *  modify it under the terms of the GNU Lesser General Public
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     7
 *  License as published by the Free Software Foundation; either
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     8
 *  version 2.1 of the License, or (at your option) any later version.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
     9
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    10
 *  This library is distributed in the hope that it will be useful,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    13
 *  Lesser General Public License for more details.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    14
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    15
 *  You should have received a copy of the GNU Lesser General Public
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    16
 *  License along with this library; if not, see
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    17
 *  <http://www.gnu.org/licenses/>.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    18
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    19
 *  Davide Libenzi <davidel@xmailserver.org>
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    20
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    21
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    22
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    23
#include "xinclude.h"
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    24
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    25
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    26
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    27
#define XDL_MAX_COST_MIN 256
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    28
#define XDL_HEUR_MIN_COST 256
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    29
#define XDL_LINE_MAX (long)((1UL << (CHAR_BIT * sizeof(long) - 1)) - 1)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    30
#define XDL_SNAKE_CNT 20
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    31
#define XDL_K_HEUR 4
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    32
36746
1f9bbd1d6b8a xdiff: fix builds on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36703
diff changeset
    33
/* VC 2008 doesn't know about the inline keyword. */
1f9bbd1d6b8a xdiff: fix builds on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36703
diff changeset
    34
#if defined(_MSC_VER)
1f9bbd1d6b8a xdiff: fix builds on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36703
diff changeset
    35
#define inline __forceinline
1f9bbd1d6b8a xdiff: fix builds on Windows
Matt Harbison <matt_harbison@yahoo.com>
parents: 36703
diff changeset
    36
#endif
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    37
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    38
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    39
typedef struct s_xdpsplit {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    40
	long i1, i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    41
	int min_lo, min_hi;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    42
} xdpsplit_t;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    43
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    44
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    45
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    46
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    47
static long xdl_split(unsigned long const *ha1, long off1, long lim1,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    48
		      unsigned long const *ha2, long off2, long lim2,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    49
		      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    50
		      xdalgoenv_t *xenv);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    51
static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    52
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    53
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    54
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    55
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    56
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    57
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    58
 * See "An O(ND) Difference Algorithm and its Variations", by Eugene Myers.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    59
 * Basically considers a "box" (off1, off2, lim1, lim2) and scan from both
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    60
 * the forward diagonal starting from (off1, off2) and the backward diagonal
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    61
 * starting from (lim1, lim2). If the K values on the same diagonal crosses
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    62
 * returns the furthest point of reach. We might end up having to expensive
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    63
 * cases using this algorithm is full, so a little bit of heuristic is needed
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    64
 * to cut the search and to return a suboptimal point.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    65
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    66
static long xdl_split(unsigned long const *ha1, long off1, long lim1,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    67
		      unsigned long const *ha2, long off2, long lim2,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    68
		      long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    69
		      xdalgoenv_t *xenv) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    70
	long dmin = off1 - lim2, dmax = lim1 - off2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    71
	long fmid = off1 - off2, bmid = lim1 - lim2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    72
	long odd = (fmid - bmid) & 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    73
	long fmin = fmid, fmax = fmid;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    74
	long bmin = bmid, bmax = bmid;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    75
	long ec, d, i1, i2, prev1, best, dd, v, k;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    76
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    77
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    78
	 * Set initial diagonal values for both forward and backward path.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    79
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    80
	kvdf[fmid] = off1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    81
	kvdb[bmid] = lim1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    82
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    83
	for (ec = 1;; ec++) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    84
		int got_snake = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    85
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    86
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    87
		 * We need to extent the diagonal "domain" by one. If the next
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    88
		 * values exits the box boundaries we need to change it in the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    89
		 * opposite direction because (max - min) must be a power of two.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    90
		 * Also we initialize the external K value to -1 so that we can
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    91
		 * avoid extra conditions check inside the core loop.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    92
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    93
		if (fmin > dmin)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    94
			kvdf[--fmin - 1] = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    95
		else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    96
			++fmin;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    97
		if (fmax < dmax)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    98
			kvdf[++fmax + 1] = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
    99
		else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   100
			--fmax;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   101
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   102
		for (d = fmax; d >= fmin; d -= 2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   103
			if (kvdf[d - 1] >= kvdf[d + 1])
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   104
				i1 = kvdf[d - 1] + 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   105
			else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   106
				i1 = kvdf[d + 1];
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   107
			prev1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   108
			i2 = i1 - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   109
			for (; i1 < lim1 && i2 < lim2 && ha1[i1] == ha2[i2]; i1++, i2++);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   110
			if (i1 - prev1 > xenv->snake_cnt)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   111
				got_snake = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   112
			kvdf[d] = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   113
			if (odd && bmin <= d && d <= bmax && kvdb[d] <= i1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   114
				spl->i1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   115
				spl->i2 = i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   116
				spl->min_lo = spl->min_hi = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   117
				return ec;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   118
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   119
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   120
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   121
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   122
		 * We need to extent the diagonal "domain" by one. If the next
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   123
		 * values exits the box boundaries we need to change it in the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   124
		 * opposite direction because (max - min) must be a power of two.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   125
		 * Also we initialize the external K value to -1 so that we can
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   126
		 * avoid extra conditions check inside the core loop.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   127
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   128
		if (bmin > dmin)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   129
			kvdb[--bmin - 1] = XDL_LINE_MAX;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   130
		else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   131
			++bmin;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   132
		if (bmax < dmax)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   133
			kvdb[++bmax + 1] = XDL_LINE_MAX;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   134
		else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   135
			--bmax;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   136
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   137
		for (d = bmax; d >= bmin; d -= 2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   138
			if (kvdb[d - 1] < kvdb[d + 1])
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   139
				i1 = kvdb[d - 1];
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   140
			else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   141
				i1 = kvdb[d + 1] - 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   142
			prev1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   143
			i2 = i1 - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   144
			for (; i1 > off1 && i2 > off2 && ha1[i1 - 1] == ha2[i2 - 1]; i1--, i2--);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   145
			if (prev1 - i1 > xenv->snake_cnt)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   146
				got_snake = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   147
			kvdb[d] = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   148
			if (!odd && fmin <= d && d <= fmax && i1 <= kvdf[d]) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   149
				spl->i1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   150
				spl->i2 = i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   151
				spl->min_lo = spl->min_hi = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   152
				return ec;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   153
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   154
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   155
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   156
		if (need_min)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   157
			continue;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   158
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   159
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   160
		 * If the edit cost is above the heuristic trigger and if
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   161
		 * we got a good snake, we sample current diagonals to see
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   162
		 * if some of the, have reached an "interesting" path. Our
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   163
		 * measure is a function of the distance from the diagonal
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   164
		 * corner (i1 + i2) penalized with the distance from the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   165
		 * mid diagonal itself. If this value is above the current
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   166
		 * edit cost times a magic factor (XDL_K_HEUR) we consider
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   167
		 * it interesting.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   168
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   169
		if (got_snake && ec > xenv->heur_min) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   170
			for (best = 0, d = fmax; d >= fmin; d -= 2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   171
				dd = d > fmid ? d - fmid: fmid - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   172
				i1 = kvdf[d];
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   173
				i2 = i1 - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   174
				v = (i1 - off1) + (i2 - off2) - dd;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   175
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   176
				if (v > XDL_K_HEUR * ec && v > best &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   177
				    off1 + xenv->snake_cnt <= i1 && i1 < lim1 &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   178
				    off2 + xenv->snake_cnt <= i2 && i2 < lim2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   179
					for (k = 1; ha1[i1 - k] == ha2[i2 - k]; k++)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   180
						if (k == xenv->snake_cnt) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   181
							best = v;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   182
							spl->i1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   183
							spl->i2 = i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   184
							break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   185
						}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   186
				}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   187
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   188
			if (best > 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   189
				spl->min_lo = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   190
				spl->min_hi = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   191
				return ec;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   192
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   193
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   194
			for (best = 0, d = bmax; d >= bmin; d -= 2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   195
				dd = d > bmid ? d - bmid: bmid - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   196
				i1 = kvdb[d];
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   197
				i2 = i1 - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   198
				v = (lim1 - i1) + (lim2 - i2) - dd;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   199
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   200
				if (v > XDL_K_HEUR * ec && v > best &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   201
				    off1 < i1 && i1 <= lim1 - xenv->snake_cnt &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   202
				    off2 < i2 && i2 <= lim2 - xenv->snake_cnt) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   203
					for (k = 0; ha1[i1 + k] == ha2[i2 + k]; k++)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   204
						if (k == xenv->snake_cnt - 1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   205
							best = v;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   206
							spl->i1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   207
							spl->i2 = i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   208
							break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   209
						}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   210
				}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   211
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   212
			if (best > 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   213
				spl->min_lo = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   214
				spl->min_hi = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   215
				return ec;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   216
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   217
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   218
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   219
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   220
		 * Enough is enough. We spent too much time here and now we collect
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   221
		 * the furthest reaching path using the (i1 + i2) measure.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   222
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   223
		if (ec >= xenv->mxcost) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   224
			long fbest, fbest1, bbest, bbest1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   225
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   226
			fbest = fbest1 = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   227
			for (d = fmax; d >= fmin; d -= 2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   228
				i1 = XDL_MIN(kvdf[d], lim1);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   229
				i2 = i1 - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   230
				if (lim2 < i2)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   231
					i1 = lim2 + d, i2 = lim2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   232
				if (fbest < i1 + i2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   233
					fbest = i1 + i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   234
					fbest1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   235
				}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   236
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   237
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   238
			bbest = bbest1 = XDL_LINE_MAX;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   239
			for (d = bmax; d >= bmin; d -= 2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   240
				i1 = XDL_MAX(off1, kvdb[d]);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   241
				i2 = i1 - d;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   242
				if (i2 < off2)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   243
					i1 = off2 + d, i2 = off2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   244
				if (i1 + i2 < bbest) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   245
					bbest = i1 + i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   246
					bbest1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   247
				}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   248
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   249
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   250
			if ((lim1 + lim2) - bbest < fbest - (off1 + off2)) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   251
				spl->i1 = fbest1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   252
				spl->i2 = fbest - fbest1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   253
				spl->min_lo = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   254
				spl->min_hi = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   255
			} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   256
				spl->i1 = bbest1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   257
				spl->i2 = bbest - bbest1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   258
				spl->min_lo = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   259
				spl->min_hi = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   260
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   261
			return ec;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   262
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   263
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   264
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   265
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   266
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   267
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   268
 * Rule: "Divide et Impera". Recursively split the box in sub-boxes by calling
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   269
 * the box splitting function. Note that the real job (marking changed lines)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   270
 * is done in the two boundary reaching checks.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   271
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   272
int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   273
		 diffdata_t *dd2, long off2, long lim2,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   274
		 long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   275
	unsigned long const *ha1 = dd1->ha, *ha2 = dd2->ha;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   276
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   277
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   278
	 * Shrink the box by walking through each diagonal snake (SW and NE).
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   279
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   280
	for (; off1 < lim1 && off2 < lim2 && ha1[off1] == ha2[off2]; off1++, off2++);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   281
	for (; off1 < lim1 && off2 < lim2 && ha1[lim1 - 1] == ha2[lim2 - 1]; lim1--, lim2--);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   282
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   283
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   284
	 * If one dimension is empty, then all records on the other one must
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   285
	 * be obviously changed.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   286
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   287
	if (off1 == lim1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   288
		char *rchg2 = dd2->rchg;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   289
		long *rindex2 = dd2->rindex;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   290
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   291
		for (; off2 < lim2; off2++)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   292
			rchg2[rindex2[off2]] = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   293
	} else if (off2 == lim2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   294
		char *rchg1 = dd1->rchg;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   295
		long *rindex1 = dd1->rindex;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   296
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   297
		for (; off1 < lim1; off1++)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   298
			rchg1[rindex1[off1]] = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   299
	} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   300
		xdpsplit_t spl;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   301
		spl.i1 = spl.i2 = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   302
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   303
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   304
		 * Divide ...
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   305
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   306
		if (xdl_split(ha1, off1, lim1, ha2, off2, lim2, kvdf, kvdb,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   307
			      need_min, &spl, xenv) < 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   308
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   309
			return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   310
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   311
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   312
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   313
		 * ... et Impera.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   314
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   315
		if (xdl_recs_cmp(dd1, off1, spl.i1, dd2, off2, spl.i2,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   316
				 kvdf, kvdb, spl.min_lo, xenv) < 0 ||
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   317
		    xdl_recs_cmp(dd1, spl.i1, lim1, dd2, spl.i2, lim2,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   318
				 kvdf, kvdb, spl.min_hi, xenv) < 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   319
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   320
			return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   321
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   322
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   323
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   324
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   325
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   326
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   327
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   328
int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   329
		xdfenv_t *xe) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   330
	long ndiags;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   331
	long *kvd, *kvdf, *kvdb;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   332
	xdalgoenv_t xenv;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   333
	diffdata_t dd1, dd2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   334
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   335
	if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   336
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   337
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   338
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   339
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   340
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   341
	 * Allocate and setup K vectors to be used by the differential algorithm.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   342
	 * One is to store the forward path and one to store the backward path.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   343
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   344
	ndiags = xe->xdf1.nreff + xe->xdf2.nreff + 3;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   345
	if (!(kvd = (long *) xdl_malloc((2 * ndiags + 2) * sizeof(long)))) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   346
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   347
		xdl_free_env(xe);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   348
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   349
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   350
	kvdf = kvd;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   351
	kvdb = kvdf + ndiags;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   352
	kvdf += xe->xdf2.nreff + 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   353
	kvdb += xe->xdf2.nreff + 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   354
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   355
	xenv.mxcost = xdl_bogosqrt(ndiags);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   356
	if (xenv.mxcost < XDL_MAX_COST_MIN)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   357
		xenv.mxcost = XDL_MAX_COST_MIN;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   358
	xenv.snake_cnt = XDL_SNAKE_CNT;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   359
	xenv.heur_min = XDL_HEUR_MIN_COST;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   360
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   361
	dd1.nrec = xe->xdf1.nreff;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   362
	dd1.ha = xe->xdf1.ha;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   363
	dd1.rchg = xe->xdf1.rchg;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   364
	dd1.rindex = xe->xdf1.rindex;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   365
	dd2.nrec = xe->xdf2.nreff;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   366
	dd2.ha = xe->xdf2.ha;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   367
	dd2.rchg = xe->xdf2.rchg;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   368
	dd2.rindex = xe->xdf2.rindex;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   369
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   370
	if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   371
			 kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   372
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   373
		xdl_free(kvd);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   374
		xdl_free_env(xe);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   375
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   376
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   377
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   378
	xdl_free(kvd);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   379
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   380
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   381
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   382
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   383
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   384
static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   385
	xdchange_t *xch;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   386
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   387
	if (!(xch = (xdchange_t *) xdl_malloc(sizeof(xdchange_t))))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   388
		return NULL;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   389
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   390
	xch->next = xscr;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   391
	xch->i1 = i1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   392
	xch->i2 = i2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   393
	xch->chg1 = chg1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   394
	xch->chg2 = chg2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   395
	xch->ignore = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   396
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   397
	return xch;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   398
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   399
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   400
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   401
static int recs_match(xrecord_t *rec1, xrecord_t *rec2, long flags)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   402
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   403
	return (rec1->ha == rec2->ha &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   404
		xdl_recmatch(rec1->ptr, rec1->size,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   405
			     rec2->ptr, rec2->size,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   406
			     flags));
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   407
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   408
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   409
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   410
 * If a line is indented more than this, get_indent() just returns this value.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   411
 * This avoids having to do absurd amounts of work for data that are not
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   412
 * human-readable text, and also ensures that the output of get_indent fits within
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   413
 * an int.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   414
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   415
#define MAX_INDENT 200
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   416
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   417
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   418
 * Return the amount of indentation of the specified line, treating TAB as 8
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   419
 * columns. Return -1 if line is empty or contains only whitespace. Clamp the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   420
 * output value at MAX_INDENT.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   421
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   422
static int get_indent(xrecord_t *rec)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   423
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   424
	long i;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   425
	int ret = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   426
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   427
	for (i = 0; i < rec->size; i++) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   428
		char c = rec->ptr[i];
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   429
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   430
		if (!XDL_ISSPACE(c))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   431
			return ret;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   432
		else if (c == ' ')
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   433
			ret += 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   434
		else if (c == '\t')
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   435
			ret += 8 - ret % 8;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   436
		/* ignore other whitespace characters */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   437
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   438
		if (ret >= MAX_INDENT)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   439
			return MAX_INDENT;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   440
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   441
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   442
	/* The line contains only whitespace. */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   443
	return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   444
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   445
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   446
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   447
 * If more than this number of consecutive blank rows are found, just return this
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   448
 * value. This avoids requiring O(N^2) work for pathological cases, and also
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   449
 * ensures that the output of score_split fits in an int.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   450
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   451
#define MAX_BLANKS 20
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   452
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   453
/* Characteristics measured about a hypothetical split position. */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   454
struct split_measurement {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   455
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   456
	 * Is the split at the end of the file (aside from any blank lines)?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   457
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   458
	int end_of_file;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   459
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   460
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   461
	 * How much is the line immediately following the split indented (or -1 if
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   462
	 * the line is blank):
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   463
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   464
	int indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   465
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   466
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   467
	 * How many consecutive lines above the split are blank?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   468
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   469
	int pre_blank;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   470
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   471
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   472
	 * How much is the nearest non-blank line above the split indented (or -1
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   473
	 * if there is no such line)?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   474
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   475
	int pre_indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   476
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   477
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   478
	 * How many lines after the line following the split are blank?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   479
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   480
	int post_blank;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   481
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   482
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   483
	 * How much is the nearest non-blank line after the line following the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   484
	 * split indented (or -1 if there is no such line)?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   485
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   486
	int post_indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   487
};
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   488
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   489
struct split_score {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   490
	/* The effective indent of this split (smaller is preferred). */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   491
	int effective_indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   492
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   493
	/* Penalty for this split (smaller is preferred). */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   494
	int penalty;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   495
};
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   496
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   497
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   498
 * Fill m with information about a hypothetical split of xdf above line split.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   499
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   500
static void measure_split(const xdfile_t *xdf, long split,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   501
			  struct split_measurement *m)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   502
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   503
	long i;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   504
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   505
	if (split >= xdf->nrec) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   506
		m->end_of_file = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   507
		m->indent = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   508
	} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   509
		m->end_of_file = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   510
		m->indent = get_indent(xdf->recs[split]);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   511
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   512
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   513
	m->pre_blank = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   514
	m->pre_indent = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   515
	for (i = split - 1; i >= 0; i--) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   516
		m->pre_indent = get_indent(xdf->recs[i]);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   517
		if (m->pre_indent != -1)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   518
			break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   519
		m->pre_blank += 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   520
		if (m->pre_blank == MAX_BLANKS) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   521
			m->pre_indent = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   522
			break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   523
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   524
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   525
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   526
	m->post_blank = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   527
	m->post_indent = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   528
	for (i = split + 1; i < xdf->nrec; i++) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   529
		m->post_indent = get_indent(xdf->recs[i]);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   530
		if (m->post_indent != -1)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   531
			break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   532
		m->post_blank += 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   533
		if (m->post_blank == MAX_BLANKS) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   534
			m->post_indent = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   535
			break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   536
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   537
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   538
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   539
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   540
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   541
 * The empirically-determined weight factors used by score_split() below.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   542
 * Larger values means that the position is a less favorable place to split.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   543
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   544
 * Note that scores are only ever compared against each other, so multiplying
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   545
 * all of these weight/penalty values by the same factor wouldn't change the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   546
 * heuristic's behavior. Still, we need to set that arbitrary scale *somehow*.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   547
 * In practice, these numbers are chosen to be large enough that they can be
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   548
 * adjusted relative to each other with sufficient precision despite using
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   549
 * integer math.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   550
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   551
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   552
/* Penalty if there are no non-blank lines before the split */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   553
#define START_OF_FILE_PENALTY 1
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   554
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   555
/* Penalty if there are no non-blank lines after the split */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   556
#define END_OF_FILE_PENALTY 21
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   557
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   558
/* Multiplier for the number of blank lines around the split */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   559
#define TOTAL_BLANK_WEIGHT (-30)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   560
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   561
/* Multiplier for the number of blank lines after the split */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   562
#define POST_BLANK_WEIGHT 6
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   563
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   564
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   565
 * Penalties applied if the line is indented more than its predecessor
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   566
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   567
#define RELATIVE_INDENT_PENALTY (-4)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   568
#define RELATIVE_INDENT_WITH_BLANK_PENALTY 10
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   569
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   570
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   571
 * Penalties applied if the line is indented less than both its predecessor and
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   572
 * its successor
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   573
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   574
#define RELATIVE_OUTDENT_PENALTY 24
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   575
#define RELATIVE_OUTDENT_WITH_BLANK_PENALTY 17
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   576
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   577
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   578
 * Penalties applied if the line is indented less than its predecessor but not
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   579
 * less than its successor
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   580
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   581
#define RELATIVE_DEDENT_PENALTY 23
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   582
#define RELATIVE_DEDENT_WITH_BLANK_PENALTY 17
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   583
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   584
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   585
 * We only consider whether the sum of the effective indents for splits are
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   586
 * less than (-1), equal to (0), or greater than (+1) each other. The resulting
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   587
 * value is multiplied by the following weight and combined with the penalty to
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   588
 * determine the better of two scores.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   589
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   590
#define INDENT_WEIGHT 60
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   591
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   592
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   593
 * Compute a badness score for the hypothetical split whose measurements are
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   594
 * stored in m. The weight factors were determined empirically using the tools and
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   595
 * corpus described in
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   596
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   597
 *     https://github.com/mhagger/diff-slider-tools
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   598
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   599
 * Also see that project if you want to improve the weights based on, for example,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   600
 * a larger or more diverse corpus.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   601
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   602
static void score_add_split(const struct split_measurement *m, struct split_score *s)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   603
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   604
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   605
	 * A place to accumulate penalty factors (positive makes this index more
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   606
	 * favored):
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   607
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   608
	int post_blank, total_blank, indent, any_blanks;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   609
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   610
	if (m->pre_indent == -1 && m->pre_blank == 0)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   611
		s->penalty += START_OF_FILE_PENALTY;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   612
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   613
	if (m->end_of_file)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   614
		s->penalty += END_OF_FILE_PENALTY;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   615
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   616
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   617
	 * Set post_blank to the number of blank lines following the split,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   618
	 * including the line immediately after the split:
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   619
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   620
	post_blank = (m->indent == -1) ? 1 + m->post_blank : 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   621
	total_blank = m->pre_blank + post_blank;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   622
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   623
	/* Penalties based on nearby blank lines: */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   624
	s->penalty += TOTAL_BLANK_WEIGHT * total_blank;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   625
	s->penalty += POST_BLANK_WEIGHT * post_blank;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   626
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   627
	if (m->indent != -1)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   628
		indent = m->indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   629
	else
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   630
		indent = m->post_indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   631
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   632
	any_blanks = (total_blank != 0);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   633
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   634
	/* Note that the effective indent is -1 at the end of the file: */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   635
	s->effective_indent += indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   636
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   637
	if (indent == -1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   638
		/* No additional adjustments needed. */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   639
	} else if (m->pre_indent == -1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   640
		/* No additional adjustments needed. */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   641
	} else if (indent > m->pre_indent) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   642
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   643
		 * The line is indented more than its predecessor.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   644
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   645
		s->penalty += any_blanks ?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   646
			RELATIVE_INDENT_WITH_BLANK_PENALTY :
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   647
			RELATIVE_INDENT_PENALTY;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   648
	} else if (indent == m->pre_indent) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   649
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   650
		 * The line has the same indentation level as its predecessor.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   651
		 * No additional adjustments needed.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   652
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   653
	} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   654
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   655
		 * The line is indented less than its predecessor. It could be
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   656
		 * the block terminator of the previous block, but it could
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   657
		 * also be the start of a new block (e.g., an "else" block, or
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   658
		 * maybe the previous block didn't have a block terminator).
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   659
		 * Try to distinguish those cases based on what comes next:
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   660
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   661
		if (m->post_indent != -1 && m->post_indent > indent) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   662
			/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   663
			 * The following line is indented more. So it is likely
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   664
			 * that this line is the start of a block.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   665
			 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   666
			s->penalty += any_blanks ?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   667
				RELATIVE_OUTDENT_WITH_BLANK_PENALTY :
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   668
				RELATIVE_OUTDENT_PENALTY;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   669
		} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   670
			/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   671
			 * That was probably the end of a block.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   672
			 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   673
			s->penalty += any_blanks ?
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   674
				RELATIVE_DEDENT_WITH_BLANK_PENALTY :
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   675
				RELATIVE_DEDENT_PENALTY;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   676
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   677
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   678
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   679
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   680
static int score_cmp(struct split_score *s1, struct split_score *s2)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   681
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   682
	/* -1 if s1.effective_indent < s2->effective_indent, etc. */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   683
	int cmp_indents = ((s1->effective_indent > s2->effective_indent) -
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   684
			   (s1->effective_indent < s2->effective_indent));
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   685
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   686
	return INDENT_WEIGHT * cmp_indents + (s1->penalty - s2->penalty);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   687
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   688
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   689
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   690
 * Represent a group of changed lines in an xdfile_t (i.e., a contiguous group
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   691
 * of lines that was inserted or deleted from the corresponding version of the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   692
 * file). We consider there to be such a group at the beginning of the file, at
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   693
 * the end of the file, and between any two unchanged lines, though most such
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   694
 * groups will usually be empty.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   695
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   696
 * If the first line in a group is equal to the line following the group, then
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   697
 * the group can be slid down. Similarly, if the last line in a group is equal
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   698
 * to the line preceding the group, then the group can be slid up. See
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   699
 * group_slide_down() and group_slide_up().
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   700
 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   701
 * Note that loops that are testing for changed lines in xdf->rchg do not need
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   702
 * index bounding since the array is prepared with a zero at position -1 and N.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   703
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   704
struct xdlgroup {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   705
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   706
	 * The index of the first changed line in the group, or the index of
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   707
	 * the unchanged line above which the (empty) group is located.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   708
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   709
	long start;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   710
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   711
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   712
	 * The index of the first unchanged line after the group. For an empty
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   713
	 * group, end is equal to start.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   714
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   715
	long end;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   716
};
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   717
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   718
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   719
 * Initialize g to point at the first group in xdf.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   720
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   721
static void group_init(xdfile_t *xdf, struct xdlgroup *g)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   722
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   723
	g->start = g->end = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   724
	while (xdf->rchg[g->end])
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   725
		g->end++;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   726
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   727
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   728
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   729
 * Move g to describe the next (possibly empty) group in xdf and return 0. If g
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   730
 * is already at the end of the file, do nothing and return -1.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   731
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   732
static inline int group_next(xdfile_t *xdf, struct xdlgroup *g)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   733
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   734
	if (g->end == xdf->nrec)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   735
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   736
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   737
	g->start = g->end + 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   738
	for (g->end = g->start; xdf->rchg[g->end]; g->end++)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   739
		;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   740
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   741
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   742
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   743
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   744
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   745
 * Move g to describe the previous (possibly empty) group in xdf and return 0.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   746
 * If g is already at the beginning of the file, do nothing and return -1.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   747
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   748
static inline int group_previous(xdfile_t *xdf, struct xdlgroup *g)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   749
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   750
	if (g->start == 0)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   751
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   752
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   753
	g->end = g->start - 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   754
	for (g->start = g->end; xdf->rchg[g->start - 1]; g->start--)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   755
		;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   756
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   757
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   758
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   759
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   760
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   761
 * If g can be slid toward the end of the file, do so, and if it bumps into a
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   762
 * following group, expand this group to include it. Return 0 on success or -1
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   763
 * if g cannot be slid down.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   764
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   765
static int group_slide_down(xdfile_t *xdf, struct xdlgroup *g, long flags)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   766
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   767
	if (g->end < xdf->nrec &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   768
	    recs_match(xdf->recs[g->start], xdf->recs[g->end], flags)) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   769
		xdf->rchg[g->start++] = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   770
		xdf->rchg[g->end++] = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   771
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   772
		while (xdf->rchg[g->end])
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   773
			g->end++;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   774
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   775
		return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   776
	} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   777
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   778
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   779
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   780
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   781
/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   782
 * If g can be slid toward the beginning of the file, do so, and if it bumps
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   783
 * into a previous group, expand this group to include it. Return 0 on success
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   784
 * or -1 if g cannot be slid up.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   785
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   786
static int group_slide_up(xdfile_t *xdf, struct xdlgroup *g, long flags)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   787
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   788
	if (g->start > 0 &&
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   789
	    recs_match(xdf->recs[g->start - 1], xdf->recs[g->end - 1], flags)) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   790
		xdf->rchg[--g->start] = 1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   791
		xdf->rchg[--g->end] = 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   792
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   793
		while (xdf->rchg[g->start - 1])
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   794
			g->start--;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   795
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   796
		return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   797
	} else {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   798
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   799
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   800
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   801
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   802
static void xdl_bug(const char *msg)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   803
{
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   804
	fprintf(stderr, "BUG: %s\n", msg);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   805
	exit(1);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   806
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   807
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   808
/*
36703
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   809
 * For indentation heuristic, skip searching for better slide position after
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   810
 * checking MAX_BORING lines without finding an improvement. This defends the
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   811
 * indentation heuristic logic against pathological cases. The value is not
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   812
 * picked scientifically but should be good enough.
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   813
 */
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   814
#define MAX_BORING 100
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   815
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   816
/*
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   817
 * Move back and forward change groups for a consistent and pretty diff output.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   818
 * This also helps in finding joinable change groups and reducing the diff
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   819
 * size.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   820
 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   821
int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   822
	struct xdlgroup g, go;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   823
	long earliest_end, end_matching_other;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   824
	long groupsize;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   825
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   826
	group_init(xdf, &g);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   827
	group_init(xdfo, &go);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   828
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   829
	while (1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   830
		/* If the group is empty in the to-be-compacted file, skip it: */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   831
		if (g.end == g.start)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   832
			goto next;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   833
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   834
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   835
		 * Now shift the change up and then down as far as possible in
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   836
		 * each direction. If it bumps into any other changes, merge them.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   837
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   838
		do {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   839
			groupsize = g.end - g.start;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   840
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   841
			/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   842
			 * Keep track of the last "end" index that causes this
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   843
			 * group to align with a group of changed lines in the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   844
			 * other file. -1 indicates that we haven't found such
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   845
			 * a match yet:
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   846
			 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   847
			end_matching_other = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   848
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   849
			/* Shift the group backward as much as possible: */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   850
			while (!group_slide_up(xdf, &g, flags))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   851
				if (group_previous(xdfo, &go))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   852
					xdl_bug("group sync broken sliding up");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   853
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   854
			/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   855
			 * This is this highest that this group can be shifted.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   856
			 * Record its end index:
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   857
			 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   858
			earliest_end = g.end;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   859
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   860
			if (go.end > go.start)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   861
				end_matching_other = g.end;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   862
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   863
			/* Now shift the group forward as far as possible: */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   864
			while (1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   865
				if (group_slide_down(xdf, &g, flags))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   866
					break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   867
				if (group_next(xdfo, &go))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   868
					xdl_bug("group sync broken sliding down");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   869
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   870
				if (go.end > go.start)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   871
					end_matching_other = g.end;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   872
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   873
		} while (groupsize != g.end - g.start);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   874
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   875
		/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   876
		 * If the group can be shifted, then we can possibly use this
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   877
		 * freedom to produce a more intuitive diff.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   878
		 *
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   879
		 * The group is currently shifted as far down as possible, so the
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   880
		 * heuristics below only have to handle upwards shifts.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   881
		 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   882
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   883
		if (g.end == earliest_end) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   884
			/* no shifting was possible */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   885
		} else if (end_matching_other != -1) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   886
			/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   887
			 * Move the possibly merged group of changes back to line
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   888
			 * up with the last group of changes from the other file
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   889
			 * that it can align with.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   890
			 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   891
			while (go.end == go.start) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   892
				if (group_slide_up(xdf, &g, flags))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   893
					xdl_bug("match disappeared");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   894
				if (group_previous(xdfo, &go))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   895
					xdl_bug("group sync broken sliding to match");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   896
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   897
		} else if (flags & XDF_INDENT_HEURISTIC) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   898
			/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   899
			 * Indent heuristic: a group of pure add/delete lines
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   900
			 * implies two splits, one between the end of the "before"
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   901
			 * context and the start of the group, and another between
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   902
			 * the end of the group and the beginning of the "after"
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   903
			 * context. Some splits are aesthetically better and some
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   904
			 * are worse. We compute a badness "score" for each split,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   905
			 * and add the scores for the two splits to define a
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   906
			 * "score" for each position that the group can be shifted
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   907
			 * to. Then we pick the shift with the lowest score.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   908
			 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   909
			long shift, best_shift = -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   910
			struct split_score best_score;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   911
36703
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   912
			/*
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   913
			 * This is O(N * MAX_BLANKS) (N = shift-able lines).
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   914
			 * Even with MAX_BLANKS bounded to a small value, a
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   915
			 * large N could still make this loop take several
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   916
			 * times longer than the main diff algorithm. The
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   917
			 * "boring" value is to help cut down N to something
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   918
			 * like (MAX_BORING + groupsize).
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   919
			 *
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   920
			 * Scan from bottom to top. So we can exit the loop
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   921
			 * without compromising the assumption "for a same best
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   922
			 * score, pick the bottommost shift".
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   923
			 */
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   924
			int boring = 0;
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   925
			for (shift = g.end; shift >= earliest_end; shift--) {
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   926
				struct split_measurement m;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   927
				struct split_score score = {0, 0};
36703
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   928
				int cmp;
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   929
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   930
				measure_split(xdf, shift, &m);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   931
				score_add_split(&m, &score);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   932
				measure_split(xdf, shift - groupsize, &m);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   933
				score_add_split(&m, &score);
36703
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   934
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   935
				if (best_shift == -1) {
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   936
					cmp = -1;
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   937
				} else {
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   938
					cmp = score_cmp(&score, &best_score);
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   939
				}
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   940
				if (cmp < 0) {
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   941
					boring = 0;
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   942
					best_score.effective_indent = score.effective_indent;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   943
					best_score.penalty = score.penalty;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   944
					best_shift = shift;
36703
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   945
				} else {
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   946
					boring += 1;
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   947
					if (boring >= MAX_BORING)
c420792217c8 xdiff: reduce indent heuristic overhead
Jun Wu <quark@fb.com>
parents: 36702
diff changeset
   948
						break;
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   949
				}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   950
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   951
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   952
			while (g.end > best_shift) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   953
				if (group_slide_up(xdf, &g, flags))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   954
					xdl_bug("best shift unreached");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   955
				if (group_previous(xdfo, &go))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   956
					xdl_bug("group sync broken sliding to blank line");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   957
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   958
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   959
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   960
	next:
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   961
		/* Move past the just-processed group: */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   962
		if (group_next(xdf, &g))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   963
			break;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   964
		if (group_next(xdfo, &go))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   965
			xdl_bug("group sync broken moving to next group");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   966
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   967
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   968
	if (!group_next(xdfo, &go))
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   969
		xdl_bug("group sync broken at end of file");
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   970
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   971
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   972
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   973
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   974
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   975
int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   976
	xdchange_t *cscr = NULL, *xch;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   977
	char *rchg1 = xe->xdf1.rchg, *rchg2 = xe->xdf2.rchg;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   978
	long i1, i2, l1, l2;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   979
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   980
	/*
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   981
	 * Trivial. Collects "groups" of changes and creates an edit script.
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   982
	 */
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   983
	for (i1 = xe->xdf1.nrec, i2 = xe->xdf2.nrec; i1 >= 0 || i2 >= 0; i1--, i2--)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   984
		if (rchg1[i1 - 1] || rchg2[i2 - 1]) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   985
			for (l1 = i1; rchg1[i1 - 1]; i1--);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   986
			for (l2 = i2; rchg2[i2 - 1]; i2--);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   987
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   988
			if (!(xch = xdl_add_change(cscr, i1, i2, l1 - i1, l2 - i2))) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   989
				xdl_free_script(cscr);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   990
				return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   991
			}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   992
			cscr = xch;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   993
		}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   994
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   995
	*xscr = cscr;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   996
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   997
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   998
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
   999
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1000
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1001
void xdl_free_script(xdchange_t *xscr) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1002
	xdchange_t *xch;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1003
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1004
	while ((xch = xscr) != NULL) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1005
		xscr = xscr->next;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1006
		xdl_free(xch);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1007
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1008
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1009
36771
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1010
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1011
/*
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1012
 * Starting at the passed change atom, find the latest change atom to be included
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1013
 * inside the differential hunk according to the specified configuration.
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1014
 * Also advance xscr if the first changes must be discarded.
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1015
 */
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1016
xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1017
{
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1018
	xdchange_t *xch, *xchp, *lxch;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1019
	long max_common = 0;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1020
	long max_ignorable = 0;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1021
	unsigned long ignored = 0; /* number of ignored blank lines */
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1022
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1023
	/* remove ignorable changes that are too far before other changes */
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1024
	for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1025
		xch = xchp->next;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1026
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1027
		if (xch == NULL ||
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1028
		    xch->i1 - (xchp->i1 + xchp->chg1) >= max_ignorable)
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1029
			*xscr = xch;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1030
	}
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1031
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1032
	if (*xscr == NULL)
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1033
		return NULL;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1034
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1035
	lxch = *xscr;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1036
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1037
	for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1038
		long distance = xch->i1 - (xchp->i1 + xchp->chg1);
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1039
		if (distance > max_common)
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1040
			break;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1041
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1042
		if (distance < max_ignorable && (!xch->ignore || lxch == xchp)) {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1043
			lxch = xch;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1044
			ignored = 0;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1045
		} else if (distance < max_ignorable && xch->ignore) {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1046
			ignored += xch->chg2;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1047
		} else if (lxch != xchp &&
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1048
			   xch->i1 + ignored - (lxch->i1 + lxch->chg1) > max_common) {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1049
			break;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1050
		} else if (!xch->ignore) {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1051
			lxch = xch;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1052
			ignored = 0;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1053
		} else {
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1054
			ignored += xch->chg2;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1055
		}
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1056
	}
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1057
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1058
	return lxch;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1059
}
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1060
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1061
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1062
static int xdl_call_hunk_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1063
			      xdemitconf_t const *xecfg)
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1064
{
36828
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1065
	long p = xe->nprefix, s = xe->nsuffix;
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1066
	xdchange_t *xch, *xche;
36771
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1067
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1068
	if (!xecfg->hunk_func)
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1069
		return -1;
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1070
36702
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1071
	if ((xecfg->flags & XDL_EMIT_BDIFFHUNK) != 0) {
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1072
		long i1 = 0, i2 = 0, n1 = xe->xdf1.nrec, n2 = xe->xdf2.nrec;
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1073
		for (xch = xscr; xch; xch = xche->next) {
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1074
			xche = xdl_get_hunk(&xch, xecfg);
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1075
			if (!xch)
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1076
				break;
36828
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1077
			if (xch != xche)
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1078
				xdl_bug("xch != xche");
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1079
			xch->i1 += p;
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1080
			xch->i2 += p;
36702
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1081
			if (xch->i1 > i1 || xch->i2 > i2) {
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1082
				if (xecfg->hunk_func(i1, xch->i1, i2, xch->i2, ecb->priv) < 0)
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1083
					return -1;
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1084
			}
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1085
			i1 = xche->i1 + xche->chg1;
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1086
			i2 = xche->i2 + xche->chg2;
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1087
		}
36828
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1088
		if (xecfg->hunk_func(i1, n1 + p + s, i2, n2 + p + s,
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1089
				     ecb->priv) < 0)
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1090
			return -1;
36702
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1091
	} else {
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1092
		for (xch = xscr; xch; xch = xche->next) {
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1093
			xche = xdl_get_hunk(&xch, xecfg);
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1094
			if (!xch)
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1095
				break;
36828
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1096
			if (xecfg->hunk_func(xch->i1 + p,
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1097
					xche->i1 + xche->chg1 - xch->i1,
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1098
					xch->i2 + p,
f33a87cf60cc xdiff: add a preprocessing step that trims files
Jun Wu <quark@fb.com>
parents: 36771
diff changeset
  1099
					xche->i2 + xche->chg2 - xch->i2,
36702
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1100
					ecb->priv) < 0)
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1101
				return -1;
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1102
		}
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1103
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1104
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1105
}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1106
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1107
int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1108
	     xdemitconf_t const *xecfg, xdemitcb_t *ecb) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1109
	xdchange_t *xscr;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1110
	xdfenv_t xe;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1111
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1112
	if (xdl_do_diff(mf1, mf2, xpp, &xe) < 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1113
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1114
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1115
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1116
	if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 ||
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1117
	    xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 ||
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1118
	    xdl_build_script(&xe, &xscr) < 0) {
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1119
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1120
		xdl_free_env(&xe);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1121
		return -1;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1122
	}
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1123
36771
90f8fe72446c xdiff: remove xemit related logic
Jun Wu <quark@fb.com>
parents: 36769
diff changeset
  1124
	if (xdl_call_hunk_func(&xe, xscr, ecb, xecfg) < 0) {
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1125
		xdl_free_script(xscr);
36702
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1126
		xdl_free_env(&xe);
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1127
		return -1;
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1128
	}
36702
b3c9c483cac9 xdiff: add a bdiff hunk mode
Jun Wu <quark@fb.com>
parents: 36701
diff changeset
  1129
	xdl_free_script(xscr);
36700
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1130
	xdl_free_env(&xe);
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1131
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1132
	return 0;
34e2ff1f9cd8 xdiff: vendor xdiff library from git
Jun Wu <quark@fb.com>
parents:
diff changeset
  1133
}