diff options
author | Jeff King <peff@peff.net> | 2012-10-25 06:42:36 -0400 |
---|---|---|
committer | Jeff King <peff@peff.net> | 2012-10-25 06:42:36 -0400 |
commit | 70d1825749ba1528af507e27ba5f8a660a5ede3d (patch) | |
tree | c036a00d0b86ef7faa76b2b3e11acf43127eb7e3 /attr.c | |
parent | 315ea32f1bd57b884f654f6f8a965af9b5e4d8ee (diff) | |
parent | 4742d136e2c8423ce17ccd0ccf161d9f20d49847 (diff) | |
download | git-70d1825749ba1528af507e27ba5f8a660a5ede3d.tar.gz |
Merge branch 'nd/attr-match-optim'
Trivial and obvious optimization for finding attributes that match
a given path.
* nd/attr-match-optim:
attr: avoid searching for basename on every match
attr: avoid strlen() on every match
Diffstat (limited to 'attr.c')
-rw-r--r-- | attr.c | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -277,6 +277,7 @@ static struct match_attr *parse_attr_line(const char *line, const char *src, static struct attr_stack { struct attr_stack *prev; char *origin; + size_t originlen; unsigned num_matches; unsigned alloc; struct match_attr **attrs; @@ -535,6 +536,7 @@ static void bootstrap_attr_stack(void) if (!is_bare_repository() || direction == GIT_ATTR_INDEX) { elem = read_attr(GITATTRIBUTES_FILE, 1); elem->origin = xstrdup(""); + elem->originlen = 0; elem->prev = attr_stack; attr_stack = elem; debug_push(elem); @@ -628,7 +630,7 @@ static void prepare_attr_stack(const char *path) strbuf_addstr(&pathbuf, GITATTRIBUTES_FILE); elem = read_attr(pathbuf.buf, 0); strbuf_setlen(&pathbuf, cp - path); - elem->origin = strbuf_detach(&pathbuf, NULL); + elem->origin = strbuf_detach(&pathbuf, &elem->originlen); elem->prev = attr_stack; attr_stack = elem; debug_push(elem); @@ -645,13 +647,11 @@ static void prepare_attr_stack(const char *path) } static int path_matches(const char *pathname, int pathlen, + const char *basename, const char *pattern, const char *base, int baselen) { if (!strchr(pattern, '/')) { - /* match basename */ - const char *basename = strrchr(pathname, '/'); - basename = basename ? basename + 1 : pathname; return (fnmatch_icase(pattern, basename, 0) == 0); } /* @@ -693,7 +693,8 @@ static int fill_one(const char *what, struct match_attr *a, int rem) return rem; } -static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem) +static int fill(const char *path, int pathlen, const char *basename, + struct attr_stack *stk, int rem) { int i; const char *base = stk->origin ? stk->origin : ""; @@ -702,8 +703,8 @@ static int fill(const char *path, int pathlen, struct attr_stack *stk, int rem) struct match_attr *a = stk->attrs[i]; if (a->is_macro) continue; - if (path_matches(path, pathlen, - a->u.pattern, base, strlen(base))) + if (path_matches(path, pathlen, basename, + a->u.pattern, base, stk->originlen)) rem = fill_one("fill", a, rem); } return rem; @@ -741,15 +742,19 @@ static void collect_all_attrs(const char *path) { struct attr_stack *stk; int i, pathlen, rem; + const char *basename; prepare_attr_stack(path); for (i = 0; i < attr_nr; i++) check_all_attr[i].value = ATTR__UNKNOWN; + basename = strrchr(path, '/'); + basename = basename ? basename + 1 : path; + pathlen = strlen(path); rem = attr_nr; for (stk = attr_stack; 0 < rem && stk; stk = stk->prev) - rem = fill(path, pathlen, stk, rem); + rem = fill(path, pathlen, basename, stk, rem); } int git_check_attr(const char *path, int num, struct git_attr_check *check) |