1446
stop_progress(&ctx->progress);
1447
}
1448
1449
-static void compute_topological_levels(struct write_commit_graph_context *ctx)
1449
+struct compute_generation_info {
1450
+ struct repository *r;
1451
+ struct packed_commit_list *commits;
1452
+ struct progress *progress;
1453
+ int progress_cnt;
1454
+
1455
+ timestamp_t (*get_generation)(struct commit *c, void *data);
1456
+ void (*set_generation)(struct commit *c, timestamp_t gen, void *data);
1457
+ void *data;
1458
+};
1459
+
1460
+static timestamp_t compute_generation_from_max(struct commit *c,
1461
+ timestamp_t max_gen,
1462
+ int generation_version)
1463
+{
1464
+ switch (generation_version) {
1465
+ case 1: /* topological levels */
1466
+ if (max_gen > GENERATION_NUMBER_V1_MAX - 1)
1467
+ max_gen = GENERATION_NUMBER_V1_MAX - 1;
1468
+ return max_gen + 1;
1469
+
1470
+ case 2: /* corrected commit date */
1471
+ if (c->date && c->date > max_gen)
1472
+ max_gen = c->date - 1;
1473
+ return max_gen + 1;
1474
+
1475
+ default:
1476
+ BUG("attempting unimplemented version");
1477
+ }
1478
+}
1479
+
1480
+static void compute_reachable_generation_numbers(
1481
+ struct compute_generation_info *info,
1482
+ int generation_version)
1483
{
1484
int i;
1485
struct commit_list *list = NULL;
1486
1454
- if (ctx->report_progress)
1455
- ctx->progress = start_delayed_progress(
1456
- _("Computing commit graph topological levels"),
1457
- ctx->commits.nr);
1458
- for (i = 0; i < ctx->commits.nr; i++) {
1459
- struct commit *c = ctx->commits.list[i];
1460
- uint32_t level;
1461
-
1462
- repo_parse_commit(ctx->r, c);
1463
- level = *topo_level_slab_at(ctx->topo_levels, c);
1487
+ for (i = 0; i < info->commits->nr; i++) {
1488
+ struct commit *c = info->commits->list[i];
1489
+ timestamp_t gen;
1490
+ repo_parse_commit(info->r, c);
1491
+ gen = info->get_generation(c, info->data);
1492
+ display_progress(info->progress, info->progress_cnt + 1);
1493
1465
- display_progress(ctx->progress, i + 1);
1466
- if (level != GENERATION_NUMBER_ZERO)
1494
+ if (gen != GENERATION_NUMBER_ZERO && gen != GENERATION_NUMBER_INFINITY)
1495
continue;
1496
1497
commit_list_insert(c, &list);
1499
struct commit *current = list->item;
1500
struct commit_list *parent;
1501
int all_parents_computed = 1;
1474
- uint32_t max_level = 0;
1502
+ uint32_t max_gen = 0;
1503
1504
for (parent = current->parents; parent; parent = parent->next) {
1477
- repo_parse_commit(ctx->r, parent->item);
1478
- level = *topo_level_slab_at(ctx->topo_levels, parent->item);
1505
+ repo_parse_commit(info->r, parent->item);
1506
+ gen = info->get_generation(parent->item, info->data);
1507
1480
- if (level == GENERATION_NUMBER_ZERO) {
1508
+ if (gen == GENERATION_NUMBER_ZERO) {
1509
all_parents_computed = 0;
1510
commit_list_insert(parent->item, &list);
1511
break;
1512
}
1513
1486
- if (level > max_level)
1487
- max_level = level;
1514
+ if (gen > max_gen)
1515
+ max_gen = gen;
1516
}
1517
1518
if (all_parents_computed) {
1519
pop_commit(&list);
1492
-
1493
- if (max_level > GENERATION_NUMBER_V1_MAX - 1)
1494
- max_level = GENERATION_NUMBER_V1_MAX - 1;
1495
- *topo_level_slab_at(ctx->topo_levels, current) = max_level + 1;
1520
+ gen = compute_generation_from_max(
1521
+ current, max_gen,
1522
+ generation_version);
1523
+ info->set_generation(current, gen, info->data);
1524
}
1525
}
1526
}
1527
+}
1528
+
1529
+static timestamp_t get_topo_level(struct commit *c, void *data)
1530
+{
1531
+ struct write_commit_graph_context *ctx = data;
1532
+ return *topo_level_slab_at(ctx->topo_levels, c);
1533
+}
1534
+
1535
+static void set_topo_level(struct commit *c, timestamp_t t, void *data)
1536
+{
1537
+ struct write_commit_graph_context *ctx = data;
1538
+ *topo_level_slab_at(ctx->topo_levels, c) = (uint32_t)t;
1539
+}
1540
+
1541
+static void compute_topological_levels(struct write_commit_graph_context *ctx)
1542
+{
1543
+ struct compute_generation_info info = {
1544
+ .r = ctx->r,
1545
+ .commits = &ctx->commits,
1546
+ .get_generation = get_topo_level,
1547
+ .set_generation = set_topo_level,
1548
+ .data = ctx,
1549
+ };
1550
+
1551
+ if (ctx->report_progress)
1552
+ info.progress = ctx->progress
1553
+ = start_delayed_progress(
1554
+ _("Computing commit graph topological levels"),
1555
+ ctx->commits.nr);
1556
+
1557
+ compute_reachable_generation_numbers(&info, 1);
1558
+
1559
stop_progress(&ctx->progress);
1560
}
1561