Improve tree_entry_interesting() handling code

t_e_i() can return -1 or 2 to early shortcut a search. Current code
may use up to two variables to handle it. One for saving return value
from t_e_i temporarily, one for saving return code 2.

The second variable is not needed. If we make sure the first variable
does not change until the next t_e_i() call, then we can do something
like this:

int ret = 0;

while (...) {
	if (ret != 2) {
		ret = t_e_i();
		if (ret < 0) /* no longer interesting */
			break;
		if (ret == 0) /* skip this round */
			continue;
	}
	/* ret > 0, interesting */
}

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2011-03-25 16:34:20 +07:00 committed by Junio C Hamano
parent f0096c06bc
commit 97d0b74a49
3 changed files with 33 additions and 50 deletions

View File

@ -521,18 +521,18 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len) struct tree_desc *tree, struct strbuf *base, int tn_len)
{ {
int hit = 0, matched = 0; int hit = 0, match = 0;
struct name_entry entry; struct name_entry entry;
int old_baselen = base->len; int old_baselen = base->len;
while (tree_entry(tree, &entry)) { while (tree_entry(tree, &entry)) {
int te_len = tree_entry_len(entry.path, entry.sha1); int te_len = tree_entry_len(entry.path, entry.sha1);
if (matched != 2) { if (match != 2) {
matched = tree_entry_interesting(&entry, base, tn_len, pathspec); match = tree_entry_interesting(&entry, base, tn_len, pathspec);
if (matched == -1) if (match < 0)
break; /* no more matches */ break;
if (!matched) if (match == 0)
continue; continue;
} }

View File

@ -68,7 +68,7 @@ static void process_tree(struct rev_info *revs,
struct tree_desc desc; struct tree_desc desc;
struct name_entry entry; struct name_entry entry;
struct name_path me; struct name_path me;
int all_interesting = (revs->diffopt.pathspec.nr == 0); int match = revs->diffopt.pathspec.nr == 0 ? 2 : 0;
int baselen = base->len; int baselen = base->len;
if (!revs->tree_objects) if (!revs->tree_objects)
@ -85,7 +85,7 @@ static void process_tree(struct rev_info *revs,
me.elem = name; me.elem = name;
me.elem_len = strlen(name); me.elem_len = strlen(name);
if (!all_interesting) { if (!match) {
strbuf_addstr(base, name); strbuf_addstr(base, name);
if (base->len) if (base->len)
strbuf_addch(base, '/'); strbuf_addch(base, '/');
@ -94,17 +94,13 @@ static void process_tree(struct rev_info *revs,
init_tree_desc(&desc, tree->buffer, tree->size); init_tree_desc(&desc, tree->buffer, tree->size);
while (tree_entry(&desc, &entry)) { while (tree_entry(&desc, &entry)) {
if (!all_interesting) { if (match != 2) {
int showit = tree_entry_interesting(&entry, match = tree_entry_interesting(&entry, base, 0,
base, 0, &revs->diffopt.pathspec);
&revs->diffopt.pathspec); if (match < 0)
if (showit < 0)
break; break;
else if (!showit) if (match == 0)
continue; continue;
else if (showit == 2)
all_interesting = 1;
} }
if (S_ISDIR(entry.mode)) if (S_ISDIR(entry.mode))

View File

@ -65,23 +65,17 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2,
static void show_tree(struct diff_options *opt, const char *prefix, static void show_tree(struct diff_options *opt, const char *prefix,
struct tree_desc *desc, struct strbuf *base) struct tree_desc *desc, struct strbuf *base)
{ {
int all_interesting = 0; int match = 0;
while (desc->size) { for (; desc->size; update_tree_entry(desc)) {
int show; if (match != 2) {
match = tree_entry_interesting(&desc->entry, base, 0,
if (all_interesting) &opt->pathspec);
show = 1; if (match < 0)
else { break;
show = tree_entry_interesting(&desc->entry, base, 0, if (match == 0)
&opt->pathspec); continue;
if (show == 2)
all_interesting = 1;
} }
if (show < 0) show_entry(opt, prefix, desc, base);
break;
if (show)
show_entry(opt, prefix, desc, base);
update_tree_entry(desc);
} }
} }
@ -121,20 +115,16 @@ static void show_entry(struct diff_options *opt, const char *prefix,
} }
static void skip_uninteresting(struct tree_desc *t, struct strbuf *base, static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
struct diff_options *opt, int *all_interesting) struct diff_options *opt, int *match)
{ {
while (t->size) { while (t->size) {
int show = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec); *match = tree_entry_interesting(&t->entry, base, 0, &opt->pathspec);
if (show == 2) if (*match) {
*all_interesting = 1; if (*match < 0)
if (!show) { t->size = 0;
update_tree_entry(t); break;
continue;
} }
/* Skip it all? */ update_tree_entry(t);
if (show < 0)
t->size = 0;
return;
} }
} }
@ -143,8 +133,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
{ {
struct strbuf base; struct strbuf base;
int baselen = strlen(base_str); int baselen = strlen(base_str);
int all_t1_interesting = 0; int t1_match = 0, t2_match = 0;
int all_t2_interesting = 0;
/* Enable recursion indefinitely */ /* Enable recursion indefinitely */
opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE); opt->pathspec.recursive = DIFF_OPT_TST(opt, RECURSIVE);
@ -158,10 +147,8 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2,
DIFF_OPT_TST(opt, HAS_CHANGES)) DIFF_OPT_TST(opt, HAS_CHANGES))
break; break;
if (opt->pathspec.nr) { if (opt->pathspec.nr) {
if (!all_t1_interesting) skip_uninteresting(t1, &base, opt, &t1_match);
skip_uninteresting(t1, &base, opt, &all_t1_interesting); skip_uninteresting(t2, &base, opt, &t2_match);
if (!all_t2_interesting)
skip_uninteresting(t2, &base, opt, &all_t2_interesting);
} }
if (!t1->size) { if (!t1->size) {
if (!t2->size) if (!t2->size)