Skip to content

Commit d80bea4

Browse files
committed
Merge branch 'ak/commit-graph-to-slab'
A few fields in "struct commit" that do not have to always be present have been moved to commit slabs. * ak/commit-graph-to-slab: commit-graph: minimize commit_graph_data_slab access commit: move members graph_pos, generation to a slab commit-graph: introduce commit_graph_data_slab object: drop parsed_object_pool->commit_count
2 parents 0cc4dca + c752ad0 commit d80bea4

File tree

20 files changed

+217
-94
lines changed

20 files changed

+217
-94
lines changed

alloc.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,23 +99,27 @@ void *alloc_object_node(struct repository *r)
9999
return obj;
100100
}
101101

102-
static unsigned int alloc_commit_index(struct repository *r)
102+
/*
103+
* The returned count is to be used as an index into commit slabs,
104+
* that are *NOT* maintained per repository, and that is why a single
105+
* global counter is used.
106+
*/
107+
static unsigned int alloc_commit_index(void)
103108
{
104-
return r->parsed_objects->commit_count++;
109+
static unsigned int parsed_commits_count;
110+
return parsed_commits_count++;
105111
}
106112

107-
void init_commit_node(struct repository *r, struct commit *c)
113+
void init_commit_node(struct commit *c)
108114
{
109115
c->object.type = OBJ_COMMIT;
110-
c->index = alloc_commit_index(r);
111-
c->graph_pos = COMMIT_NOT_FROM_GRAPH;
112-
c->generation = GENERATION_NUMBER_INFINITY;
116+
c->index = alloc_commit_index();
113117
}
114118

115119
void *alloc_commit_node(struct repository *r)
116120
{
117121
struct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));
118-
init_commit_node(r, c);
122+
init_commit_node(c);
119123
return c;
120124
}
121125

alloc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ struct repository;
99

1010
void *alloc_blob_node(struct repository *r);
1111
void *alloc_tree_node(struct repository *r);
12-
void init_commit_node(struct repository *r, struct commit *c);
12+
void init_commit_node(struct commit *c);
1313
void *alloc_commit_node(struct repository *r);
1414
void *alloc_tag_node(struct repository *r);
1515
void *alloc_object_node(struct repository *r);

blame.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ static int maybe_changed_path(struct repository *r,
12721272
if (!bd)
12731273
return 1;
12741274

1275-
if (origin->commit->generation == GENERATION_NUMBER_INFINITY)
1275+
if (commit_graph_generation(origin->commit) == GENERATION_NUMBER_INFINITY)
12761276
return 1;
12771277

12781278
filter = get_bloom_filter(r, origin->commit, 0);

blob.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ struct blob *lookup_blob(struct repository *r, const struct object_id *oid)
1010
struct object *obj = lookup_object(r, oid);
1111
if (!obj)
1212
return create_object(r, oid, alloc_blob_node(r));
13-
return object_as_type(r, obj, OBJ_BLOB, 0);
13+
return object_as_type(obj, OBJ_BLOB, 0);
1414
}
1515

1616
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)

bloom.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,16 @@ static int load_bloom_filter_from_graph(struct commit_graph *g,
3333
struct commit *c)
3434
{
3535
uint32_t lex_pos, start_index, end_index;
36+
uint32_t graph_pos = commit_graph_position(c);
3637

37-
while (c->graph_pos < g->num_commits_in_base)
38+
while (graph_pos < g->num_commits_in_base)
3839
g = g->base_graph;
3940

4041
/* The commit graph commit 'c' lives in doesn't carry bloom filters. */
4142
if (!g->chunk_bloom_indexes)
4243
return 0;
4344

44-
lex_pos = c->graph_pos - g->num_commits_in_base;
45+
lex_pos = graph_pos - g->num_commits_in_base;
4546

4647
end_index = get_be32(g->chunk_bloom_indexes + 4 * lex_pos);
4748

@@ -193,7 +194,7 @@ struct bloom_filter *get_bloom_filter(struct repository *r,
193194

194195
if (!filter->data) {
195196
load_commit_graph_info(r, c);
196-
if (c->graph_pos != COMMIT_NOT_FROM_GRAPH &&
197+
if (commit_graph_position(c) != COMMIT_NOT_FROM_GRAPH &&
197198
r->objects->commit_graph->chunk_bloom_indexes) {
198199
if (load_bloom_filter_from_graph(r->objects->commit_graph, filter, c))
199200
return filter;

builtin/commit-graph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ static int read_one_commit(struct oidset *commits, struct progress *progress,
154154
NULL, 0);
155155
if (!result)
156156
return error(_("invalid object: %s"), hash);
157-
else if (object_as_type(the_repository, result, OBJ_COMMIT, 1))
157+
else if (object_as_type(result, OBJ_COMMIT, 1))
158158
oidset_insert(commits, &result->oid);
159159

160160
display_progress(progress, oidset_size(commits));

builtin/fsck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static void mark_unreachable_referents(const struct object_id *oid)
241241
enum object_type type = oid_object_info(the_repository,
242242
&obj->oid, NULL);
243243
if (type > 0)
244-
object_as_type(the_repository, obj, type, 0);
244+
object_as_type(obj, type, 0);
245245
}
246246

247247
options.walk = mark_used;

commit-graph.c

Lines changed: 100 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,69 @@ static int commit_pos_cmp(const void *va, const void *vb)
8787
commit_pos_at(&commit_pos, b);
8888
}
8989

90+
define_commit_slab(commit_graph_data_slab, struct commit_graph_data);
91+
static struct commit_graph_data_slab commit_graph_data_slab =
92+
COMMIT_SLAB_INIT(1, commit_graph_data_slab);
93+
94+
uint32_t commit_graph_position(const struct commit *c)
95+
{
96+
struct commit_graph_data *data =
97+
commit_graph_data_slab_peek(&commit_graph_data_slab, c);
98+
99+
return data ? data->graph_pos : COMMIT_NOT_FROM_GRAPH;
100+
}
101+
102+
uint32_t commit_graph_generation(const struct commit *c)
103+
{
104+
struct commit_graph_data *data =
105+
commit_graph_data_slab_peek(&commit_graph_data_slab, c);
106+
107+
if (!data)
108+
return GENERATION_NUMBER_INFINITY;
109+
else if (data->graph_pos == COMMIT_NOT_FROM_GRAPH)
110+
return GENERATION_NUMBER_INFINITY;
111+
112+
return data->generation;
113+
}
114+
115+
static struct commit_graph_data *commit_graph_data_at(const struct commit *c)
116+
{
117+
unsigned int i, nth_slab;
118+
struct commit_graph_data *data =
119+
commit_graph_data_slab_peek(&commit_graph_data_slab, c);
120+
121+
if (data)
122+
return data;
123+
124+
nth_slab = c->index / commit_graph_data_slab.slab_size;
125+
data = commit_graph_data_slab_at(&commit_graph_data_slab, c);
126+
127+
/*
128+
* commit-slab initializes elements with zero, overwrite this with
129+
* COMMIT_NOT_FROM_GRAPH for graph_pos.
130+
*
131+
* We avoid initializing generation with checking if graph position
132+
* is not COMMIT_NOT_FROM_GRAPH.
133+
*/
134+
for (i = 0; i < commit_graph_data_slab.slab_size; i++) {
135+
commit_graph_data_slab.slab[nth_slab][i].graph_pos =
136+
COMMIT_NOT_FROM_GRAPH;
137+
}
138+
139+
return data;
140+
}
141+
90142
static int commit_gen_cmp(const void *va, const void *vb)
91143
{
92144
const struct commit *a = *(const struct commit **)va;
93145
const struct commit *b = *(const struct commit **)vb;
94146

147+
uint32_t generation_a = commit_graph_generation(a);
148+
uint32_t generation_b = commit_graph_generation(b);
95149
/* lower generation commits first */
96-
if (a->generation < b->generation)
150+
if (generation_a < generation_b)
97151
return -1;
98-
else if (a->generation > b->generation)
152+
else if (generation_a > generation_b)
99153
return 1;
100154

101155
/* use date as a heuristic when generations are equal */
@@ -670,22 +724,25 @@ static struct commit_list **insert_parent_or_die(struct repository *r,
670724
c = lookup_commit(r, &oid);
671725
if (!c)
672726
die(_("could not find commit %s"), oid_to_hex(&oid));
673-
c->graph_pos = pos;
727+
commit_graph_data_at(c)->graph_pos = pos;
674728
return &commit_list_insert(c, pptr)->next;
675729
}
676730

677731
static void fill_commit_graph_info(struct commit *item, struct commit_graph *g, uint32_t pos)
678732
{
679733
const unsigned char *commit_data;
734+
struct commit_graph_data *graph_data;
680735
uint32_t lex_index;
681736

682737
while (pos < g->num_commits_in_base)
683738
g = g->base_graph;
684739

685740
lex_index = pos - g->num_commits_in_base;
686741
commit_data = g->chunk_commit_data + GRAPH_DATA_WIDTH * lex_index;
687-
item->graph_pos = pos;
688-
item->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
742+
743+
graph_data = commit_graph_data_at(item);
744+
graph_data->graph_pos = pos;
745+
graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
689746
}
690747

691748
static inline void set_commit_tree(struct commit *c, struct tree *t)
@@ -701,6 +758,7 @@ static int fill_commit_in_graph(struct repository *r,
701758
uint32_t *parent_data_ptr;
702759
uint64_t date_low, date_high;
703760
struct commit_list **pptr;
761+
struct commit_graph_data *graph_data;
704762
const unsigned char *commit_data;
705763
uint32_t lex_index;
706764

@@ -714,7 +772,8 @@ static int fill_commit_in_graph(struct repository *r,
714772
* Store the "full" position, but then use the
715773
* "local" position for the rest of the calculation.
716774
*/
717-
item->graph_pos = pos;
775+
graph_data = commit_graph_data_at(item);
776+
graph_data->graph_pos = pos;
718777
lex_index = pos - g->num_commits_in_base;
719778

720779
commit_data = g->chunk_commit_data + (g->hash_len + 16) * lex_index;
@@ -727,7 +786,7 @@ static int fill_commit_in_graph(struct repository *r,
727786
date_low = get_be32(commit_data + g->hash_len + 12);
728787
item->date = (timestamp_t)((date_high << 32) | date_low);
729788

730-
item->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
789+
graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2;
731790

732791
pptr = &item->parents;
733792

@@ -759,8 +818,9 @@ static int fill_commit_in_graph(struct repository *r,
759818

760819
static int find_commit_in_graph(struct commit *item, struct commit_graph *g, uint32_t *pos)
761820
{
762-
if (item->graph_pos != COMMIT_NOT_FROM_GRAPH) {
763-
*pos = item->graph_pos;
821+
uint32_t graph_pos = commit_graph_position(item);
822+
if (graph_pos != COMMIT_NOT_FROM_GRAPH) {
823+
*pos = graph_pos;
764824
return 1;
765825
} else {
766826
struct commit_graph *cur_g = g;
@@ -815,12 +875,13 @@ static struct tree *load_tree_for_commit(struct repository *r,
815875
{
816876
struct object_id oid;
817877
const unsigned char *commit_data;
878+
uint32_t graph_pos = commit_graph_position(c);
818879

819-
while (c->graph_pos < g->num_commits_in_base)
880+
while (graph_pos < g->num_commits_in_base)
820881
g = g->base_graph;
821882

822883
commit_data = g->chunk_commit_data +
823-
GRAPH_DATA_WIDTH * (c->graph_pos - g->num_commits_in_base);
884+
GRAPH_DATA_WIDTH * (graph_pos - g->num_commits_in_base);
824885

825886
hashcpy(oid.hash, commit_data);
826887
set_commit_tree(c, lookup_tree(r, &oid));
@@ -834,7 +895,7 @@ static struct tree *get_commit_tree_in_graph_one(struct repository *r,
834895
{
835896
if (c->maybe_tree)
836897
return c->maybe_tree;
837-
if (c->graph_pos == COMMIT_NOT_FROM_GRAPH)
898+
if (commit_graph_position(c) == COMMIT_NOT_FROM_GRAPH)
838899
BUG("get_commit_tree_in_graph_one called from non-commit-graph commit");
839900

840901
return load_tree_for_commit(r, g, (struct commit *)c);
@@ -1020,7 +1081,7 @@ static void write_graph_chunk_data(struct hashfile *f, int hash_len,
10201081
else
10211082
packedDate[0] = 0;
10221083

1023-
packedDate[0] |= htonl((*list)->generation << 2);
1084+
packedDate[0] |= htonl(commit_graph_data_at(*list)->generation << 2);
10241085

10251086
packedDate[1] = htonl((*list)->date);
10261087
hashwrite(f, packedDate, 8);
@@ -1219,7 +1280,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
12191280
continue;
12201281
if (ctx->split) {
12211282
if ((!parse_commit(commit) &&
1222-
commit->graph_pos == COMMIT_NOT_FROM_GRAPH) ||
1283+
commit_graph_position(commit) == COMMIT_NOT_FROM_GRAPH) ||
12231284
flags == COMMIT_GRAPH_SPLIT_REPLACE)
12241285
add_missing_parents(ctx, commit);
12251286
} else if (!parse_commit_no_graph(commit))
@@ -1251,9 +1312,11 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
12511312
_("Computing commit graph generation numbers"),
12521313
ctx->commits.nr);
12531314
for (i = 0; i < ctx->commits.nr; i++) {
1315+
uint32_t generation = commit_graph_data_at(ctx->commits.list[i])->generation;
1316+
12541317
display_progress(ctx->progress, i + 1);
1255-
if (ctx->commits.list[i]->generation != GENERATION_NUMBER_INFINITY &&
1256-
ctx->commits.list[i]->generation != GENERATION_NUMBER_ZERO)
1318+
if (generation != GENERATION_NUMBER_INFINITY &&
1319+
generation != GENERATION_NUMBER_ZERO)
12571320
continue;
12581321

12591322
commit_list_insert(ctx->commits.list[i], &list);
@@ -1264,22 +1327,26 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
12641327
uint32_t max_generation = 0;
12651328

12661329
for (parent = current->parents; parent; parent = parent->next) {
1267-
if (parent->item->generation == GENERATION_NUMBER_INFINITY ||
1268-
parent->item->generation == GENERATION_NUMBER_ZERO) {
1330+
generation = commit_graph_data_at(parent->item)->generation;
1331+
1332+
if (generation == GENERATION_NUMBER_INFINITY ||
1333+
generation == GENERATION_NUMBER_ZERO) {
12691334
all_parents_computed = 0;
12701335
commit_list_insert(parent->item, &list);
12711336
break;
1272-
} else if (parent->item->generation > max_generation) {
1273-
max_generation = parent->item->generation;
1337+
} else if (generation > max_generation) {
1338+
max_generation = generation;
12741339
}
12751340
}
12761341

12771342
if (all_parents_computed) {
1278-
current->generation = max_generation + 1;
1343+
struct commit_graph_data *data = commit_graph_data_at(current);
1344+
1345+
data->generation = max_generation + 1;
12791346
pop_commit(&list);
12801347

1281-
if (current->generation > GENERATION_NUMBER_MAX)
1282-
current->generation = GENERATION_NUMBER_MAX;
1348+
if (data->generation > GENERATION_NUMBER_MAX)
1349+
data->generation = GENERATION_NUMBER_MAX;
12831350
}
12841351
}
12851352
}
@@ -1458,7 +1525,7 @@ static uint32_t count_distinct_commits(struct write_commit_graph_context *ctx)
14581525
if (ctx->split) {
14591526
struct commit *c = lookup_commit(ctx->r, &ctx->oids.list[i]);
14601527

1461-
if (!c || c->graph_pos != COMMIT_NOT_FROM_GRAPH)
1528+
if (!c || commit_graph_position(c) != COMMIT_NOT_FROM_GRAPH)
14621529
continue;
14631530
}
14641531

@@ -1492,7 +1559,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
14921559
ctx->commits.list[ctx->commits.nr] = lookup_commit(ctx->r, &ctx->oids.list[i]);
14931560

14941561
if (ctx->split && flags != COMMIT_GRAPH_SPLIT_REPLACE &&
1495-
ctx->commits.list[ctx->commits.nr]->graph_pos != COMMIT_NOT_FROM_GRAPH)
1562+
commit_graph_position(ctx->commits.list[ctx->commits.nr]) != COMMIT_NOT_FROM_GRAPH)
14961563
continue;
14971564

14981565
if (ctx->split && flags == COMMIT_GRAPH_SPLIT_REPLACE)
@@ -2241,6 +2308,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
22412308
struct commit *graph_commit, *odb_commit;
22422309
struct commit_list *graph_parents, *odb_parents;
22432310
uint32_t max_generation = 0;
2311+
uint32_t generation;
22442312

22452313
display_progress(progress, i + 1);
22462314
hashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);
@@ -2279,8 +2347,9 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
22792347
oid_to_hex(&graph_parents->item->object.oid),
22802348
oid_to_hex(&odb_parents->item->object.oid));
22812349

2282-
if (graph_parents->item->generation > max_generation)
2283-
max_generation = graph_parents->item->generation;
2350+
generation = commit_graph_generation(graph_parents->item);
2351+
if (generation > max_generation)
2352+
max_generation = generation;
22842353

22852354
graph_parents = graph_parents->next;
22862355
odb_parents = odb_parents->next;
@@ -2290,7 +2359,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
22902359
graph_report(_("commit-graph parent list for commit %s terminates early"),
22912360
oid_to_hex(&cur_oid));
22922361

2293-
if (!graph_commit->generation) {
2362+
if (!commit_graph_generation(graph_commit)) {
22942363
if (generation_zero == GENERATION_NUMBER_EXISTS)
22952364
graph_report(_("commit-graph has generation number zero for commit %s, but non-zero elsewhere"),
22962365
oid_to_hex(&cur_oid));
@@ -2310,10 +2379,11 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
23102379
if (max_generation == GENERATION_NUMBER_MAX)
23112380
max_generation--;
23122381

2313-
if (graph_commit->generation != max_generation + 1)
2382+
generation = commit_graph_generation(graph_commit);
2383+
if (generation != max_generation + 1)
23142384
graph_report(_("commit-graph generation for commit %s is %u != %u"),
23152385
oid_to_hex(&cur_oid),
2316-
graph_commit->generation,
2386+
generation,
23172387
max_generation + 1);
23182388

23192389
if (graph_commit->date != odb_commit->date)

0 commit comments

Comments
 (0)