| 167 | } |
| 168 | |
| 169 | int diffcore_count_changes(struct repository *r, |
| 170 | struct diff_filespec *src, |
| 171 | struct diff_filespec *dst, |
| 172 | void **src_count_p, |
| 173 | void **dst_count_p, |
| 174 | unsigned long *src_copied, |
| 175 | unsigned long *literal_added) |
| 176 | { |
| 177 | struct spanhash *s, *d; |
| 178 | struct spanhash_top *src_count, *dst_count; |
| 179 | unsigned long sc, la; |
| 180 | |
| 181 | src_count = dst_count = NULL; |
| 182 | if (src_count_p) |
| 183 | src_count = *src_count_p; |
| 184 | if (!src_count) { |
| 185 | src_count = hash_chars(r, src); |
| 186 | if (src_count_p) |
| 187 | *src_count_p = src_count; |
| 188 | } |
| 189 | if (dst_count_p) |
| 190 | dst_count = *dst_count_p; |
| 191 | if (!dst_count) { |
| 192 | dst_count = hash_chars(r, dst); |
| 193 | if (dst_count_p) |
| 194 | *dst_count_p = dst_count; |
| 195 | } |
| 196 | sc = la = 0; |
| 197 | |
| 198 | s = src_count->data; |
| 199 | d = dst_count->data; |
| 200 | for (;;) { |
| 201 | unsigned dst_cnt, src_cnt; |
| 202 | if (!s->cnt) |
| 203 | break; /* we checked all in src */ |
| 204 | while (d->cnt) { |
| 205 | if (d->hashval >= s->hashval) |
| 206 | break; |
| 207 | la += d->cnt; |
| 208 | d++; |
| 209 | } |
| 210 | src_cnt = s->cnt; |
| 211 | dst_cnt = 0; |
| 212 | if (d->cnt && d->hashval == s->hashval) { |
| 213 | dst_cnt = d->cnt; |
| 214 | d++; |
| 215 | } |
| 216 | if (src_cnt < dst_cnt) { |
| 217 | la += dst_cnt - src_cnt; |
| 218 | sc += src_cnt; |
| 219 | } |
| 220 | else |
| 221 | sc += dst_cnt; |
| 222 | s++; |
| 223 | } |
| 224 | while (d->cnt) { |
| 225 | la += d->cnt; |
| 226 | d++; |
no test coverage detected