]> git.ipfire.org Git - thirdparty/git.git/commitdiff
speed up refresh_index() by utilizing preload_index()
authorBen Peart <benpeart@microsoft.com>
Mon, 29 Oct 2018 20:41:59 +0000 (16:41 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 30 Oct 2018 02:28:39 +0000 (11:28 +0900)
Speed up refresh_index() by utilizing preload_index() to do most of the work
spread across multiple threads.  This works because most cache entries will
get marked CE_UPTODATE so that refresh_cache_ent() can bail out early when
called from within refresh_index().

On a Windows repo with ~200K files, this drops refresh times from 6.64
seconds to 2.87 seconds for a savings of 57%.

Signed-off-by: Ben Peart <benpeart@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h
preload-index.c
read-cache.c

diff --git a/cache.h b/cache.h
index f7fabdde8f37d857f6160c0e4798788f1963d3ae..883099db083124ca69d95bbc36654df61951955c 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -659,6 +659,9 @@ extern int daemonize(void);
 /* Initialize and use the cache information */
 struct lock_file;
 extern int read_index(struct index_state *);
+extern void preload_index(struct index_state *index,
+                         const struct pathspec *pathspec,
+                         unsigned int refresh_flags);
 extern int read_index_preload(struct index_state *,
                              const struct pathspec *pathspec,
                              unsigned int refresh_flags);
index 9e7152ab14d9359d0a48da8b25cd58253a13fc0c..222792ccbc39b6166a75c702525c396b77c2299e 100644 (file)
@@ -9,7 +9,7 @@
 #include "progress.h"
 
 #ifdef NO_PTHREADS
-static void preload_index(struct index_state *index,
+void preload_index(struct index_state *index,
                          const struct pathspec *pathspec,
                          unsigned int refresh_flags)
 {
@@ -100,9 +100,9 @@ static void *preload_thread(void *_data)
        return NULL;
 }
 
-static void preload_index(struct index_state *index,
-                         const struct pathspec *pathspec,
-                         unsigned int refresh_flags)
+void preload_index(struct index_state *index,
+                  const struct pathspec *pathspec,
+                  unsigned int refresh_flags)
 {
        int threads, i, work, offset;
        struct thread_data data[MAX_PARALLEL];
index d57958233e82df6551fdc890f1238ae65beb8940..53733d651db59881c4378ee5787311eef1f6ff99 100644 (file)
@@ -1496,6 +1496,12 @@ int refresh_index(struct index_state *istate, unsigned int flags,
        typechange_fmt = (in_porcelain ? "T\t%s\n" : "%s needs update\n");
        added_fmt = (in_porcelain ? "A\t%s\n" : "%s needs update\n");
        unmerged_fmt = (in_porcelain ? "U\t%s\n" : "%s: needs merge\n");
+       /*
+        * Use the multi-threaded preload_index() to refresh most of the
+        * cache entries quickly then in the single threaded loop below,
+        * we only have to do the special cases that are left.
+        */
+       preload_index(istate, pathspec, 0);
        for (i = 0; i < istate->cache_nr; i++) {
                struct cache_entry *ce, *new_entry;
                int cache_errno = 0;