From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: Simon Ruderich <simon@ruderich.org>,
Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>,
git <git@vger.kernel.org>
Subject: Re: [PATCH v2 1/3] diffcore-pickaxe: remove unnecessary call to get_textconv()
Date: Thu, 04 Apr 2013 14:10:22 -0700 [thread overview]
Message-ID: <7vmwtegfy9.fsf@alter.siamese.dyndns.org> (raw)
In-Reply-To: <7vvc82ggy3.fsf@alter.siamese.dyndns.org> (Junio C. Hamano's message of "Thu, 04 Apr 2013 13:48:52 -0700")
Junio C Hamano <gitster@pobox.com> writes:
> Perhaps...
>
> The fill_one() function is responsible for finding and
> filling the textconv filter as necessary, and is called by
> diff_grep() function that implements "git log -G<pattern>".
>
> The has_changes() function calls get_textconv() for two
> sides being compared, before it checks to see if it was
> asked to perform the pickaxe limiting with the -S option.
> Move the code around to avoid this wastage. After that,
> fill_one() is called to use the textconv.
>
> By adding get_textconv() to diff_grep() and relieving
> fill_one() of responsibility to find the textconv filter, we
> can avoid calling get_textconv() twice.
>
> Explained that way, it makes me wonder why we cannot fix it the
> other way around, that is, not fetching textconv in has_changes()
> and instead letting fill_one() to find textconv as needed.
>
> The answer is because has_changes() itself looks at the textconv.
>
> But we have to wonder why it is so. diff_grep() short-circuits when
> the two sides are identical and has_changes() has a similar but
> different logic to check if the identical two sides are processed
> with the same textconv filter before saying this filepair is
> uninteresting.
>
> Shouldn't that logic be unified as well?
That is, something along this line. We may want to unify these two
functions even more, but I do not offhand see a good way to do so.
-- >8 --
Subject: [PATCH] log -S/-G: unify the short-cut logic a bit more
The fill_one() function is responsible for finding and filling the
textconv filter as necessary, and is called by diff_grep() function
that implements "git log -G<pattern>".
The has_changes() function calls get_textconv() for two sides being
compared, before it checks to see if it was asked to perform the
pickaxe limiting with the -S option. Move the code around to avoid
this wastage.
By adding get_textconv() to diff_grep() and relieving fill_one() of
responsibility to find the textconv filter, we can avoid calling
get_textconv() twice; fill_one() no longer has to be passed a
pointer to a pointer to textconv.
The reason has_changes() calls get_textconv() early is because it
wants to compare two textconv filters on both sides. When comparing
the two sides that are otherwise identical, if the same textconv
applies to both sides, we know pickaxe (either -S or -G) would not
find anything before applying the textconv and comparing the result.
Teach the same short-circuit logic to diff_grep() as well. The code
in these two functions become more similar as the result.
---
diffcore-pickaxe.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index b097fa7..6d285a7 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -75,11 +75,10 @@ static void diffgrep_consume(void *priv, char *line, unsigned long len)
}
static void fill_one(struct diff_filespec *one,
- mmfile_t *mf, struct userdiff_driver **textconv)
+ mmfile_t *mf, struct userdiff_driver *textconv)
{
if (DIFF_FILE_VALID(one)) {
- *textconv = get_textconv(one);
- mf->size = fill_textconv(*textconv, one, &mf->ptr);
+ mf->size = fill_textconv(textconv, one, &mf->ptr);
} else {
memset(mf, 0, sizeof(*mf));
}
@@ -94,11 +93,24 @@ static int diff_grep(struct diff_filepair *p, struct diff_options *o,
mmfile_t mf1, mf2;
int hit;
- if (diff_unmodified_pair(p))
+ if (!o->pickaxe[0])
return 0;
- fill_one(p->one, &mf1, &textconv_one);
- fill_one(p->two, &mf2, &textconv_two);
+ textconv_one = get_textconv(p->one);
+ textconv_two = get_textconv(p->two);
+
+ /*
+ * If we have an unmodified pair, we know that the count will be the
+ * same and don't even have to load the blobs. Unless textconv is in
+ * play, _and_ we are using two different textconv filters (e.g.,
+ * because a pair is an exact rename with different textconv attributes
+ * for each side, which might generate different content).
+ */
+ if (textconv_one == textconv_two && diff_unmodified_pair(p))
+ return 0;
+
+ fill_one(p->one, &mf1, textconv_one);
+ fill_one(p->two, &mf2, textconv_two);
if (!mf1.ptr) {
if (!mf2.ptr)
@@ -131,6 +143,8 @@ static int diff_grep(struct diff_filepair *p, struct diff_options *o,
free(mf1.ptr);
if (textconv_two)
free(mf2.ptr);
+ diff_free_filespec_data(p->one);
+ diff_free_filespec_data(p->two);
return hit;
}
@@ -201,14 +215,17 @@ static unsigned int contains(mmfile_t *mf, struct diff_options *o,
static int has_changes(struct diff_filepair *p, struct diff_options *o,
regex_t *regexp, kwset_t kws)
{
- struct userdiff_driver *textconv_one = get_textconv(p->one);
- struct userdiff_driver *textconv_two = get_textconv(p->two);
+ struct userdiff_driver *textconv_one = NULL;
+ struct userdiff_driver *textconv_two = NULL;
mmfile_t mf1, mf2;
int ret;
if (!o->pickaxe[0])
return 0;
+ textconv_one = get_textconv(p->one);
+ textconv_two = get_textconv(p->two);
+
/*
* If we have an unmodified pair, we know that the count will be the
* same and don't even have to load the blobs. Unless textconv is in
@@ -219,8 +236,8 @@ static int has_changes(struct diff_filepair *p, struct diff_options *o,
if (textconv_one == textconv_two && diff_unmodified_pair(p))
return 0;
- fill_one(p->one, &mf1, &textconv_one);
- fill_one(p->two, &mf2, &textconv_two);
+ fill_one(p->one, &mf1, textconv_one);
+ fill_one(p->two, &mf2, textconv_two);
if (!mf1.ptr) {
if (!mf2.ptr)
--
1.8.2-634-g203ba97
next prev parent reply other threads:[~2013-04-04 21:10 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-04 8:34 [BUG] git log -S not respecting --no-textconv Matthieu Moy
2013-04-04 16:03 ` [PATCH 1/2] diffcore-pickaxe: respect --no-textconv Simon Ruderich
2013-04-04 17:03 ` Matthieu Moy
2013-04-04 17:43 ` Jeff King
2013-04-04 17:45 ` Junio C Hamano
2013-04-04 17:51 ` Jeff King
2013-04-04 18:10 ` Junio C Hamano
2013-04-04 20:20 ` [PATCH v2 1/3] diffcore-pickaxe: remove unnecessary call to get_textconv() Simon Ruderich
2013-04-04 20:48 ` Junio C Hamano
2013-04-04 21:10 ` Junio C Hamano [this message]
2013-04-04 21:11 ` Jeff King
2013-04-04 22:51 ` Junio C Hamano
2013-04-05 13:20 ` Simon Ruderich
2013-04-04 20:21 ` [PATCH v2 2/3] diffcore-pickaxe: remove fill_one() Simon Ruderich
2013-04-05 0:08 ` Jeff King
2013-04-05 4:43 ` Junio C Hamano
2013-04-05 4:45 ` [PATCH 1/3] diffcore-pickaxe: port optimization from has_changes() to diff_grep() Junio C Hamano
2013-04-05 4:45 ` [PATCH 2/3] diffcore-pickaxe: fix leaks in "log -S<block>" and "log -G<pattern>" Junio C Hamano
2013-04-05 4:45 ` [PATCH 3/3] diffcore-pickaxe: unify setup and teardown code between log -S/-G Junio C Hamano
2013-04-05 5:28 ` Jeff King
2013-04-05 5:43 ` Junio C Hamano
2013-04-05 5:45 ` Jeff King
2013-04-05 16:44 ` Junio C Hamano
2013-04-04 20:21 ` [PATCH v2 3/3] diffcore-pickaxe: respect --no-textconv Simon Ruderich
2013-04-05 7:40 ` Matthieu Moy
2013-04-05 13:16 ` [PATCH v3 " Simon Ruderich
2013-04-05 17:31 ` Junio C Hamano
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=7vmwtegfy9.fsf@alter.siamese.dyndns.org \
--to=gitster@pobox.com \
--cc=Matthieu.Moy@grenoble-inp.fr \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
--cc=simon@ruderich.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.