X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=diffcore-delta.c;h=1e6a6911ecc7b9a6b6c28a20db9adea3e1238a2d;hb=c150462824008957f568ca7aa05a65b35d860eb9;hp=d03787be65be82b0fcd6dc62dae77013b2576c80;hpb=09a278e6b906d3902f3b75ec183a06b0c029d27b;p=git.git diff --git a/diffcore-delta.c b/diffcore-delta.c index d03787be..1e6a6911 100644 --- a/diffcore-delta.c +++ b/diffcore-delta.c @@ -1,88 +1,32 @@ #include "cache.h" #include "diff.h" #include "diffcore.h" - -struct linehash { - unsigned long bytes; - unsigned long hash; -}; - -static unsigned long hash_extended_line(const unsigned char **buf_p, - unsigned long left) -{ - /* An extended line is zero or more whitespace letters (including LF) - * followed by one non whitespace letter followed by zero or more - * non LF, and terminated with by a LF (or EOF). - */ - const unsigned char *bol = *buf_p; - const unsigned char *buf = bol; - unsigned long hashval = 0; - while (left) { - unsigned c = *buf++; - if (!c) - goto binary; - left--; - if (' ' < c) { - hashval = c; - break; - } - } - while (left) { - unsigned c = *buf++; - if (!c) - goto binary; - left--; - if (c == '\n') - break; - if (' ' < c) - hashval = hashval * 11 + c; - } - *buf_p = buf; - return hashval; - - binary: - *buf_p = NULL; - return 0; -} - -static int linehash_compare(const void *a_, const void *b_) -{ - struct linehash *a = (struct linehash *) a_; - struct linehash *b = (struct linehash *) b_; - if (a->hash < b->hash) return -1; - if (a->hash > b->hash) return 1; - return 0; -} - -static struct linehash *hash_lines(const unsigned char *buf, - unsigned long size) +#include "delta.h" +#include "count-delta.h" + +static int diffcore_count_changes_1(void *src, unsigned long src_size, + void *dst, unsigned long dst_size, + unsigned long delta_limit, + unsigned long *src_copied, + unsigned long *literal_added) { - const unsigned char *eobuf = buf + size; - struct linehash *line = NULL; - int alloc = 0, used = 0; + void *delta; + unsigned long delta_size; + + delta = diff_delta(src, src_size, + dst, dst_size, + &delta_size, delta_limit); + if (!delta) + /* If delta_limit is exceeded, we have too much differences */ + return -1; - while (buf < eobuf) { - const unsigned char *ptr = buf; - unsigned long hash = hash_extended_line(&buf, eobuf-ptr); - if (!buf) { - free(line); - return NULL; - } - if (alloc <= used) { - alloc = alloc_nr(alloc); - line = xrealloc(line, sizeof(*line) * alloc); - } - line[used].bytes = buf - ptr; - line[used].hash = hash; - used++; + /* Estimate the edit size by interpreting delta. */ + if (count_delta(delta, delta_size, src_copied, literal_added)) { + free(delta); + return -1; } - qsort(line, used, sizeof(*line), linehash_compare); - - /* Terminate the list */ - if (alloc <= used) - line = xrealloc(line, sizeof(*line) * (used+1)); - line[used].bytes = line[used].hash = 0; - return line; + free(delta); + return 0; } int diffcore_count_changes(void *src, unsigned long src_size, @@ -91,38 +35,9 @@ int diffcore_count_changes(void *src, unsigned long src_size, unsigned long *src_copied, unsigned long *literal_added) { - struct linehash *src_lines, *dst_lines; - unsigned long sc, la; - - src_lines = hash_lines(src, src_size); - if (!src_lines) - return -1; - dst_lines = hash_lines(dst, dst_size); - if (!dst_lines) { - free(src_lines); - return -1; - } - sc = la = 0; - while (src_lines->bytes && dst_lines->bytes) { - int cmp = linehash_compare(src_lines, dst_lines); - if (!cmp) { - sc += src_lines->bytes; - src_lines++; - dst_lines++; - continue; - } - if (cmp < 0) { - src_lines++; - continue; - } - la += dst_lines->bytes; - dst_lines++; - } - while (dst_lines->bytes) { - la += dst_lines->bytes; - dst_lines++; - } - *src_copied = sc; - *literal_added = la; - return 0; + return diffcore_count_changes_1(src, src_size, + dst, dst_size, + delta_limit, + src_copied, + literal_added); }