Skip to content

Commit faab03f

Browse files
ttaylorrgitster
authored andcommitted
pack-bitmap.c: teach rev-list --test-bitmap about incremental MIDXs
Implement support for the special `--test-bitmap` mode of `git rev-list` when using incremental MIDXs. The bitmap_test_data structure is extended to contain a "base" pointer that mirrors the structure of the bitmap chain that it is being used to test. When we find a commit to test, we first chase down the ->base pointer to find the appropriate bitmap_test_data for the bitmap layer that the given commit is contained within, and then perform the test on that bitmap. In order to implement this, light modifications are made to bitmap_for_commit() to reimplement it in terms of a new function, find_bitmap_for_commit(), which fills out a pointer which indicates the bitmap layer which contains the given commit. Signed-off-by: Taylor Blau <[email protected]> Acked-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3886c72 commit faab03f

File tree

1 file changed

+86
-21
lines changed

1 file changed

+86
-21
lines changed

pack-bitmap.c

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -938,8 +938,9 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
938938
return NULL;
939939
}
940940

941-
struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
942-
struct commit *commit)
941+
static struct ewah_bitmap *find_bitmap_for_commit(struct bitmap_index *bitmap_git,
942+
struct commit *commit,
943+
struct bitmap_index **found)
943944
{
944945
khiter_t hash_pos;
945946
if (!bitmap_git)
@@ -949,18 +950,30 @@ struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
949950
if (hash_pos >= kh_end(bitmap_git->bitmaps)) {
950951
struct stored_bitmap *bitmap = NULL;
951952
if (!bitmap_git->table_lookup)
952-
return bitmap_for_commit(bitmap_git->base, commit);
953+
return find_bitmap_for_commit(bitmap_git->base, commit,
954+
found);
953955

954956
/* this is a fairly hot codepath - no trace2_region please */
955957
/* NEEDSWORK: cache misses aren't recorded */
956958
bitmap = lazy_bitmap_for_commit(bitmap_git, commit);
957959
if (!bitmap)
958-
return bitmap_for_commit(bitmap_git->base, commit);
960+
return find_bitmap_for_commit(bitmap_git->base, commit,
961+
found);
962+
if (found)
963+
*found = bitmap_git;
959964
return lookup_stored_bitmap(bitmap);
960965
}
966+
if (found)
967+
*found = bitmap_git;
961968
return lookup_stored_bitmap(kh_value(bitmap_git->bitmaps, hash_pos));
962969
}
963970

971+
struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
972+
struct commit *commit)
973+
{
974+
return find_bitmap_for_commit(bitmap_git, commit, NULL);
975+
}
976+
964977
static inline int bitmap_position_extended(struct bitmap_index *bitmap_git,
965978
const struct object_id *oid)
966979
{
@@ -2513,6 +2526,8 @@ struct bitmap_test_data {
25132526
struct bitmap *tags;
25142527
struct progress *prg;
25152528
size_t seen;
2529+
2530+
struct bitmap_test_data *base_tdata;
25162531
};
25172532

25182533
static void test_bitmap_type(struct bitmap_test_data *tdata,
@@ -2521,6 +2536,11 @@ static void test_bitmap_type(struct bitmap_test_data *tdata,
25212536
enum object_type bitmap_type = OBJ_NONE;
25222537
int bitmaps_nr = 0;
25232538

2539+
if (bitmap_is_midx(tdata->bitmap_git)) {
2540+
while (pos < tdata->bitmap_git->midx->num_objects_in_base)
2541+
tdata = tdata->base_tdata;
2542+
}
2543+
25242544
if (bitmap_get(tdata->commits, pos)) {
25252545
bitmap_type = OBJ_COMMIT;
25262546
bitmaps_nr++;
@@ -2584,13 +2604,57 @@ static void test_show_commit(struct commit *commit, void *data)
25842604
display_progress(tdata->prg, ++tdata->seen);
25852605
}
25862606

2607+
static uint32_t bitmap_total_entry_count(struct bitmap_index *bitmap_git)
2608+
{
2609+
uint32_t total = 0;
2610+
do {
2611+
total = st_add(total, bitmap_git->entry_count);
2612+
bitmap_git = bitmap_git->base;
2613+
} while (bitmap_git);
2614+
2615+
return total;
2616+
}
2617+
2618+
static void bitmap_test_data_prepare(struct bitmap_test_data *tdata,
2619+
struct bitmap_index *bitmap_git)
2620+
{
2621+
memset(tdata, 0, sizeof(struct bitmap_test_data));
2622+
2623+
tdata->bitmap_git = bitmap_git;
2624+
tdata->base = bitmap_new();
2625+
tdata->commits = ewah_to_bitmap(bitmap_git->commits);
2626+
tdata->trees = ewah_to_bitmap(bitmap_git->trees);
2627+
tdata->blobs = ewah_to_bitmap(bitmap_git->blobs);
2628+
tdata->tags = ewah_to_bitmap(bitmap_git->tags);
2629+
2630+
if (bitmap_git->base) {
2631+
tdata->base_tdata = xmalloc(sizeof(struct bitmap_test_data));
2632+
bitmap_test_data_prepare(tdata->base_tdata, bitmap_git->base);
2633+
}
2634+
}
2635+
2636+
static void bitmap_test_data_release(struct bitmap_test_data *tdata)
2637+
{
2638+
if (!tdata)
2639+
return;
2640+
2641+
bitmap_test_data_release(tdata->base_tdata);
2642+
free(tdata->base_tdata);
2643+
2644+
bitmap_free(tdata->base);
2645+
bitmap_free(tdata->commits);
2646+
bitmap_free(tdata->trees);
2647+
bitmap_free(tdata->blobs);
2648+
bitmap_free(tdata->tags);
2649+
}
2650+
25872651
void test_bitmap_walk(struct rev_info *revs)
25882652
{
25892653
struct object *root;
25902654
struct bitmap *result = NULL;
25912655
size_t result_popcnt;
25922656
struct bitmap_test_data tdata;
2593-
struct bitmap_index *bitmap_git;
2657+
struct bitmap_index *bitmap_git, *found;
25942658
struct ewah_bitmap *bm;
25952659

25962660
if (!(bitmap_git = prepare_bitmap_git(revs->repo)))
@@ -2599,17 +2663,28 @@ void test_bitmap_walk(struct rev_info *revs)
25992663
if (revs->pending.nr != 1)
26002664
die(_("you must specify exactly one commit to test"));
26012665

2602-
fprintf_ln(stderr, "Bitmap v%d test (%d entries%s)",
2666+
fprintf_ln(stderr, "Bitmap v%d test (%d entries%s, %d total)",
26032667
bitmap_git->version,
26042668
bitmap_git->entry_count,
2605-
bitmap_git->table_lookup ? "" : " loaded");
2669+
bitmap_git->table_lookup ? "" : " loaded",
2670+
bitmap_total_entry_count(bitmap_git));
26062671

26072672
root = revs->pending.objects[0].item;
2608-
bm = bitmap_for_commit(bitmap_git, (struct commit *)root);
2673+
bm = find_bitmap_for_commit(bitmap_git, (struct commit *)root, &found);
26092674

26102675
if (bm) {
26112676
fprintf_ln(stderr, "Found bitmap for '%s'. %d bits / %08x checksum",
2612-
oid_to_hex(&root->oid), (int)bm->bit_size, ewah_checksum(bm));
2677+
oid_to_hex(&root->oid),
2678+
(int)bm->bit_size, ewah_checksum(bm));
2679+
2680+
if (bitmap_is_midx(found))
2681+
fprintf_ln(stderr, "Located via MIDX '%s'.",
2682+
hash_to_hex_algop(get_midx_checksum(found->midx),
2683+
revs->repo->hash_algo));
2684+
else
2685+
fprintf_ln(stderr, "Located via pack '%s'.",
2686+
hash_to_hex_algop(found->pack->hash,
2687+
revs->repo->hash_algo));
26132688

26142689
result = ewah_to_bitmap(bm);
26152690
}
@@ -2626,16 +2701,10 @@ void test_bitmap_walk(struct rev_info *revs)
26262701
if (prepare_revision_walk(revs))
26272702
die(_("revision walk setup failed"));
26282703

2629-
tdata.bitmap_git = bitmap_git;
2630-
tdata.base = bitmap_new();
2631-
tdata.commits = ewah_to_bitmap(bitmap_git->commits);
2632-
tdata.trees = ewah_to_bitmap(bitmap_git->trees);
2633-
tdata.blobs = ewah_to_bitmap(bitmap_git->blobs);
2634-
tdata.tags = ewah_to_bitmap(bitmap_git->tags);
2704+
bitmap_test_data_prepare(&tdata, bitmap_git);
26352705
tdata.prg = start_progress(revs->repo,
26362706
"Verifying bitmap entries",
26372707
result_popcnt);
2638-
tdata.seen = 0;
26392708

26402709
traverse_commit_list(revs, &test_show_commit, &test_show_object, &tdata);
26412710

@@ -2647,11 +2716,7 @@ void test_bitmap_walk(struct rev_info *revs)
26472716
die(_("mismatch in bitmap results"));
26482717

26492718
bitmap_free(result);
2650-
bitmap_free(tdata.base);
2651-
bitmap_free(tdata.commits);
2652-
bitmap_free(tdata.trees);
2653-
bitmap_free(tdata.blobs);
2654-
bitmap_free(tdata.tags);
2719+
bitmap_test_data_release(&tdata);
26552720
free_bitmap_index(bitmap_git);
26562721
}
26572722

0 commit comments

Comments
 (0)