Skip to content

Commit d21ee7d

Browse files
peffgitster
authored andcommitted
commit-graph: examine changed-path objects in pack order
Looking at the diff of commit objects in pack order is much faster than in sha1 order, as it gives locality to the access of tree deltas (whereas sha1 order is effectively random). Unfortunately the commit-graph code sorts the commits (several times, sometimes as an oid and sometimes a pointer-to-commit), and we ultimately traverse in sha1 order. Instead, let's remember the position at which we see each commit, and traverse in that order when looking at bloom filters. This drops my time for "git commit-graph write --changed-paths" in linux.git from ~4 minutes to ~1.5 minutes. Probably the "--reachable" code path would want something similar. Or alternatively, we could use a different data structure (either a hash, or maybe even just a bit in "struct commit") to keep track of which oids we've seen, etc instead of sorting. And then we could keep the original order. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Garima Singh <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f97b932 commit d21ee7d

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

commit-graph.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "replace-object.h"
1818
#include "progress.h"
1919
#include "bloom.h"
20+
#include "commit-slab.h"
2021

2122
#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
2223
#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
@@ -46,9 +47,32 @@
4647
/* Remember to update object flag allocation in object.h */
4748
#define REACHABLE (1u<<15)
4849

49-
char *get_commit_graph_filename(struct object_directory *odb)
50+
/* Keep track of the order in which commits are added to our list. */
51+
define_commit_slab(commit_pos, int);
52+
static struct commit_pos commit_pos = COMMIT_SLAB_INIT(1, commit_pos);
53+
54+
static void set_commit_pos(struct repository *r, const struct object_id *oid)
55+
{
56+
static int32_t max_pos;
57+
struct commit *commit = lookup_commit(r, oid);
58+
59+
if (!commit)
60+
return; /* should never happen, but be lenient */
61+
62+
*commit_pos_at(&commit_pos, commit) = max_pos++;
63+
}
64+
65+
static int commit_pos_cmp(const void *va, const void *vb)
5066
{
51-
return xstrfmt("%s/info/commit-graph", odb->path);
67+
const struct commit *a = *(const struct commit **)va;
68+
const struct commit *b = *(const struct commit **)vb;
69+
return commit_pos_at(&commit_pos, a) -
70+
commit_pos_at(&commit_pos, b);
71+
}
72+
73+
char *get_commit_graph_filename(struct object_directory *obj_dir)
74+
{
75+
return xstrfmt("%s/info/commit-graph", obj_dir->path);
5276
}
5377

5478
static char *get_split_graph_filename(struct object_directory *odb,
@@ -1021,6 +1045,8 @@ static int add_packed_commits(const struct object_id *oid,
10211045
oidcpy(&(ctx->oids.list[ctx->oids.nr]), oid);
10221046
ctx->oids.nr++;
10231047

1048+
set_commit_pos(ctx->r, oid);
1049+
10241050
return 0;
10251051
}
10261052

@@ -1141,6 +1167,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
11411167
{
11421168
int i;
11431169
struct progress *progress = NULL;
1170+
struct commit **sorted_commits;
11441171

11451172
init_bloom_filters();
11461173

@@ -1149,13 +1176,18 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx)
11491176
_("Computing commit changed paths Bloom filters"),
11501177
ctx->commits.nr);
11511178

1179+
ALLOC_ARRAY(sorted_commits, ctx->commits.nr);
1180+
COPY_ARRAY(sorted_commits, ctx->commits.list, ctx->commits.nr);
1181+
QSORT(sorted_commits, ctx->commits.nr, commit_pos_cmp);
1182+
11521183
for (i = 0; i < ctx->commits.nr; i++) {
1153-
struct commit *c = ctx->commits.list[i];
1184+
struct commit *c = sorted_commits[i];
11541185
struct bloom_filter *filter = get_bloom_filter(ctx->r, c);
11551186
ctx->total_bloom_filter_data_size += sizeof(unsigned char) * filter->len;
11561187
display_progress(progress, i + 1);
11571188
}
11581189

1190+
free(sorted_commits);
11591191
stop_progress(&progress);
11601192
}
11611193

0 commit comments

Comments
 (0)