diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2008-07-16 02:05:20 +0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-07-15 16:38:32 -0700 |
commit | eb46328e18688cdc3e0daaffc15c1bfc717c7527 (patch) | |
tree | 8c4c2795b587771227a6de4bdca3758e6e4ba714 | |
parent | 6c11a5fd465eb64301093de8826c38018b474bde (diff) | |
download | git-eb46328e18688cdc3e0daaffc15c1bfc717c7527.tar.gz git-eb46328e18688cdc3e0daaffc15c1bfc717c7527.tar.xz |
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>
-rw-r--r-- | builtin-blame.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/builtin-blame.c b/builtin-blame.c index 06c7de429..7ac1a3767 100644 --- a/builtin-blame.c +++ b/builtin-blame.c @@ -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,12 +1044,12 @@ 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; @@ -1053,6 +1057,16 @@ static struct blame_list *setup_blame_list(struct scoreboard *sb, } /* + * 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 * in the parent we already tried. @@ -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; |