@@ -87,15 +87,69 @@ static int commit_pos_cmp(const void *va, const void *vb)
87
87
commit_pos_at (& commit_pos , b );
88
88
}
89
89
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
+
90
142
static int commit_gen_cmp (const void * va , const void * vb )
91
143
{
92
144
const struct commit * a = * (const struct commit * * )va ;
93
145
const struct commit * b = * (const struct commit * * )vb ;
94
146
147
+ uint32_t generation_a = commit_graph_generation (a );
148
+ uint32_t generation_b = commit_graph_generation (b );
95
149
/* lower generation commits first */
96
- if (a -> generation < b -> generation )
150
+ if (generation_a < generation_b )
97
151
return -1 ;
98
- else if (a -> generation > b -> generation )
152
+ else if (generation_a > generation_b )
99
153
return 1 ;
100
154
101
155
/* use date as a heuristic when generations are equal */
@@ -670,22 +724,25 @@ static struct commit_list **insert_parent_or_die(struct repository *r,
670
724
c = lookup_commit (r , & oid );
671
725
if (!c )
672
726
die (_ ("could not find commit %s" ), oid_to_hex (& oid ));
673
- c -> graph_pos = pos ;
727
+ commit_graph_data_at ( c ) -> graph_pos = pos ;
674
728
return & commit_list_insert (c , pptr )-> next ;
675
729
}
676
730
677
731
static void fill_commit_graph_info (struct commit * item , struct commit_graph * g , uint32_t pos )
678
732
{
679
733
const unsigned char * commit_data ;
734
+ struct commit_graph_data * graph_data ;
680
735
uint32_t lex_index ;
681
736
682
737
while (pos < g -> num_commits_in_base )
683
738
g = g -> base_graph ;
684
739
685
740
lex_index = pos - g -> num_commits_in_base ;
686
741
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 ;
689
746
}
690
747
691
748
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,
701
758
uint32_t * parent_data_ptr ;
702
759
uint64_t date_low , date_high ;
703
760
struct commit_list * * pptr ;
761
+ struct commit_graph_data * graph_data ;
704
762
const unsigned char * commit_data ;
705
763
uint32_t lex_index ;
706
764
@@ -714,7 +772,8 @@ static int fill_commit_in_graph(struct repository *r,
714
772
* Store the "full" position, but then use the
715
773
* "local" position for the rest of the calculation.
716
774
*/
717
- item -> graph_pos = pos ;
775
+ graph_data = commit_graph_data_at (item );
776
+ graph_data -> graph_pos = pos ;
718
777
lex_index = pos - g -> num_commits_in_base ;
719
778
720
779
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,
727
786
date_low = get_be32 (commit_data + g -> hash_len + 12 );
728
787
item -> date = (timestamp_t )((date_high << 32 ) | date_low );
729
788
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 ;
731
790
732
791
pptr = & item -> parents ;
733
792
@@ -759,8 +818,9 @@ static int fill_commit_in_graph(struct repository *r,
759
818
760
819
static int find_commit_in_graph (struct commit * item , struct commit_graph * g , uint32_t * pos )
761
820
{
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 ;
764
824
return 1 ;
765
825
} else {
766
826
struct commit_graph * cur_g = g ;
@@ -815,12 +875,13 @@ static struct tree *load_tree_for_commit(struct repository *r,
815
875
{
816
876
struct object_id oid ;
817
877
const unsigned char * commit_data ;
878
+ uint32_t graph_pos = commit_graph_position (c );
818
879
819
- while (c -> graph_pos < g -> num_commits_in_base )
880
+ while (graph_pos < g -> num_commits_in_base )
820
881
g = g -> base_graph ;
821
882
822
883
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 );
824
885
825
886
hashcpy (oid .hash , commit_data );
826
887
set_commit_tree (c , lookup_tree (r , & oid ));
@@ -834,7 +895,7 @@ static struct tree *get_commit_tree_in_graph_one(struct repository *r,
834
895
{
835
896
if (c -> maybe_tree )
836
897
return c -> maybe_tree ;
837
- if (c -> graph_pos == COMMIT_NOT_FROM_GRAPH )
898
+ if (commit_graph_position ( c ) == COMMIT_NOT_FROM_GRAPH )
838
899
BUG ("get_commit_tree_in_graph_one called from non-commit-graph commit" );
839
900
840
901
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,
1020
1081
else
1021
1082
packedDate [0 ] = 0 ;
1022
1083
1023
- packedDate [0 ] |= htonl ((* list )-> generation << 2 );
1084
+ packedDate [0 ] |= htonl (commit_graph_data_at (* list )-> generation << 2 );
1024
1085
1025
1086
packedDate [1 ] = htonl ((* list )-> date );
1026
1087
hashwrite (f , packedDate , 8 );
@@ -1219,7 +1280,7 @@ static void close_reachable(struct write_commit_graph_context *ctx)
1219
1280
continue ;
1220
1281
if (ctx -> split ) {
1221
1282
if ((!parse_commit (commit ) &&
1222
- commit -> graph_pos == COMMIT_NOT_FROM_GRAPH ) ||
1283
+ commit_graph_position ( commit ) == COMMIT_NOT_FROM_GRAPH ) ||
1223
1284
flags == COMMIT_GRAPH_SPLIT_REPLACE )
1224
1285
add_missing_parents (ctx , commit );
1225
1286
} else if (!parse_commit_no_graph (commit ))
@@ -1251,9 +1312,11 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1251
1312
_ ("Computing commit graph generation numbers" ),
1252
1313
ctx -> commits .nr );
1253
1314
for (i = 0 ; i < ctx -> commits .nr ; i ++ ) {
1315
+ uint32_t generation = commit_graph_data_at (ctx -> commits .list [i ])-> generation ;
1316
+
1254
1317
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 )
1257
1320
continue ;
1258
1321
1259
1322
commit_list_insert (ctx -> commits .list [i ], & list );
@@ -1264,22 +1327,26 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1264
1327
uint32_t max_generation = 0 ;
1265
1328
1266
1329
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 ) {
1269
1334
all_parents_computed = 0 ;
1270
1335
commit_list_insert (parent -> item , & list );
1271
1336
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 ;
1274
1339
}
1275
1340
}
1276
1341
1277
1342
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 ;
1279
1346
pop_commit (& list );
1280
1347
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 ;
1283
1350
}
1284
1351
}
1285
1352
}
@@ -1458,7 +1525,7 @@ static uint32_t count_distinct_commits(struct write_commit_graph_context *ctx)
1458
1525
if (ctx -> split ) {
1459
1526
struct commit * c = lookup_commit (ctx -> r , & ctx -> oids .list [i ]);
1460
1527
1461
- if (!c || c -> graph_pos != COMMIT_NOT_FROM_GRAPH )
1528
+ if (!c || commit_graph_position ( c ) != COMMIT_NOT_FROM_GRAPH )
1462
1529
continue ;
1463
1530
}
1464
1531
@@ -1492,7 +1559,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx)
1492
1559
ctx -> commits .list [ctx -> commits .nr ] = lookup_commit (ctx -> r , & ctx -> oids .list [i ]);
1493
1560
1494
1561
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 )
1496
1563
continue ;
1497
1564
1498
1565
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)
2241
2308
struct commit * graph_commit , * odb_commit ;
2242
2309
struct commit_list * graph_parents , * odb_parents ;
2243
2310
uint32_t max_generation = 0 ;
2311
+ uint32_t generation ;
2244
2312
2245
2313
display_progress (progress , i + 1 );
2246
2314
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)
2279
2347
oid_to_hex (& graph_parents -> item -> object .oid ),
2280
2348
oid_to_hex (& odb_parents -> item -> object .oid ));
2281
2349
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 ;
2284
2353
2285
2354
graph_parents = graph_parents -> next ;
2286
2355
odb_parents = odb_parents -> next ;
@@ -2290,7 +2359,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
2290
2359
graph_report (_ ("commit-graph parent list for commit %s terminates early" ),
2291
2360
oid_to_hex (& cur_oid ));
2292
2361
2293
- if (!graph_commit -> generation ) {
2362
+ if (!commit_graph_generation ( graph_commit ) ) {
2294
2363
if (generation_zero == GENERATION_NUMBER_EXISTS )
2295
2364
graph_report (_ ("commit-graph has generation number zero for commit %s, but non-zero elsewhere" ),
2296
2365
oid_to_hex (& cur_oid ));
@@ -2310,10 +2379,11 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)
2310
2379
if (max_generation == GENERATION_NUMBER_MAX )
2311
2380
max_generation -- ;
2312
2381
2313
- if (graph_commit -> generation != max_generation + 1 )
2382
+ generation = commit_graph_generation (graph_commit );
2383
+ if (generation != max_generation + 1 )
2314
2384
graph_report (_ ("commit-graph generation for commit %s is %u != %u" ),
2315
2385
oid_to_hex (& cur_oid ),
2316
- graph_commit -> generation ,
2386
+ generation ,
2317
2387
max_generation + 1 );
2318
2388
2319
2389
if (graph_commit -> date != odb_commit -> date )
0 commit comments