prep_exclude is only necessary when we enter or leave a directory. Now
it's called for every entry in a directory. With this patch, the
number of prep_exclude calls in webkit.git goes from 188k down to
11k. This patch does not make exclude any faster, but it prepares for
making prep_exclude heavier in terms of computation, where a large
number of calls may have bigger impacts.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 dir.c | 10 +++++++++-
 dir.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index 58739f3..f8f7a7e 100644
--- a/dir.c
+++ b/dir.c
@@ -804,7 +804,10 @@ static struct exclude *last_exclude_matching(struct 
dir_struct *dir,
        basename = (basename) ? basename+1 : pathname;
 
        START_CLOCK();
-       prep_exclude(dir, pathname, basename-pathname);
+       if (!dir->exclude_prepared) {
+               prep_exclude(dir, pathname, basename-pathname);
+               dir->exclude_prepared = 1;
+       }
        STOP_CLOCK(tv_prep_exclude);
 
        START_CLOCK();
@@ -894,6 +897,7 @@ struct exclude *last_exclude_matching_path(struct 
path_exclude_check *check,
 
                if (ch == '/') {
                        int dt = DT_DIR;
+                       check->dir->exclude_prepared = 0;
                        exclude = last_exclude_matching(check->dir,
                                                        path->buf, path->len,
                                                        &dt);
@@ -908,6 +912,7 @@ struct exclude *last_exclude_matching_path(struct 
path_exclude_check *check,
        /* An entry in the index; cannot be a directory with subentries */
        strbuf_setlen(path, 0);
 
+       check->dir->exclude_prepared = 0;
        return last_exclude_matching(check->dir, name, namelen, dtype);
 }
 
@@ -1394,6 +1399,7 @@ static int read_directory_recursive(struct dir_struct 
*dir,
        if (!fdir)
                goto out;
 
+       dir->exclude_prepared = 0;
        while ((de = readdir(fdir)) != NULL) {
                switch (treat_path(dir, de, &path, baselen, simplify)) {
                case path_recurse:
@@ -1415,6 +1421,7 @@ static int read_directory_recursive(struct dir_struct 
*dir,
        }
        closedir(fdir);
  out:
+       dir->exclude_prepared = 0;
        strbuf_release(&path);
 
        return contents;
@@ -1486,6 +1493,7 @@ static int treat_leading_path(struct dir_struct *dir,
                        break;
                if (simplify_away(sb.buf, sb.len, simplify))
                        break;
+               dir->exclude_prepared = 0;
                if (treat_one_path(dir, &sb, simplify,
                                   DT_DIR, NULL) == path_ignored)
                        break; /* do not recurse into it */
diff --git a/dir.h b/dir.h
index 560ade4..0748407 100644
--- a/dir.h
+++ b/dir.h
@@ -86,6 +86,7 @@ struct dir_struct {
 
        /* Exclude info */
        const char *exclude_per_dir;
+       int exclude_prepared;
 
        /*
         * We maintain three groups of exclude pattern lists:
-- 
1.8.1.2.536.gf441e6d

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to