]> granicus.if.org Git - git/commitdiff
read-cache: speed up add_index_entry during checkout
authorJeff Hostetler <jeffhost@microsoft.com>
Wed, 19 Apr 2017 17:06:16 +0000 (17:06 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 20 Apr 2017 03:33:01 +0000 (20:33 -0700)
Teach add_index_entry_with_check() to see if the path
of the new item is greater than the last path in the
index array before attempting to search for it.

During checkout, merge_working_tree() populates the new
index in sorted order, so this change will save a binary
lookups per file.  This preserves the original behavior
but simply checks the last element before starting the
search.

This helps performance on very large repositories.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
read-cache.c

index 11823f5dbcbe277532d33559c3ff4dd43990c866..836338b3ba7ba094ba60936728424dfb291bf33e 100644 (file)
@@ -1021,7 +1021,16 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
 
        if (!(option & ADD_CACHE_KEEP_CACHE_TREE))
                cache_tree_invalidate_path(istate, ce->name);
-       pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce));
+
+       /*
+        * If this entry's path sorts after the last entry in the index,
+        * we can avoid searching for it.
+        */
+       if (istate->cache_nr > 0 &&
+               strcmp(ce->name, istate->cache[istate->cache_nr - 1]->name) > 0)
+               pos = -istate->cache_nr - 1;
+       else
+               pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce));
 
        /* existing match? Just replace it. */
        if (pos >= 0) {