Instead of index_name_exists() calculating a hash for full pathname
for every entry, we calculate partial hash per directory, use it as a
seed. The number of characters that icase_hash has to chew will
reduce.

treat_leading_path:   0.000  0.000
read_directory:       1.296  1.235
+treat_one_path:      0.599  0.531
++is_excluded:        0.102  0.102
+++prep_exclude:      0.040  0.040
+++matching:          0.035  0.035
++dir_exist:          0.035  0.035
++index_name_exists:  0.292  0.225
lazy_init_name_hash:  0.155  0.155
+simplify_away:       0.082  0.083
+dir_add_name:        0.000  0.000

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 dir.c | 44 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 33 insertions(+), 11 deletions(-)

diff --git a/dir.c b/dir.c
index 5fda5af..8638dcd 100644
--- a/dir.c
+++ b/dir.c
@@ -46,6 +46,7 @@ struct path_simplify {
 
 static void read_directory_recursive(struct dir_struct *dir,
                                     const char *path, int len,
+                                    unsigned int hash,
                                     int check_only,
                                     const struct path_simplify *simplify,
                                     int *contents);
@@ -1044,12 +1045,17 @@ static struct dir_entry *dir_entry_new(const char 
*pathname, int len)
        return ent;
 }
 
-static struct dir_entry *dir_add_name(struct dir_struct *dir, const char 
*pathname, int len)
+static struct dir_entry *dir_add_name(struct dir_struct *dir,
+                                     const char *pathname, int len,
+                                     unsigned int hash, int baselen)
 {
        if (!(dir->flags & DIR_SHOW_IGNORED)) {
                struct cache_entry *ce;
                START_CLOCK();
-               ce = cache_name_exists(pathname, len, ignore_case);
+               ce = index_name_exists_base(&the_index,
+                                           hash, baselen,
+                                           pathname, len,
+                                           ignore_case);
                STOP_CLOCK(tv_index_name_exists);
                if (ce)
                        return NULL;
@@ -1225,7 +1231,9 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
        if ((dir->flags & DIR_SHOW_IGNORED) && !exclude) {
                dir->flags &= ~DIR_SHOW_IGNORED;
                dir->flags |= DIR_HIDE_EMPTY_DIRECTORIES;
-               read_directory_recursive(dir, dirname, len, 1, simplify, 
&contents);
+               read_directory_recursive(dir, dirname, len,
+                                        hash_name(dirname, len),
+                                        1, simplify, &contents);
                dir->flags &= ~DIR_HIDE_EMPTY_DIRECTORIES;
                dir->flags |= DIR_SHOW_IGNORED;
 
@@ -1234,7 +1242,9 @@ static enum directory_treatment treat_directory(struct 
dir_struct *dir,
        if (!(dir->flags & DIR_SHOW_IGNORED) &&
            !(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
                return show_directory;
-       read_directory_recursive(dir, dirname, len, 1, simplify, &contents);
+       read_directory_recursive(dir, dirname, len,
+                                hash_name(dirname, len),
+                                1, simplify, &contents);
        if (!contents)
                return ignore_directory;
        return show_directory;
@@ -1401,6 +1411,8 @@ enum path_treatment {
 
 static enum path_treatment treat_one_path(struct dir_struct *dir,
                                          struct strbuf *path,
+                                         unsigned int hash,
+                                         int baselen,
                                          const struct path_simplify *simplify,
                                          int dtype, struct dirent *de,
                                          int exclude_shortcut_ok)
@@ -1416,7 +1428,8 @@ static enum path_treatment treat_one_path(struct 
dir_struct *dir,
            dtype != DT_DIR) {
                struct cache_entry *ce;
                START_CLOCK();
-               ce = cache_name_exists(path->buf, path->len, ignore_case);
+               ce = index_name_exists_base(&the_index, hash, baselen,
+                                           path->buf, path->len, ignore_case);
                STOP_CLOCK(tv_index_name_exists);
                if (ce)
                        return path_ignored;
@@ -1467,6 +1480,7 @@ static enum path_treatment treat_one_path(struct 
dir_struct *dir,
 static enum path_treatment treat_path(struct dir_struct *dir,
                                      struct dirent *de,
                                      struct strbuf *path,
+                                     unsigned int hash,
                                      int baselen,
                                      const struct path_simplify *simplify,
                                      int exclude_shortcut_ok)
@@ -1485,7 +1499,8 @@ static enum path_treatment treat_path(struct dir_struct 
*dir,
 
        dtype = DTYPE(de);
        START_CLOCK();
-       ret = treat_one_path(dir, path, simplify, dtype, de, 
exclude_shortcut_ok);
+       ret = treat_one_path(dir, path, hash, baselen,
+                            simplify, dtype, de, exclude_shortcut_ok);
        STOP_CLOCK(tv_treat_one_path);
        return ret;
 }
@@ -1501,6 +1516,7 @@ static enum path_treatment treat_path(struct dir_struct 
*dir,
  */
 static void read_directory_recursive(struct dir_struct *dir,
                                     const char *base, int baselen,
+                                    unsigned int hash,
                                     int check_only,
                                     const struct path_simplify *simplify,
                                     int *contents)
@@ -1517,12 +1533,16 @@ static void read_directory_recursive(struct dir_struct 
*dir,
 
        dir->exclude_prepared = 0;
        while ((de = readdir(fdir)) != NULL) {
-               switch (treat_path(dir, de, &path, baselen,
+               switch (treat_path(dir, de, &path, hash, baselen,
                                   simplify,
                                   !check_only && !contents)) {
                case path_recurse:
                        read_directory_recursive(dir, path.buf,
-                                                path.len, 0,
+                                                path.len,
+                                                hash_name_from(hash,
+                                                               path.buf + 
baselen,
+                                                               path.len - 
baselen),
+                                                0,
                                                 simplify,
                                                 contents);
                        continue;
@@ -1543,7 +1563,7 @@ static void read_directory_recursive(struct dir_struct 
*dir,
                if (check_only)
                        break;
                START_CLOCK();
-               dir_add_name(dir, path.buf, path.len);
+               dir_add_name(dir, path.buf, path.len, hash, baselen);
                STOP_CLOCK(tv_dir_add_name);
        }
        closedir(fdir);
@@ -1619,7 +1639,7 @@ static int treat_leading_path(struct dir_struct *dir,
                if (simplify_away(sb.buf, sb.len, simplify))
                        break;
                dir->exclude_prepared = 0;
-               if (treat_one_path(dir, &sb, simplify,
+               if (treat_one_path(dir, &sb, 0, 0, simplify,
                                   DT_DIR, NULL, 0) == path_ignored)
                        break; /* do not recurse into it */
                if (len <= baselen) {
@@ -1648,7 +1668,9 @@ int read_directory(struct dir_struct *dir, const char 
*path, int len, const char
                STOP_CLOCK(tv_lazy_init_name_hash);
 #endif
                START_CLOCK();
-               read_directory_recursive(dir, path, len, 0, simplify, NULL);
+               read_directory_recursive(dir, path, len,
+                                        hash_name(path, len),
+                                        0, simplify, NULL);
                STOP_CLOCK(tv_read_directory);
        }
 #ifdef MEASURE_EXCLUDE
-- 
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