10 static unsigned long hash_extended_line(const unsigned char **buf_p,
13 /* An extended line is zero or more whitespace letters (including LF)
14 * followed by one non whitespace letter followed by zero or more
15 * non LF, and terminated with by a LF (or EOF).
17 const unsigned char *bol = *buf_p;
18 const unsigned char *buf = bol;
19 unsigned long hashval = 0;
38 hashval = hashval * 11 + c;
48 static int linehash_compare(const void *a_, const void *b_)
50 struct linehash *a = (struct linehash *) a_;
51 struct linehash *b = (struct linehash *) b_;
52 if (a->hash < b->hash) return -1;
53 if (a->hash > b->hash) return 1;
57 static struct linehash *hash_lines(const unsigned char *buf,
60 const unsigned char *eobuf = buf + size;
61 struct linehash *line = NULL;
62 int alloc = 0, used = 0;
65 const unsigned char *ptr = buf;
66 unsigned long hash = hash_extended_line(&buf, eobuf-ptr);
72 alloc = alloc_nr(alloc);
73 line = xrealloc(line, sizeof(*line) * alloc);
75 line[used].bytes = buf - ptr;
76 line[used].hash = hash;
79 qsort(line, used, sizeof(*line), linehash_compare);
81 /* Terminate the list */
83 line = xrealloc(line, sizeof(*line) * (used+1));
84 line[used].bytes = line[used].hash = 0;
88 int diffcore_count_changes(void *src, unsigned long src_size,
89 void *dst, unsigned long dst_size,
90 unsigned long delta_limit,
91 unsigned long *src_copied,
92 unsigned long *literal_added)
94 struct linehash *src_lines, *dst_lines;
97 src_lines = hash_lines(src, src_size);
100 dst_lines = hash_lines(dst, dst_size);
106 while (src_lines->bytes && dst_lines->bytes) {
107 int cmp = linehash_compare(src_lines, dst_lines);
109 sc += src_lines->bytes;
118 la += dst_lines->bytes;
121 while (dst_lines->bytes) {
122 la += dst_lines->bytes;