summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0fd9d7e)
raw | patch | inline | side by side (parent: 0fd9d7e)
author | Davide Libenzi <davidel@xmailserver.org> | |
Sat, 8 Nov 2008 05:24:33 +0000 (21:24 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Wed, 3 Dec 2008 07:45:37 +0000 (23:45 -0800) |
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>
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>
xdiff/xprepare.c | patch | blob | history |
diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c
index e87ab57c652b56b1a684e2a0a56885c1d1b27ef7..a43aa72cd088af07b13a6bc8de304ecc178047e5 100644 (file)
--- a/xdiff/xprepare.c
+++ b/xdiff/xprepare.c
#include "xinclude.h"
-
#define XDL_KPDIS_RUN 4
#define XDL_MAX_EQLIMIT 1024
-
+#define XDL_SIMSCAN_WINDOW 100
typedef struct s_xdlclass {
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).