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;