@matheusbsbs / matheus-bagliano / commits / 733070bea9
Fork 0

xdiff: give up scanning similar lines early

In a corner case of large files whose lines do not match uniquely, the loop to eliminate a line that matches multiple locations adjacent to a run of lines that do not uniquely match wasted too much cycles. Fix this by giving up early after scanning 100 lines in both direction. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Davide Libenzi committed Nov 7, 2008 at 21:24 UTC 733070bea9ce28d557f0b0950acc05b3fe6ff6c6
1 file changed +13 -2
xdiff/xprepare.c
+13 -2
@@ -23,10 +23,9 @@
23 #include "xinclude.h"
24
25
26 -
26 #define XDL_KPDIS_RUN 4
27 #define XDL_MAX_EQLIMIT 1024
29 -
28 +#define XDL_SIMSCAN_WINDOW 100
29
30
31 typedef struct s_xdlclass {
@@ -312,6 +311,18 @@ void xdl_free_env(xdfenv_t *xe) {
311 static int xdl_clean_mmatch(char const *dis, long i, long s, long e) {
312 long r, rdis0, rpdis0, rdis1, rpdis1;
313
314 + /*
315 + * Limits the window the is examined during the similar-lines
316 + * scan. The loops below stops when dis[i - r] == 1 (line that
317 + * has no match), but there are corner cases where the loop
318 + * proceed all the way to the extremities by causing huge
319 + * performance penalties in case of big files.
320 + */
321 + if (i - s > XDL_SIMSCAN_WINDOW)
322 + s = i - XDL_SIMSCAN_WINDOW;
323 + if (e - i > XDL_SIMSCAN_WINDOW)
324 + e = i + XDL_SIMSCAN_WINDOW;
325 +
326 /*
327 * Scans the lines before 'i' to find a run of lines that either
328 * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1).