Skip to content

Commit a92fce4

Browse files
committed
Merge branch 'vd/skip-cache-tree-update'
Avoid calling 'cache_tree_update()' when doing so would be redundant. * vd/skip-cache-tree-update: rebase: use 'skip_cache_tree_update' option read-tree: use 'skip_cache_tree_update' option reset: use 'skip_cache_tree_update' option unpack-trees: add 'skip_cache_tree_update' option cache-tree: add perf test comparing update and prime
2 parents 3f98d7a + 652bd02 commit a92fce4

14 files changed

+145
-3
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,7 @@ TEST_BUILTINS_OBJS += test-advise.o
787787
TEST_BUILTINS_OBJS += test-bitmap.o
788788
TEST_BUILTINS_OBJS += test-bloom.o
789789
TEST_BUILTINS_OBJS += test-bundle-uri.o
790+
TEST_BUILTINS_OBJS += test-cache-tree.o
790791
TEST_BUILTINS_OBJS += test-chmtime.o
791792
TEST_BUILTINS_OBJS += test-config.o
792793
TEST_BUILTINS_OBJS += test-crontab.o

builtin/read-tree.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
249249
if (opts.debug_unpack)
250250
opts.fn = debug_merge;
251251

252+
/* If we're going to prime_cache_tree later, skip cache tree update */
253+
if (nr_trees == 1 && !opts.prefix)
254+
opts.skip_cache_tree_update = 1;
255+
252256
cache_tree_free(&active_cache_tree);
253257
for (i = 0; i < nr_trees; i++) {
254258
struct tree *tree = trees[i];

builtin/reset.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t
7373
case HARD:
7474
opts.update = 1;
7575
opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED;
76+
opts.skip_cache_tree_update = 1;
7677
break;
7778
case MIXED:
7879
opts.reset = UNPACK_RESET_PROTECT_UNTRACKED;
80+
opts.skip_cache_tree_update = 1;
7981
/* but opts.update=0, so working tree not updated */
8082
break;
8183
default:

reset.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ int reset_head(struct repository *r, const struct reset_head_opts *opts)
128128
unpack_tree_opts.update = 1;
129129
unpack_tree_opts.merge = 1;
130130
unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
131+
unpack_tree_opts.skip_cache_tree_update = 1;
131132
init_checkout_metadata(&unpack_tree_opts.meta, switch_to_branch, oid, NULL);
132133
if (reset_hard)
133134
unpack_tree_opts.reset = UNPACK_RESET_PROTECT_UNTRACKED;

sequencer.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3748,6 +3748,7 @@ static int do_reset(struct repository *r,
37483748
unpack_tree_opts.merge = 1;
37493749
unpack_tree_opts.update = 1;
37503750
unpack_tree_opts.preserve_ignored = 0; /* FIXME: !overwrite_ignore */
3751+
unpack_tree_opts.skip_cache_tree_update = 1;
37513752
init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL);
37523753

37533754
if (repo_read_index_unmerged(r)) {

t/helper/test-cache-tree.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "test-tool.h"
2+
#include "cache.h"
3+
#include "tree.h"
4+
#include "cache-tree.h"
5+
#include "parse-options.h"
6+
7+
static char const * const test_cache_tree_usage[] = {
8+
N_("test-tool cache-tree <options> (control|prime|update)"),
9+
NULL
10+
};
11+
12+
int cmd__cache_tree(int argc, const char **argv)
13+
{
14+
struct object_id oid;
15+
struct tree *tree;
16+
int empty = 0;
17+
int invalidate_qty = 0;
18+
int i;
19+
20+
struct option options[] = {
21+
OPT_BOOL(0, "empty", &empty,
22+
N_("clear the cache tree before each iteration")),
23+
OPT_INTEGER_F(0, "invalidate", &invalidate_qty,
24+
N_("number of entries in the cache tree to invalidate (default 0)"),
25+
PARSE_OPT_NONEG),
26+
OPT_END()
27+
};
28+
29+
setup_git_directory();
30+
31+
argc = parse_options(argc, argv, NULL, options, test_cache_tree_usage, 0);
32+
33+
if (read_cache() < 0)
34+
die(_("unable to read index file"));
35+
36+
oidcpy(&oid, &the_index.cache_tree->oid);
37+
tree = parse_tree_indirect(&oid);
38+
if (!tree)
39+
die(_("not a tree object: %s"), oid_to_hex(&oid));
40+
41+
if (empty) {
42+
/* clear the cache tree & allocate a new one */
43+
cache_tree_free(&the_index.cache_tree);
44+
the_index.cache_tree = cache_tree();
45+
} else if (invalidate_qty) {
46+
/* invalidate the specified number of unique paths */
47+
float f_interval = (float)the_index.cache_nr / invalidate_qty;
48+
int interval = f_interval < 1.0 ? 1 : (int)f_interval;
49+
for (i = 0; i < invalidate_qty && i * interval < the_index.cache_nr; i++)
50+
cache_tree_invalidate_path(&the_index, the_index.cache[i * interval]->name);
51+
}
52+
53+
if (argc != 1)
54+
usage_with_options(test_cache_tree_usage, options);
55+
else if (!strcmp(argv[0], "prime"))
56+
prime_cache_tree(the_repository, &the_index, tree);
57+
else if (!strcmp(argv[0], "update"))
58+
cache_tree_update(&the_index, WRITE_TREE_SILENT | WRITE_TREE_REPAIR);
59+
/* use "control" subcommand to specify no-op */
60+
else if (!!strcmp(argv[0], "control"))
61+
die(_("Unhandled subcommand '%s'"), argv[0]);
62+
63+
return 0;
64+
}

t/helper/test-tool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ static struct test_cmd cmds[] = {
1414
{ "bitmap", cmd__bitmap },
1515
{ "bloom", cmd__bloom },
1616
{ "bundle-uri", cmd__bundle_uri },
17+
{ "cache-tree", cmd__cache_tree },
1718
{ "chmtime", cmd__chmtime },
1819
{ "config", cmd__config },
1920
{ "crontab", cmd__crontab },

t/helper/test-tool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ int cmd__advise_if_enabled(int argc, const char **argv);
88
int cmd__bitmap(int argc, const char **argv);
99
int cmd__bloom(int argc, const char **argv);
1010
int cmd__bundle_uri(int argc, const char **argv);
11+
int cmd__cache_tree(int argc, const char **argv);
1112
int cmd__chmtime(int argc, const char **argv);
1213
int cmd__config(int argc, const char **argv);
1314
int cmd__crontab(int argc, const char **argv);

t/perf/p0006-read-tree-checkout.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ test_perf "read-tree br_base br_ballast ($nr_files)" '
4949
git read-tree -n -m br_base br_ballast
5050
'
5151

52+
test_perf "read-tree br_ballast_plus_1 ($nr_files)" '
53+
# Run read-tree 100 times for clearer performance results & comparisons
54+
for i in $(test_seq 100)
55+
do
56+
git read-tree -n -m br_ballast_plus_1 || return 1
57+
done
58+
'
59+
5260
test_perf "switch between br_base br_ballast ($nr_files)" '
5361
git checkout -q br_base &&
5462
git checkout -q br_ballast

t/perf/p0090-cache-tree.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/sh
2+
3+
test_description="Tests performance of cache tree update operations"
4+
5+
. ./perf-lib.sh
6+
7+
test_perf_large_repo
8+
test_checkout_worktree
9+
10+
count=100
11+
12+
test_expect_success 'setup cache tree' '
13+
git write-tree
14+
'
15+
16+
test_cache_tree () {
17+
test_perf "$1, $3" "
18+
for i in \$(test_seq $count)
19+
do
20+
test-tool cache-tree $4 $2
21+
done
22+
"
23+
}
24+
25+
test_cache_tree_update_functions () {
26+
test_cache_tree 'no-op' 'control' "$1" "$2"
27+
test_cache_tree 'prime_cache_tree' 'prime' "$1" "$2"
28+
test_cache_tree 'cache_tree_update' 'update' "$1" "$2"
29+
}
30+
31+
test_cache_tree_update_functions "clean" ""
32+
test_cache_tree_update_functions "invalidate 2" "--invalidate 2"
33+
test_cache_tree_update_functions "invalidate 50" "--invalidate 50"
34+
test_cache_tree_update_functions "empty" "--empty"
35+
36+
test_done

0 commit comments

Comments
 (0)