summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2012-06-01 12:22:09 -0700
committerJunio C Hamano <gitster@pobox.com>2012-06-03 16:08:25 -0700
commit93921b07e985de38f7af6689d81e5c7dfb3f8aa0 (patch)
tree09fdb1fb43f1ec6d80bc8b8bc83be99d8dc276b2
parenteb41775ecc031cd8e38aebbd26826d74922a0db9 (diff)
downloadgit-93921b07e985de38f7af6689d81e5c7dfb3f8aa0.tar.gz
ls-files -i: micro-optimize path_excluded()
As we know a caller that does not recurse is calling us in the index order, we can remember the last directory we found to be excluded and see if the path we are looking at is still inside it, in which case we can just answer that it is excluded. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--dir.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/dir.c b/dir.c
index c3f08849bc..839bc9f61c 100644
--- a/dir.c
+++ b/dir.c
@@ -592,11 +592,25 @@ void path_exclude_check_clear(struct path_exclude_check *check)
strbuf_release(&check->path);
}
+/*
+ * Is the ce->name excluded? This is for a caller like show_files() that
+ * do not honor directory hierarchy and iterate through paths that are
+ * possibly in an ignored directory.
+ *
+ * A path to a directory known to be excluded is left in check->path to
+ * optimize for repeated checks for files in the same excluded directory.
+ */
int path_excluded(struct path_exclude_check *check, struct cache_entry *ce)
{
int i, dtype;
struct strbuf *path = &check->path;
+ if (path->len &&
+ path->len <= ce_namelen(ce) &&
+ !memcmp(ce->name, path->buf, path->len) &&
+ (!ce->name[path->len] || ce->name[path->len] == '/'))
+ return 1;
+
strbuf_setlen(path, 0);
for (i = 0; ce->name[i]; i++) {
int ch = ce->name[i];
@@ -608,6 +622,10 @@ int path_excluded(struct path_exclude_check *check, struct cache_entry *ce)
}
strbuf_addch(path, ch);
}
+
+ /* An entry in the index; cannot be a directory with subentries */
+ strbuf_setlen(path, 0);
+
dtype = ce_to_dtype(ce);
return excluded(check->dir, ce->name, &dtype);
}