read-tree: teach 1 and 2 way merges about cache-tree.

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>
This commit is contained in:
Junio C Hamano
2006-04-27 00:13:34 -07:00
parent 497c32136f
commit b34c39cf31

View File

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