diffcore-delta: stop using deltifier for packing.
[git/gitweb.git] / diffcore-delta.c
blobd03787be65be82b0fcd6dc62dae77013b2576c80
1 #include "cache.h"
2 #include "diff.h"
3 #include "diffcore.h"
5 struct linehash {
6 unsigned long bytes;
7 unsigned long hash;
8 };
10 static unsigned long hash_extended_line(const unsigned char **buf_p,
11 unsigned long left)
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;
20 while (left) {
21 unsigned c = *buf++;
22 if (!c)
23 goto binary;
24 left--;
25 if (' ' < c) {
26 hashval = c;
27 break;
30 while (left) {
31 unsigned c = *buf++;
32 if (!c)
33 goto binary;
34 left--;
35 if (c == '\n')
36 break;
37 if (' ' < c)
38 hashval = hashval * 11 + c;
40 *buf_p = buf;
41 return hashval;
43 binary:
44 *buf_p = NULL;
45 return 0;
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;
54 return 0;
57 static struct linehash *hash_lines(const unsigned char *buf,
58 unsigned long size)
60 const unsigned char *eobuf = buf + size;
61 struct linehash *line = NULL;
62 int alloc = 0, used = 0;
64 while (buf < eobuf) {
65 const unsigned char *ptr = buf;
66 unsigned long hash = hash_extended_line(&buf, eobuf-ptr);
67 if (!buf) {
68 free(line);
69 return NULL;
71 if (alloc <= used) {
72 alloc = alloc_nr(alloc);
73 line = xrealloc(line, sizeof(*line) * alloc);
75 line[used].bytes = buf - ptr;
76 line[used].hash = hash;
77 used++;
79 qsort(line, used, sizeof(*line), linehash_compare);
81 /* Terminate the list */
82 if (alloc <= used)
83 line = xrealloc(line, sizeof(*line) * (used+1));
84 line[used].bytes = line[used].hash = 0;
85 return line;
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;
95 unsigned long sc, la;
97 src_lines = hash_lines(src, src_size);
98 if (!src_lines)
99 return -1;
100 dst_lines = hash_lines(dst, dst_size);
101 if (!dst_lines) {
102 free(src_lines);
103 return -1;
105 sc = la = 0;
106 while (src_lines->bytes && dst_lines->bytes) {
107 int cmp = linehash_compare(src_lines, dst_lines);
108 if (!cmp) {
109 sc += src_lines->bytes;
110 src_lines++;
111 dst_lines++;
112 continue;
114 if (cmp < 0) {
115 src_lines++;
116 continue;
118 la += dst_lines->bytes;
119 dst_lines++;
121 while (dst_lines->bytes) {
122 la += dst_lines->bytes;
123 dst_lines++;
125 *src_copied = sc;
126 *literal_added = la;
127 return 0;