@matheusbsbs / matheus-bagliano / commits / eb46328e18
Fork 0

Avoid rescanning unchanged entries in search for copies.

Repeatedly comparing the same entry against the same set of blobs in search for copies is quite pointless. This huge waste of effort can be avoided using a flag in the blame_entry structure. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Alexander Gavrilov committed Jul 16, 2008 at 02:05 UTC eb46328e18688cdc3e0daaffc15c1bfc717c7527
1 file changed +19 -2
builtin-blame.c
+19 -2
@@ -153,6 +153,10 @@ struct blame_entry {
153 */
154 char guilty;
155
156 + /* true if the entry has been scanned for copies in the current parent
157 + */
158 + char scanned;
159 +
160 /* the line number of the first line of this group in the
161 * suspect's file; internally all line numbers are 0 based.
162 */
@@ -1040,18 +1044,28 @@ static struct blame_list *setup_blame_list(struct scoreboard *sb,
1044 struct blame_list *blame_list = NULL;
1045
1046 for (e = sb->ent, num_ents = 0; e; e = e->next)
1043 - if (!e->guilty && same_suspect(e->suspect, target))
1047 + if (!e->scanned && !e->guilty && same_suspect(e->suspect, target))
1048 num_ents++;
1049 if (num_ents) {
1050 blame_list = xcalloc(num_ents, sizeof(struct blame_list));
1051 for (e = sb->ent, i = 0; e; e = e->next)
1048 - if (!e->guilty && same_suspect(e->suspect, target))
1052 + if (!e->scanned && !e->guilty && same_suspect(e->suspect, target))
1053 blame_list[i++].ent = e;
1054 }
1055 *num_ents_p = num_ents;
1056 return blame_list;
1057 }
1058
1059 +/*
1060 + * Reset the scanned status on all entries.
1061 + */
1062 +static void reset_scanned_flag(struct scoreboard *sb)
1063 +{
1064 + struct blame_entry *e;
1065 + for (e = sb->ent; e; e = e->next)
1066 + e->scanned = 0;
1067 +}
1068 +
1069 /*
1070 * For lines target is suspected for, see if we can find code movement
1071 * across file boundary from the parent commit. porigin is the path
@@ -1144,6 +1158,8 @@ static int find_copy_in_parent(struct scoreboard *sb,
1158 split_blame(sb, split, blame_list[j].ent);
1159 made_progress = 1;
1160 }
1161 + else
1162 + blame_list[j].ent->scanned = 1;
1163 decref_split(split);
1164 }
1165 free(blame_list);
@@ -1156,6 +1172,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
1172 break;
1173 }
1174 }
1175 + reset_scanned_flag(sb);
1176 diff_flush(&diff_opts);
1177 diff_tree_release_paths(&diff_opts);
1178 return retval;