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
;