From: Thomas Rast <trast@student.ethz.ch>
To: <git@vger.kernel.org>
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Bo Yang" <struggleyb.nku@gmail.com>,
"Zbigniew Jędrzejewski-Szmek" <zbyszek@in.waw.pl>,
"Will Palmer" <wmpalmer@gmail.com>,
"Antoine Pelisse" <apelisse@gmail.com>
Subject: [PATCH v10 5/5] Speed up log -L... -M
Date: Thu, 28 Mar 2013 17:47:34 +0100 [thread overview]
Message-ID: <03ec60dc6569672539a6e857c946287d85140c3b.1364488205.git.trast@inf.ethz.ch> (raw)
In-Reply-To: <cover.1364488205.git.trast@inf.ethz.ch>
So far log -L only used the implicit diff filtering by pathspec. If
the user specifies -M, we cannot do that, and so we simply handed the
whole diff queue (which is approximately 'git show --raw') to
diffcore_std().
Unfortunately this is very slow. We can optimize a lot if we throw
out files that we know cannot possibly be interesting, in the same
spirit that the pathspec filtering reduces the number of files.
However, in this case, we have to be more careful. Because we want to
look out for renames, we need to keep all filepairs where something
was deleted.
This is a bit hacky and should really be replaced by equivalent
support in --follow, and just using that. However, in the meantime it
speeds up 'log -M -L' by an order of magnitude.
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
line-log.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 52 insertions(+), 4 deletions(-)
diff --git a/line-log.c b/line-log.c
index 68972e2..30edef4 100644
--- a/line-log.c
+++ b/line-log.c
@@ -750,7 +750,50 @@ static void move_diff_queue(struct diff_queue_struct *dst,
DIFF_QUEUE_CLEAR(src);
}
-static void queue_diffs(struct diff_options *opt,
+static void filter_diffs_for_paths(struct line_log_data *range, int keep_deletions)
+{
+ int i;
+ struct diff_queue_struct outq;
+ DIFF_QUEUE_CLEAR(&outq);
+
+ for (i = 0; i < diff_queued_diff.nr; i++) {
+ struct diff_filepair *p = diff_queued_diff.queue[i];
+ struct line_log_data *rg = NULL;
+
+ if (!DIFF_FILE_VALID(p->two)) {
+ if (keep_deletions)
+ diff_q(&outq, p);
+ else
+ diff_free_filepair(p);
+ continue;
+ }
+ for (rg = range; rg; rg = rg->next) {
+ if (!strcmp(rg->spec->path, p->two->path))
+ break;
+ }
+ if (rg)
+ diff_q(&outq, p);
+ else
+ diff_free_filepair(p);
+ }
+ free(diff_queued_diff.queue);
+ diff_queued_diff = outq;
+}
+
+static inline int diff_might_be_rename(void)
+{
+ int i;
+ for (i = 0; i < diff_queued_diff.nr; i++)
+ if (!DIFF_FILE_VALID(diff_queued_diff.queue[i]->one)) {
+ /* fprintf(stderr, "diff_might_be_rename found creation of: %s\n", */
+ /* diff_queued_diff.queue[i]->two->path); */
+ return 1;
+ }
+ return 0;
+}
+
+static void queue_diffs(struct line_log_data *range,
+ struct diff_options *opt,
struct diff_queue_struct *queue,
struct commit *commit, struct commit *parent)
{
@@ -766,7 +809,12 @@ static void queue_diffs(struct diff_options *opt,
DIFF_QUEUE_CLEAR(&diff_queued_diff);
diff_tree(&desc1, &desc2, "", opt);
- diffcore_std(opt);
+ if (opt->detect_rename) {
+ filter_diffs_for_paths(range, 1);
+ if (diff_might_be_rename())
+ diffcore_std(opt);
+ filter_diffs_for_paths(range, 0);
+ }
move_diff_queue(queue, &diff_queued_diff);
if (tree1)
@@ -1050,7 +1098,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c
if (commit->parents)
parent = commit->parents->item;
- queue_diffs(&rev->diffopt, &queue, commit, parent);
+ queue_diffs(range, &rev->diffopt, &queue, commit, parent);
changed = process_all_files(&parent_range, rev, &queue, range);
if (parent)
add_line_range(rev, parent, parent_range);
@@ -1075,7 +1123,7 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
for (i = 0; i < nparents; i++) {
parents[i] = p->item;
p = p->next;
- queue_diffs(&rev->diffopt, &diffqueues[i], commit, parents[i]);
+ queue_diffs(range, &rev->diffopt, &diffqueues[i], commit, parents[i]);
}
for (i = 0; i < nparents; i++) {
--
1.8.2.446.g2b4de83
next prev parent reply other threads:[~2013-03-28 16:48 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-21 12:52 [PATCH v9 0/5] git log -L Thomas Rast
2013-03-21 12:52 ` [PATCH v9 1/5] Refactor parse_loc Thomas Rast
2013-03-21 12:52 ` [PATCH v9 2/5] Export rewrite_parents() for 'log -L' Thomas Rast
2013-03-21 12:52 ` [PATCH v9 3/5] Implement line-history search (git log -L) Thomas Rast
2013-03-21 19:05 ` Junio C Hamano
2013-03-23 6:00 ` Thomas Rast
2013-03-21 12:52 ` [PATCH v9 4/5] log -L: :pattern:file syntax to find by funcname Thomas Rast
2013-03-21 12:52 ` [PATCH v9 5/5] Speed up log -L... -M Thomas Rast
2013-03-21 21:11 ` Eric Sunshine
2013-03-23 5:58 ` Thomas Rast
2013-03-23 9:04 ` Jeff King
2013-03-24 7:38 ` Eric Sunshine
2013-03-23 6:44 ` [PATCH v9a 0/5] git log -L Thomas Rast
2013-03-23 6:44 ` [PATCH v9a 1/5] Refactor parse_loc Thomas Rast
2013-03-23 6:44 ` [PATCH v9a 2/5] Export rewrite_parents() for 'log -L' Thomas Rast
2013-03-23 6:44 ` [PATCH v9a 3/5] Implement line-history search (git log -L) Thomas Rast
2013-03-23 10:31 ` Antoine Pelisse
2013-03-23 10:32 ` Antoine Pelisse
2013-03-28 16:47 ` [PATCH v10 0/5] git log -L Thomas Rast
2013-03-28 16:47 ` [PATCH v10 1/5] Refactor parse_loc Thomas Rast
2013-03-28 16:47 ` [PATCH v10 2/5] Export rewrite_parents() for 'log -L' Thomas Rast
2013-03-28 16:47 ` [PATCH v10 3/5] Implement line-history search (git log -L) Thomas Rast
2013-03-28 16:47 ` [PATCH v10 4/5] log -L: :pattern:file syntax to find by funcname Thomas Rast
2013-03-28 16:47 ` Thomas Rast [this message]
2013-03-23 6:44 ` [PATCH v9a " Thomas Rast
2013-03-23 6:44 ` [PATCH v9a 5/5] Speed up log -L... -M Thomas Rast
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=03ec60dc6569672539a6e857c946287d85140c3b.1364488205.git.trast@inf.ethz.ch \
--to=trast@student.ethz.ch \
--cc=apelisse@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=struggleyb.nku@gmail.com \
--cc=wmpalmer@gmail.com \
--cc=zbyszek@in.waw.pl \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).