Skip to content

Commit

Permalink
xdi_diff: trim common trailing lines
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Junio C Hamano committed Dec 14, 2007
1 parent c279d7e commit 913b45f
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion xdiff-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,41 @@ int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf)
return 0;
}

/*
* Trim down common substring at the end of the buffers,
* but leave at least ctx lines at the end.
*/
static void trim_common_tail(mmfile_t *a, mmfile_t *b, int ctx)
{
const int blk = 1024;
long trimmed = 0, recovered = 0;
int i;
char *ap = a->ptr + a->size;
char *bp = b->ptr + b->size;
long smaller = (a->size < b->size) ? a->size : b->size;

while (blk + trimmed <= smaller && !memcmp(ap - blk, bp - blk, blk)) {
trimmed += blk;
ap -= blk;
bp -= blk;
}

for (i = 0, recovered = 0; recovered < trimmed && i <= ctx; i++) {
while (recovered < trimmed && ap[recovered] != '\n')
recovered++;
}
a->size -= (trimmed - recovered);
b->size -= (trimmed - recovered);
}

int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *xecb)
{
return xdl_diff(mf1, mf2, xpp, xecfg, xecb);
mmfile_t a = *mf1;
mmfile_t b = *mf2;

trim_common_tail(&a, &b, xecfg->ctxlen);

return xdl_diff(&a, &b, xpp, xecfg, xecb);
}

int read_mmfile(mmfile_t *ptr, const char *filename)
Expand Down

0 comments on commit 913b45f

Please sign in to comment.