]> git.ipfire.org Git - thirdparty/git.git/commitdiff
diff --color-moved: shrink potential moved blocks as we go
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Thu, 9 Dec 2021 10:30:05 +0000 (10:30 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 9 Dec 2021 21:24:06 +0000 (13:24 -0800)
Rather than setting `match` to NULL and then looping over the list of
potential matched blocks for a second time to remove blocks with no
matches just filter out the blocks with no matches as we go.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff.c

diff --git a/diff.c b/diff.c
index 51f092e724ecd478a1a8a4e6fa3062a9b11f9253..626fd47aa0e0480165f2f45224b3fb961ce01f65 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -996,12 +996,12 @@ static void add_lines_to_move_detection(struct diff_options *o,
 static void pmb_advance_or_null(struct diff_options *o,
                                struct emitted_diff_symbol *l,
                                struct moved_block *pmb,
-                               int pmb_nr)
+                               int *pmb_nr)
 {
-       int i;
+       int i, j;
        unsigned flags = o->color_moved_ws_handling & XDF_WHITESPACE_FLAGS;
 
-       for (i = 0; i < pmb_nr; i++) {
+       for (i = 0, j = 0; i < *pmb_nr; i++) {
                int match;
                struct moved_entry *prev = pmb[i].match;
                struct moved_entry *cur = (prev && prev->next_line) ?
@@ -1015,38 +1015,12 @@ static void pmb_advance_or_null(struct diff_options *o,
                        match = cur &&
                                xdiff_compare_lines(cur->es->line, cur->es->len,
                                                    l->line, l->len, flags);
-               if (match)
-                       pmb[i].match = cur;
-               else
-                       moved_block_clear(&pmb[i]);
-       }
-}
-
-static int shrink_potential_moved_blocks(struct moved_block *pmb,
-                                        int pmb_nr)
-{
-       int lp, rp;
-
-       /* Shrink the set of potential block to the remaining running */
-       for (lp = 0, rp = pmb_nr - 1; lp <= rp;) {
-               while (lp < pmb_nr && pmb[lp].match)
-                       lp++;
-               /* lp points at the first NULL now */
-
-               while (rp > -1 && !pmb[rp].match)
-                       rp--;
-               /* rp points at the last non-NULL */
-
-               if (lp < pmb_nr && rp > -1 && lp < rp) {
-                       pmb[lp] = pmb[rp];
-                       memset(&pmb[rp], 0, sizeof(pmb[rp]));
-                       rp--;
-                       lp++;
+               if (match) {
+                       pmb[j] = pmb[i];
+                       pmb[j++].match = cur;
                }
        }
-
-       /* Remember the number of running sets */
-       return rp + 1;
+       *pmb_nr = j;
 }
 
 static void fill_potential_moved_blocks(struct diff_options *o,
@@ -1181,9 +1155,7 @@ static void mark_color_as_moved(struct diff_options *o,
                        continue;
                }
 
-               pmb_advance_or_null(o, l, pmb, pmb_nr);
-
-               pmb_nr = shrink_potential_moved_blocks(pmb, pmb_nr);
+               pmb_advance_or_null(o, l, pmb, &pmb_nr);
 
                if (pmb_nr == 0) {
                        int contiguous = adjust_last_block(o, n, block_length);