read-tree: teach 1 and 2 way merges about cache-tree.
authorJunio C Hamano <junkio@cox.net>
Thu, 27 Apr 2006 07:13:34 +0000 (00:13 -0700)
committerJunio C Hamano <junkio@cox.net>
Thu, 27 Apr 2006 07:34:12 +0000 (00:34 -0700)
This teaches one-way and two-way "read-tree -m" (and its special
form, "read-tree --reset" as well) not to discard cache-tree but
invalidate only the changed parts of the tree.  When switching
between related branches, this helps the eventual commit
(i.e. write-tree) by keeping cache-tree valid as much as
possible.

This does not prime cache-tree yet, but we ought to be able to
do that for no-merge (i.e. reading from a tree object) case and,
and also perhaps 1 way merge case.

With this patch applied, switching between the tip of Linux 2.6
kernel tree and a branch that touches one path (fs/ext3/Makefile)
from it invalidates only 3 paths out of 1201 cache-tree entries
in the index, and subsequent write-tree takes about a half as
much time as before.

Signed-off-by: Junio C Hamano <junkio@cox.net>
read-tree.c

index 1c65101..ab51682 100644 (file)
@@ -422,6 +422,12 @@ static void verify_uptodate(struct cache_entry *ce)
        die("Entry '%s' not uptodate. Cannot merge.", ce->name);
 }
 
+static void invalidate_ce_path(struct cache_entry *ce)
+{
+       if (ce)
+               cache_tree_invalidate_path(active_cache_tree, ce->name);
+}
+
 static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
 {
        merge->ce_flags |= htons(CE_UPDATE);
@@ -437,6 +443,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old)
                        *merge = *old;
                } else {
                        verify_uptodate(old);
+                       invalidate_ce_path(old);
                }
        }
        merge->ce_flags &= ~htons(CE_STAGEMASK);
@@ -450,6 +457,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old)
                verify_uptodate(old);
        ce->ce_mode = 0;
        add_cache_entry(ce, ADD_CACHE_OK_TO_ADD);
+       invalidate_ce_path(ce);
        return 1;
 }
 
@@ -684,8 +692,10 @@ static int oneway_merge(struct cache_entry **src)
                return error("Cannot do a oneway merge of %d trees",
                             merge_size);
 
-       if (!a)
+       if (!a) {
+               invalidate_ce_path(old);
                return 0;
+       }
        if (old && same(old, a)) {
                return keep_entry(old);
        }
@@ -704,6 +714,7 @@ static int read_cache_unmerged(void)
                struct cache_entry *ce = active_cache[i];
                if (ce_stage(ce)) {
                        deleted++;
+                       invalidate_ce_path(ce);
                        continue;
                }
                if (deleted)
@@ -815,10 +826,9 @@ int main(int argc, char **argv)
                        fn = twoway_merge;
                        break;
                case 3:
-                       fn = threeway_merge;
-                       break;
                default:
                        fn = threeway_merge;
+                       cache_tree_free(&active_cache_tree);
                        break;
                }
 
@@ -829,7 +839,6 @@ int main(int argc, char **argv)
        }
 
        unpack_trees(fn);
-       cache_tree_free(&active_cache_tree);
        if (write_cache(newfd, active_cache, active_nr) ||
            commit_index_file(&cache_file))
                die("unable to write new index file");