diff mercurial/bdiff.c @ 2584:1f4703115e28

merge with crew
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Sun, 09 Jul 2006 14:42:18 +0200
parents fa76c5d609c9
children c4325f0a9b91
line wrap: on
line diff
--- a/mercurial/bdiff.c
+++ b/mercurial/bdiff.c
@@ -65,7 +65,7 @@ static inline uint32_t rol32(uint32_t wo
 
 int splitlines(const char *a, int len, struct line **lr)
 {
-	int h, i;
+	int g, h, i;
 	const char *p, *b = a;
 	struct line *l;
 
@@ -82,7 +82,16 @@ int splitlines(const char *a, int len, s
 	/* build the line array and calculate hashes */
 	h = 0;
 	for (p = a; p < a + len; p++) {
-		h = *p + rol32(h, 7); /* a simple hash from GNU diff */
+		/*
+		 * a simple hash from GNU diff, with better collision
+		 * resistance from hashpjw. this slows down common
+		 * case by 10%, but speeds up worst case by 100x.
+		 */
+		h = *p + rol32(h, 7);
+		if ((g = h & 0xf0000000)) {
+			h ^= g >> 24;
+			h ^= g;
+		}
 		if (*p == '\n' || p == a + len - 1) {
 			l->len = p - b + 1;
 			l->h = h * l->len;