mercurial/bdiff.c
changeset 2577 fa76c5d609c9
parent 2543 860e9c83fc59
child 2600 c4325f0a9b91
equal deleted inserted replaced
2576:6a961a54f953 2577:fa76c5d609c9
    63         return (word << shift) | (word >> (32 - shift));
    63         return (word << shift) | (word >> (32 - shift));
    64 }
    64 }
    65 
    65 
    66 int splitlines(const char *a, int len, struct line **lr)
    66 int splitlines(const char *a, int len, struct line **lr)
    67 {
    67 {
    68 	int h, i;
    68 	int g, h, i;
    69 	const char *p, *b = a;
    69 	const char *p, *b = a;
    70 	struct line *l;
    70 	struct line *l;
    71 
    71 
    72 	/* count the lines */
    72 	/* count the lines */
    73 	i = 1; /* extra line for sentinel */
    73 	i = 1; /* extra line for sentinel */
    80 		return -1;
    80 		return -1;
    81 
    81 
    82 	/* build the line array and calculate hashes */
    82 	/* build the line array and calculate hashes */
    83 	h = 0;
    83 	h = 0;
    84 	for (p = a; p < a + len; p++) {
    84 	for (p = a; p < a + len; p++) {
    85 		h = *p + rol32(h, 7); /* a simple hash from GNU diff */
    85 		/*
       
    86 		 * a simple hash from GNU diff, with better collision
       
    87 		 * resistance from hashpjw. this slows down common
       
    88 		 * case by 10%, but speeds up worst case by 100x.
       
    89 		 */
       
    90 		h = *p + rol32(h, 7);
       
    91 		if ((g = h & 0xf0000000)) {
       
    92 			h ^= g >> 24;
       
    93 			h ^= g;
       
    94 		}
    86 		if (*p == '\n' || p == a + len - 1) {
    95 		if (*p == '\n' || p == a + len - 1) {
    87 			l->len = p - b + 1;
    96 			l->len = p - b + 1;
    88 			l->h = h * l->len;
    97 			l->h = h * l->len;
    89 			l->l = b;
    98 			l->l = b;
    90 			l->n = -1;
    99 			l->n = -1;