Skip to content

Commit 913b45f

Browse files
committed
xdi_diff: trim common trailing lines
This implements earlier Linus's optimization to trim common lines at the end before passing them down to low level xdiff interface for all of our xdiff users. We could later enhance this to also trim common leading lines, but that would need tweaking the output function to add the number of lines trimmed at the beginning to line numbers that appear in the hunk headers. Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent c279d7e commit 913b45f

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

xdiff-interface.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,41 @@ int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
103103
return 0;
104104
}
105105

106+
/*
107+
* Trim down common substring at the end of the buffers,
108+
* but leave at least ctx lines at the end.
109+
*/
110+
static void trim_common_tail(mmfile_t *a, mmfile_t *b, int ctx)
111+
{
112+
const int blk = 1024;
113+
long trimmed = 0, recovered = 0;
114+
int i;
115+
char *ap = a->ptr + a->size;
116+
char *bp = b->ptr + b->size;
117+
long smaller = (a->size < b->size) ? a->size : b->size;
118+
119+
while (blk + trimmed <= smaller && !memcmp(ap - blk, bp - blk, blk)) {
120+
trimmed += blk;
121+
ap -= blk;
122+
bp -= blk;
123+
}
124+
125+
for (i = 0, recovered = 0; recovered < trimmed && i <= ctx; i++) {
126+
while (recovered < trimmed && ap[recovered] != '\n')
127+
recovered++;
128+
}
129+
a->size -= (trimmed - recovered);
130+
b->size -= (trimmed - recovered);
131+
}
132+
106133
int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *xecb)
107134
{
108-
return xdl_diff(mf1, mf2, xpp, xecfg, xecb);
135+
mmfile_t a = *mf1;
136+
mmfile_t b = *mf2;
137+
138+
trim_common_tail(&a, &b, xecfg->ctxlen);
139+
140+
return xdl_diff(&a, &b, xpp, xecfg, xecb);
109141
}
110142

111143
int read_mmfile(mmfile_t *ptr, const char *filename)

0 commit comments

Comments
 (0)