From: Davide Libenzi Date: Sat, 8 Nov 2008 05:24:33 +0000 (-0800) Subject: xdiff: give up scanning similar lines early X-Git-Tag: v1.6.1-rc1~60^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9b28d55401a529ff08c709f42f66e765c93b0a20;p=git.git 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 --- diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index e87ab57c6..a43aa72cd 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -23,10 +23,9 @@ #include "xinclude.h" - #define XDL_KPDIS_RUN 4 #define XDL_MAX_EQLIMIT 1024 - +#define XDL_SIMSCAN_WINDOW 100 typedef struct s_xdlclass { @@ -312,6 +311,18 @@ void xdl_free_env(xdfenv_t *xe) { static int xdl_clean_mmatch(char const *dis, long i, long s, long e) { long r, rdis0, rpdis0, rdis1, rpdis1; + /* + * Limits the window the is examined during the similar-lines + * scan. The loops below stops when dis[i - r] == 1 (line that + * has no match), but there are corner cases where the loop + * proceed all the way to the extremities by causing huge + * performance penalties in case of big files. + */ + if (i - s > XDL_SIMSCAN_WINDOW) + s = i - XDL_SIMSCAN_WINDOW; + if (e - i > XDL_SIMSCAN_WINDOW) + e = i + XDL_SIMSCAN_WINDOW; + /* * Scans the lines before 'i' to find a run of lines that either * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1).