@@ -117,12 +117,10 @@ timestamp_t commit_graph_generation(const struct commit *c)
117
117
struct commit_graph_data * data =
118
118
commit_graph_data_slab_peek (& commit_graph_data_slab , c );
119
119
120
- if (!data )
121
- return GENERATION_NUMBER_INFINITY ;
122
- else if (data -> graph_pos == COMMIT_NOT_FROM_GRAPH )
123
- return GENERATION_NUMBER_INFINITY ;
120
+ if (data && data -> generation )
121
+ return data -> generation ;
124
122
125
- return data -> generation ;
123
+ return GENERATION_NUMBER_INFINITY ;
126
124
}
127
125
128
126
static struct commit_graph_data * commit_graph_data_at (const struct commit * c )
@@ -1447,66 +1445,144 @@ static void close_reachable(struct write_commit_graph_context *ctx)
1447
1445
stop_progress (& ctx -> progress );
1448
1446
}
1449
1447
1450
- static void compute_topological_levels (struct write_commit_graph_context * ctx )
1448
+ struct compute_generation_info {
1449
+ struct repository * r ;
1450
+ struct packed_commit_list * commits ;
1451
+ struct progress * progress ;
1452
+ int progress_cnt ;
1453
+
1454
+ timestamp_t (* get_generation )(struct commit * c , void * data );
1455
+ void (* set_generation )(struct commit * c , timestamp_t gen , void * data );
1456
+ void * data ;
1457
+ };
1458
+
1459
+ static timestamp_t compute_generation_from_max (struct commit * c ,
1460
+ timestamp_t max_gen ,
1461
+ int generation_version )
1462
+ {
1463
+ switch (generation_version ) {
1464
+ case 1 : /* topological levels */
1465
+ if (max_gen > GENERATION_NUMBER_V1_MAX - 1 )
1466
+ max_gen = GENERATION_NUMBER_V1_MAX - 1 ;
1467
+ return max_gen + 1 ;
1468
+
1469
+ case 2 : /* corrected commit date */
1470
+ if (c -> date && c -> date > max_gen )
1471
+ max_gen = c -> date - 1 ;
1472
+ return max_gen + 1 ;
1473
+
1474
+ default :
1475
+ BUG ("attempting unimplemented version" );
1476
+ }
1477
+ }
1478
+
1479
+ static void compute_reachable_generation_numbers (
1480
+ struct compute_generation_info * info ,
1481
+ int generation_version )
1451
1482
{
1452
1483
int i ;
1453
1484
struct commit_list * list = NULL ;
1454
1485
1455
- if (ctx -> report_progress )
1456
- ctx -> progress = start_delayed_progress (
1457
- _ ("Computing commit graph topological levels" ),
1458
- ctx -> commits .nr );
1459
- for (i = 0 ; i < ctx -> commits .nr ; i ++ ) {
1460
- struct commit * c = ctx -> commits .list [i ];
1461
- uint32_t level ;
1462
-
1463
- repo_parse_commit (ctx -> r , c );
1464
- level = * topo_level_slab_at (ctx -> topo_levels , c );
1486
+ for (i = 0 ; i < info -> commits -> nr ; i ++ ) {
1487
+ struct commit * c = info -> commits -> list [i ];
1488
+ timestamp_t gen ;
1489
+ repo_parse_commit (info -> r , c );
1490
+ gen = info -> get_generation (c , info -> data );
1491
+ display_progress (info -> progress , info -> progress_cnt + 1 );
1465
1492
1466
- display_progress (ctx -> progress , i + 1 );
1467
- if (level != GENERATION_NUMBER_ZERO )
1493
+ if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY )
1468
1494
continue ;
1469
1495
1470
1496
commit_list_insert (c , & list );
1471
1497
while (list ) {
1472
1498
struct commit * current = list -> item ;
1473
1499
struct commit_list * parent ;
1474
1500
int all_parents_computed = 1 ;
1475
- uint32_t max_level = 0 ;
1501
+ uint32_t max_gen = 0 ;
1476
1502
1477
1503
for (parent = current -> parents ; parent ; parent = parent -> next ) {
1478
- repo_parse_commit (ctx -> r , parent -> item );
1479
- level = * topo_level_slab_at ( ctx -> topo_levels , parent -> item );
1504
+ repo_parse_commit (info -> r , parent -> item );
1505
+ gen = info -> get_generation ( parent -> item , info -> data );
1480
1506
1481
- if (level == GENERATION_NUMBER_ZERO ) {
1507
+ if (gen == GENERATION_NUMBER_ZERO ) {
1482
1508
all_parents_computed = 0 ;
1483
1509
commit_list_insert (parent -> item , & list );
1484
1510
break ;
1485
1511
}
1486
1512
1487
- if (level > max_level )
1488
- max_level = level ;
1513
+ if (gen > max_gen )
1514
+ max_gen = gen ;
1489
1515
}
1490
1516
1491
1517
if (all_parents_computed ) {
1492
1518
pop_commit (& list );
1493
-
1494
- if ( max_level > GENERATION_NUMBER_V1_MAX - 1 )
1495
- max_level = GENERATION_NUMBER_V1_MAX - 1 ;
1496
- * topo_level_slab_at ( ctx -> topo_levels , current ) = max_level + 1 ;
1519
+ gen = compute_generation_from_max (
1520
+ current , max_gen ,
1521
+ generation_version ) ;
1522
+ info -> set_generation ( current , gen , info -> data ) ;
1497
1523
}
1498
1524
}
1499
1525
}
1526
+ }
1527
+
1528
+ static timestamp_t get_topo_level (struct commit * c , void * data )
1529
+ {
1530
+ struct write_commit_graph_context * ctx = data ;
1531
+ return * topo_level_slab_at (ctx -> topo_levels , c );
1532
+ }
1533
+
1534
+ static void set_topo_level (struct commit * c , timestamp_t t , void * data )
1535
+ {
1536
+ struct write_commit_graph_context * ctx = data ;
1537
+ * topo_level_slab_at (ctx -> topo_levels , c ) = (uint32_t )t ;
1538
+ }
1539
+
1540
+ static void compute_topological_levels (struct write_commit_graph_context * ctx )
1541
+ {
1542
+ struct compute_generation_info info = {
1543
+ .r = ctx -> r ,
1544
+ .commits = & ctx -> commits ,
1545
+ .get_generation = get_topo_level ,
1546
+ .set_generation = set_topo_level ,
1547
+ .data = ctx ,
1548
+ };
1549
+
1550
+ if (ctx -> report_progress )
1551
+ info .progress = ctx -> progress
1552
+ = start_delayed_progress (
1553
+ _ ("Computing commit graph topological levels" ),
1554
+ ctx -> commits .nr );
1555
+
1556
+ compute_reachable_generation_numbers (& info , 1 );
1557
+
1500
1558
stop_progress (& ctx -> progress );
1501
1559
}
1502
1560
1561
+ static timestamp_t get_generation_from_graph_data (struct commit * c , void * data )
1562
+ {
1563
+ return commit_graph_data_at (c )-> generation ;
1564
+ }
1565
+
1566
+ static void set_generation_v2 (struct commit * c , timestamp_t t , void * data )
1567
+ {
1568
+ struct commit_graph_data * g = commit_graph_data_at (c );
1569
+ g -> generation = (uint32_t )t ;
1570
+ }
1571
+
1503
1572
static void compute_generation_numbers (struct write_commit_graph_context * ctx )
1504
1573
{
1505
1574
int i ;
1506
- struct commit_list * list = NULL ;
1575
+ struct compute_generation_info info = {
1576
+ .r = ctx -> r ,
1577
+ .commits = & ctx -> commits ,
1578
+ .get_generation = get_generation_from_graph_data ,
1579
+ .set_generation = set_generation_v2 ,
1580
+ .data = ctx ,
1581
+ };
1507
1582
1508
1583
if (ctx -> report_progress )
1509
- ctx -> progress = start_delayed_progress (
1584
+ info .progress = ctx -> progress
1585
+ = start_delayed_progress (
1510
1586
_ ("Computing commit graph generation numbers" ),
1511
1587
ctx -> commits .nr );
1512
1588
@@ -1518,47 +1594,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1518
1594
}
1519
1595
}
1520
1596
1521
- for (i = 0 ; i < ctx -> commits .nr ; i ++ ) {
1522
- struct commit * c = ctx -> commits .list [i ];
1523
- timestamp_t corrected_commit_date ;
1524
-
1525
- repo_parse_commit (ctx -> r , c );
1526
- corrected_commit_date = commit_graph_data_at (c )-> generation ;
1527
-
1528
- display_progress (ctx -> progress , i + 1 );
1529
- if (corrected_commit_date != GENERATION_NUMBER_ZERO )
1530
- continue ;
1531
-
1532
- commit_list_insert (c , & list );
1533
- while (list ) {
1534
- struct commit * current = list -> item ;
1535
- struct commit_list * parent ;
1536
- int all_parents_computed = 1 ;
1537
- timestamp_t max_corrected_commit_date = 0 ;
1538
-
1539
- for (parent = current -> parents ; parent ; parent = parent -> next ) {
1540
- repo_parse_commit (ctx -> r , parent -> item );
1541
- corrected_commit_date = commit_graph_data_at (parent -> item )-> generation ;
1542
-
1543
- if (corrected_commit_date == GENERATION_NUMBER_ZERO ) {
1544
- all_parents_computed = 0 ;
1545
- commit_list_insert (parent -> item , & list );
1546
- break ;
1547
- }
1548
-
1549
- if (corrected_commit_date > max_corrected_commit_date )
1550
- max_corrected_commit_date = corrected_commit_date ;
1551
- }
1552
-
1553
- if (all_parents_computed ) {
1554
- pop_commit (& list );
1555
-
1556
- if (current -> date && current -> date > max_corrected_commit_date )
1557
- max_corrected_commit_date = current -> date - 1 ;
1558
- commit_graph_data_at (current )-> generation = max_corrected_commit_date + 1 ;
1559
- }
1560
- }
1561
- }
1597
+ compute_reachable_generation_numbers (& info , 2 );
1562
1598
1563
1599
for (i = 0 ; i < ctx -> commits .nr ; i ++ ) {
1564
1600
struct commit * c = ctx -> commits .list [i ];
@@ -1569,6 +1605,35 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx)
1569
1605
stop_progress (& ctx -> progress );
1570
1606
}
1571
1607
1608
+ static void set_generation_in_graph_data (struct commit * c , timestamp_t t ,
1609
+ void * data )
1610
+ {
1611
+ commit_graph_data_at (c )-> generation = t ;
1612
+ }
1613
+
1614
+ /*
1615
+ * After this method, all commits reachable from those in the given
1616
+ * list will have non-zero, non-infinite generation numbers.
1617
+ */
1618
+ void ensure_generations_valid (struct repository * r ,
1619
+ struct commit * * commits , size_t nr )
1620
+ {
1621
+ int generation_version = get_configured_generation_version (r );
1622
+ struct packed_commit_list list = {
1623
+ .list = commits ,
1624
+ .alloc = nr ,
1625
+ .nr = nr ,
1626
+ };
1627
+ struct compute_generation_info info = {
1628
+ .r = r ,
1629
+ .commits = & list ,
1630
+ .get_generation = get_generation_from_graph_data ,
1631
+ .set_generation = set_generation_in_graph_data ,
1632
+ };
1633
+
1634
+ compute_reachable_generation_numbers (& info , generation_version );
1635
+ }
1636
+
1572
1637
static void trace2_bloom_filter_write_statistics (struct write_commit_graph_context * ctx )
1573
1638
{
1574
1639
trace2_data_intmax ("commit-graph" , ctx -> r , "filter-computed" ,
0 commit comments