Patchwork D2634: [DRAFT] xdiff: avoid hashing trimmed lines

login
register
mail settings
Submitter phabricator
Date March 4, 2018, 4:21 a.m.
Message ID <differential-rev-PHID-DREV-hycrgjc3sfzmkmt7nghe-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/28905/
State Superseded
Headers show

Comments

phabricator - March 4, 2018, 4:21 a.m.
quark created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  Things are a bit faster now:
  
    hg perfbdiff --count 3000 --blocks --xdiff .hg/store/data/mercurial/commands.py.i 1
    # before
    ! wall 1.510821 comb 1.500000 user 1.500000 sys 0.000000 (best of 6)
    # after
    ! wall 1.025628 comb 1.020000 user 1.020000 sys 0.000000 (best of 8)

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2634

AFFECTED FILES
  mercurial/thirdparty/xdiff/xprepare.c
  mercurial/thirdparty/xdiff/xutils.c
  mercurial/thirdparty/xdiff/xutils.h

CHANGE DETAILS




To: quark, #hg-reviewers
Cc: mercurial-devel
phabricator - March 5, 2018, 12:50 a.m.
quark abandoned this revision.
quark added a comment.


  https://phab.mercurial-scm.org/D2686 is a better fix

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2634

To: quark, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/mercurial/thirdparty/xdiff/xutils.h b/mercurial/thirdparty/xdiff/xutils.h
--- a/mercurial/thirdparty/xdiff/xutils.h
+++ b/mercurial/thirdparty/xdiff/xutils.h
@@ -34,6 +34,7 @@ 
 long xdl_guess_lines(mmfile_t *mf, long sample);
 int xdl_blankline(const char *line, long size, long flags);
 int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
+void xdl_next_record(char const **data, char const *top);
 unsigned long xdl_hash_record(char const **data, char const *top, long flags);
 unsigned int xdl_hashbits(unsigned int size);
 int xdl_num_out(char *out, long val);
diff --git a/mercurial/thirdparty/xdiff/xutils.c b/mercurial/thirdparty/xdiff/xutils.c
--- a/mercurial/thirdparty/xdiff/xutils.c
+++ b/mercurial/thirdparty/xdiff/xutils.c
@@ -298,6 +298,15 @@ 
 	return ha;
 }
 
+inline void xdl_next_record(char const **data, char const *top) {
+	char const *next = memchr(*data, '\n', top - *data);
+	if (next) {
+		*data = next + 1;
+	} else {
+		*data = top;
+	}
+}
+
 unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
 	unsigned long ha = 5381;
 	char const *ptr = *data;
diff --git a/mercurial/thirdparty/xdiff/xprepare.c b/mercurial/thirdparty/xdiff/xprepare.c
--- a/mercurial/thirdparty/xdiff/xprepare.c
+++ b/mercurial/thirdparty/xdiff/xprepare.c
@@ -181,7 +181,7 @@ 
 	if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
 		for (top = blk + bsize; cur < top; ) {
 			prev = cur;
-			hav = xdl_hash_record(&cur, top, xpp->flags);
+			xdl_next_record(&cur, top);
 			if (nrec >= narec) {
 				narec *= 2;
 				if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
@@ -192,7 +192,7 @@ 
 				goto abort;
 			crec->ptr = prev;
 			crec->size = (long) (cur - prev);
-			crec->ha = hav;
+			crec->ha = 0;
 			recs[nrec++] = crec;
 		}
 	}
@@ -243,7 +243,7 @@ 
 
 	unsigned int hbits;
 	long hsize;
-	long i;
+	long i, j;
 	long start = xdf->dstart - reserved;
 	long end = xdf->dend + reserved;
 
@@ -261,6 +261,16 @@ 
 	memset(rhash, 0, hsize * sizeof(xrecord_t *));
 
 	for (i = start; i <= end; i++) {
+		{
+			unsigned long ha = 5381;
+			char const *ptr = xdf->recs[i]->ptr;
+
+			for (j = 0; j < xdf->recs[i]->size; ++j) {
+				ha += (ha << 5);
+				ha ^= (unsigned long)ptr[j];
+			}
+			xdf->recs[i]->ha = ha;
+		}
 		if (xdl_classify_record(pass, cf, rhash, hbits, xdf->recs[i]) < 0)
 			goto abort;
 	}