pack-bitmap: implement test helpers for pseudo-merge

Implement three new sub-commands for the "bitmap" test-helper: - t/helper test-tool bitmap dump-pseudo-merges - t/helper test-tool bitmap dump-pseudo-merge-commits <n> - t/helper test-tool bitmap dump-pseudo-merge-objects <n> These three helpers dump the list of pseudo merges, the "parents" of the nth pseudo-merges, and the set of objects reachable from those parents, respectively. These helpers will be useful in subsequent patches when we add test coverage for pseudo-merge bitmaps. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed May 23, 2024 at 17:27 UTC 71eca9ab7945b23c057c14259a99c3c1bd6872f9
3 files changed +156 -7
pack-bitmap.c
+126
@@ -2443,6 +2443,132 @@ cleanup:
2443 return 0;
2444 }
2445
2446 +static void bit_pos_to_object_id(struct bitmap_index *bitmap_git,
2447 + uint32_t bit_pos,
2448 + struct object_id *oid)
2449 +{
2450 + uint32_t index_pos;
2451 +
2452 + if (bitmap_is_midx(bitmap_git))
2453 + index_pos = pack_pos_to_midx(bitmap_git->midx, bit_pos);
2454 + else
2455 + index_pos = pack_pos_to_index(bitmap_git->pack, bit_pos);
2456 +
2457 + nth_bitmap_object_oid(bitmap_git, oid, index_pos);
2458 +}
2459 +
2460 +int test_bitmap_pseudo_merges(struct repository *r)
2461 +{
2462 + struct bitmap_index *bitmap_git;
2463 + uint32_t i;
2464 +
2465 + bitmap_git = prepare_bitmap_git(r);
2466 + if (!bitmap_git || !bitmap_git->pseudo_merges.nr)
2467 + goto cleanup;
2468 +
2469 + for (i = 0; i < bitmap_git->pseudo_merges.nr; i++) {
2470 + struct pseudo_merge *merge;
2471 + struct ewah_bitmap *commits_bitmap, *merge_bitmap;
2472 +
2473 + merge = use_pseudo_merge(&bitmap_git->pseudo_merges,
2474 + &bitmap_git->pseudo_merges.v[i]);
2475 + commits_bitmap = merge->commits;
2476 + merge_bitmap = pseudo_merge_bitmap(&bitmap_git->pseudo_merges,
2477 + merge);
2478 +
2479 + printf("at=%"PRIuMAX", commits=%"PRIuMAX", objects=%"PRIuMAX"\n",
2480 + (uintmax_t)merge->at,
2481 + (uintmax_t)ewah_bitmap_popcount(commits_bitmap),
2482 + (uintmax_t)ewah_bitmap_popcount(merge_bitmap));
2483 + }
2484 +
2485 +cleanup:
2486 + free_bitmap_index(bitmap_git);
2487 + return 0;
2488 +}
2489 +
2490 +static void dump_ewah_object_ids(struct bitmap_index *bitmap_git,
2491 + struct ewah_bitmap *bitmap)
2492 +
2493 +{
2494 + struct ewah_iterator it;
2495 + eword_t word;
2496 + uint32_t pos = 0;
2497 +
2498 + ewah_iterator_init(&it, bitmap);
2499 +
2500 + while (ewah_iterator_next(&word, &it)) {
2501 + struct object_id oid;
2502 + uint32_t offset;
2503 +
2504 + for (offset = 0; offset < BITS_IN_EWORD; offset++) {
2505 + if (!(word >> offset))
2506 + break;
2507 +
2508 + offset += ewah_bit_ctz64(word >> offset);
2509 +
2510 + bit_pos_to_object_id(bitmap_git, pos + offset, &oid);
2511 + printf("%s\n", oid_to_hex(&oid));
2512 + }
2513 + pos += BITS_IN_EWORD;
2514 + }
2515 +}
2516 +
2517 +int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n)
2518 +{
2519 + struct bitmap_index *bitmap_git;
2520 + struct pseudo_merge *merge;
2521 + int ret = 0;
2522 +
2523 + bitmap_git = prepare_bitmap_git(r);
2524 + if (!bitmap_git || !bitmap_git->pseudo_merges.nr)
2525 + goto cleanup;
2526 +
2527 + if (n >= bitmap_git->pseudo_merges.nr) {
2528 + ret = error(_("pseudo-merge index out of range "
2529 + "(%"PRIu32" >= %"PRIuMAX")"),
2530 + n, (uintmax_t)bitmap_git->pseudo_merges.nr);
2531 + goto cleanup;
2532 + }
2533 +
2534 + merge = use_pseudo_merge(&bitmap_git->pseudo_merges,
2535 + &bitmap_git->pseudo_merges.v[n]);
2536 + dump_ewah_object_ids(bitmap_git, merge->commits);
2537 +
2538 +cleanup:
2539 + free_bitmap_index(bitmap_git);
2540 + return ret;
2541 +}
2542 +
2543 +int test_bitmap_pseudo_merge_objects(struct repository *r, uint32_t n)
2544 +{
2545 + struct bitmap_index *bitmap_git;
2546 + struct pseudo_merge *merge;
2547 + int ret = 0;
2548 +
2549 + bitmap_git = prepare_bitmap_git(r);
2550 + if (!bitmap_git || !bitmap_git->pseudo_merges.nr)
2551 + goto cleanup;
2552 +
2553 + if (n >= bitmap_git->pseudo_merges.nr) {
2554 + ret = error(_("pseudo-merge index out of range "
2555 + "(%"PRIu32" >= %"PRIuMAX")"),
2556 + n, (uintmax_t)bitmap_git->pseudo_merges.nr);
2557 + goto cleanup;
2558 + }
2559 +
2560 + merge = use_pseudo_merge(&bitmap_git->pseudo_merges,
2561 + &bitmap_git->pseudo_merges.v[n]);
2562 +
2563 + dump_ewah_object_ids(bitmap_git,
2564 + pseudo_merge_bitmap(&bitmap_git->pseudo_merges,
2565 + merge));
2566 +
2567 +cleanup:
2568 + free_bitmap_index(bitmap_git);
2569 + return ret;
2570 +}
2571 +
2572 int rebuild_bitmap(const uint32_t *reposition,
2573 struct ewah_bitmap *source,
2574 struct bitmap *dest)
pack-bitmap.h
+3
@@ -73,6 +73,9 @@ void traverse_bitmap_commit_list(struct bitmap_index *,
73 void test_bitmap_walk(struct rev_info *revs);
74 int test_bitmap_commits(struct repository *r);
75 int test_bitmap_hashes(struct repository *r);
76 +int test_bitmap_pseudo_merges(struct repository *r);
77 +int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n);
78 +int test_bitmap_pseudo_merge_objects(struct repository *r, uint32_t n);
79
80 #define GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL \
81 "GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL"
t/helper/test-bitmap.c
+27 -7
@@ -13,21 +13,41 @@ static int bitmap_dump_hashes(void)
13 return test_bitmap_hashes(the_repository);
14 }
15
16 +static int bitmap_dump_pseudo_merges(void)
17 +{
18 + return test_bitmap_pseudo_merges(the_repository);
19 +}
20 +
21 +static int bitmap_dump_pseudo_merge_commits(uint32_t n)
22 +{
23 + return test_bitmap_pseudo_merge_commits(the_repository, n);
24 +}
25 +
26 +static int bitmap_dump_pseudo_merge_objects(uint32_t n)
27 +{
28 + return test_bitmap_pseudo_merge_objects(the_repository, n);
29 +}
30 +
31 int cmd__bitmap(int argc, const char **argv)
32 {
33 setup_git_directory();
34
20 - if (argc != 2)
21 - goto usage;
22 -
23 - if (!strcmp(argv[1], "list-commits"))
35 + if (argc == 2 && !strcmp(argv[1], "list-commits"))
36 return bitmap_list_commits();
25 - if (!strcmp(argv[1], "dump-hashes"))
37 + if (argc == 2 && !strcmp(argv[1], "dump-hashes"))
38 return bitmap_dump_hashes();
39 + if (argc == 2 && !strcmp(argv[1], "dump-pseudo-merges"))
40 + return bitmap_dump_pseudo_merges();
41 + if (argc == 3 && !strcmp(argv[1], "dump-pseudo-merge-commits"))
42 + return bitmap_dump_pseudo_merge_commits(atoi(argv[2]));
43 + if (argc == 3 && !strcmp(argv[1], "dump-pseudo-merge-objects"))
44 + return bitmap_dump_pseudo_merge_objects(atoi(argv[2]));
45
28 -usage:
46 usage("\ttest-tool bitmap list-commits\n"
30 - "\ttest-tool bitmap dump-hashes");
47 + "\ttest-tool bitmap dump-hashes\n"
48 + "\ttest-tool bitmap dump-pseudo-merges\n"
49 + "\ttest-tool bitmap dump-pseudo-merge-commits <n>\n"
50 + "\ttest-tool bitmap dump-pseudo-merge-objects <n>");
51
52 return -1;
53 }