From: Junio C Hamano Date: Mon, 10 Oct 2011 22:56:20 +0000 (-0700) Subject: Merge branch 'dm/tree-walk' X-Git-Tag: v1.7.8-rc0~102 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/4909bbe40af6dd12bc4aeb6b9e449a9e29641a26?ds=inline;hp=-c Merge branch 'dm/tree-walk' * dm/tree-walk: tree-walk: micro-optimization in tree_entry_interesting tree-walk: drop unused parameter from match_dir_prefix --- 4909bbe40af6dd12bc4aeb6b9e449a9e29641a26 diff --combined tree-walk.c index a8d8a66d59,f386151ce3..418107ec83 --- a/tree-walk.c +++ b/tree-walk.c @@@ -309,18 -309,6 +309,18 @@@ static void free_extended_entry(struct } } +static inline int prune_traversal(struct name_entry *e, + struct traverse_info *info, + struct strbuf *base, + int still_interesting) +{ + if (!info->pathspec || still_interesting == 2) + return 2; + if (still_interesting < 0) + return still_interesting; + return tree_entry_interesting(e, base, 0, info->pathspec); +} + int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) { int ret = 0; @@@ -328,23 -316,15 +328,23 @@@ struct name_entry *entry = xmalloc(n*sizeof(*entry)); int i; struct tree_desc_x *tx = xcalloc(n, sizeof(*tx)); + struct strbuf base = STRBUF_INIT; + int interesting = 1; for (i = 0; i < n; i++) tx[i].d = t[i]; + if (info->prev) { + strbuf_grow(&base, info->pathlen); + make_traverse_path(base.buf, info->prev, &info->name); + base.buf[info->pathlen-1] = '/'; + strbuf_setlen(&base, info->pathlen); + } for (;;) { unsigned long mask, dirmask; const char *first = NULL; int first_len = 0; - struct name_entry *e; + struct name_entry *e = NULL; int len; for (i = 0; i < n; i++) { @@@ -396,22 -376,16 +396,22 @@@ mask |= 1ul << i; if (S_ISDIR(entry[i].mode)) dirmask |= 1ul << i; + e = &entry[i]; } if (!mask) break; - ret = info->fn(n, mask, dirmask, entry, info); - if (ret < 0) { - error = ret; - if (!info->show_all_errors) - break; + interesting = prune_traversal(e, info, &base, interesting); + if (interesting < 0) + break; + if (interesting) { + ret = info->fn(n, mask, dirmask, entry, info); + if (ret < 0) { + error = ret; + if (!info->show_all_errors) + break; + } + mask &= ret; } - mask &= ret; ret = 0; for (i = 0; i < n; i++) if (mask & (1ul << i)) @@@ -421,7 -395,6 +421,7 @@@ for (i = 0; i < n; i++) free_extended_entry(tx + i); free(tx); + strbuf_release(&base); return error; } @@@ -549,7 -522,7 +549,7 @@@ static int match_entry(const struct nam return 0; } - static int match_dir_prefix(const char *base, int baselen, + static int match_dir_prefix(const char *base, const char *match, int matchlen) { if (strncmp(base, match, matchlen)) @@@ -606,7 -579,7 +606,7 @@@ int tree_entry_interesting(const struc if (baselen >= matchlen) { /* If it doesn't match, move along... */ - if (!match_dir_prefix(base_str, baselen, match, matchlen)) + if (!match_dir_prefix(base_str, match, matchlen)) goto match_wildcards; if (!ps->recursive || ps->max_depth == -1) @@@ -618,14 -591,14 +618,14 @@@ ps->max_depth); } - /* Does the base match? */ - if (!strncmp(base_str, match, baselen)) { + /* Either there must be no base, or the base must match. */ + if (baselen == 0 || !strncmp(base_str, match, baselen)) { if (match_entry(entry, pathlen, match + baselen, matchlen - baselen, &never_interesting)) return 1; - if (ps->items[i].has_wildcard) { + if (ps->items[i].use_wildcard) { if (!fnmatch(match + baselen, entry->path, 0)) return 1; @@@ -641,7 -614,7 +641,7 @@@ } match_wildcards: - if (!ps->items[i].has_wildcard) + if (!ps->items[i].use_wildcard) continue; /*