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>
This commit is contained in:
Alexander Gavrilov
2008-07-16 02:05:20 +04:00
committed by Junio C Hamano
parent 6c11a5fd46
commit eb46328e18

View File

@ -153,6 +153,10 @@ struct blame_entry {
*/
char guilty;
/* true if the entry has been scanned for copies in the current parent
*/
char scanned;
/* the line number of the first line of this group in the
* suspect's file; internally all line numbers are 0 based.
*/
@ -1040,18 +1044,28 @@ static struct blame_list *setup_blame_list(struct scoreboard *sb,
struct blame_list *blame_list = NULL;
for (e = sb->ent, num_ents = 0; e; e = e->next)
if (!e->guilty && same_suspect(e->suspect, target))
if (!e->scanned && !e->guilty && same_suspect(e->suspect, target))
num_ents++;
if (num_ents) {
blame_list = xcalloc(num_ents, sizeof(struct blame_list));
for (e = sb->ent, i = 0; e; e = e->next)
if (!e->guilty && same_suspect(e->suspect, target))
if (!e->scanned && !e->guilty && same_suspect(e->suspect, target))
blame_list[i++].ent = e;
}
*num_ents_p = num_ents;
return blame_list;
}
/*
* Reset the scanned status on all entries.
*/
static void reset_scanned_flag(struct scoreboard *sb)
{
struct blame_entry *e;
for (e = sb->ent; e; e = e->next)
e->scanned = 0;
}
/*
* For lines target is suspected for, see if we can find code movement
* across file boundary from the parent commit. porigin is the path
@ -1144,6 +1158,8 @@ static int find_copy_in_parent(struct scoreboard *sb,
split_blame(sb, split, blame_list[j].ent);
made_progress = 1;
}
else
blame_list[j].ent->scanned = 1;
decref_split(split);
}
free(blame_list);
@ -1156,6 +1172,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
break;
}
}
reset_scanned_flag(sb);
diff_flush(&diff_opts);
diff_tree_release_paths(&diff_opts);
return retval;