Skip to content

Commit a301a8a

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]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cee4f3c commit a301a8a

File tree

1 file changed

+84
-21
lines changed

1 file changed

+84
-21
lines changed

pack-bitmap.c

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -943,8 +943,9 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
943943
return NULL;
944944
}
945945

946-
struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
947-
struct commit *commit)
946+
static struct ewah_bitmap *find_bitmap_for_commit(struct bitmap_index *bitmap_git,
947+
struct commit *commit,
948+
struct bitmap_index **found)
948949
{
949950
khiter_t hash_pos;
950951
if (!bitmap_git)
@@ -954,18 +955,30 @@ struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
954955
if (hash_pos >= kh_end(bitmap_git->bitmaps)) {
955956
struct stored_bitmap *bitmap = NULL;
956957
if (!bitmap_git->table_lookup)
957-
return bitmap_for_commit(bitmap_git->base, commit);
958+
return find_bitmap_for_commit(bitmap_git->base, commit,
959+
found);
958960

959961
/* this is a fairly hot codepath - no trace2_region please */
960962
/* NEEDSWORK: cache misses aren't recorded */
961963
bitmap = lazy_bitmap_for_commit(bitmap_git, commit);
962964
if (!bitmap)
963-
return bitmap_for_commit(bitmap_git->base, commit);
965+
return find_bitmap_for_commit(bitmap_git->base, commit,
966+
found);
967+
if (found)
968+
*found = bitmap_git;
964969
return lookup_stored_bitmap(bitmap);
965970
}
971+
if (found)
972+
*found = bitmap_git;
966973
return lookup_stored_bitmap(kh_value(bitmap_git->bitmaps, hash_pos));
967974
}
968975

976+
struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
977+
struct commit *commit)
978+
{
979+
return find_bitmap_for_commit(bitmap_git, commit, NULL);
980+
}
981+
969982
static inline int bitmap_position_extended(struct bitmap_index *bitmap_git,
970983
const struct object_id *oid)
971984
{
@@ -2489,6 +2502,8 @@ struct bitmap_test_data {
24892502
struct bitmap *tags;
24902503
struct progress *prg;
24912504
size_t seen;
2505+
2506+
struct bitmap_test_data *base_tdata;
24922507
};
24932508

24942509
static void test_bitmap_type(struct bitmap_test_data *tdata,
@@ -2497,6 +2512,11 @@ static void test_bitmap_type(struct bitmap_test_data *tdata,
24972512
enum object_type bitmap_type = OBJ_NONE;
24982513
int bitmaps_nr = 0;
24992514

2515+
if (bitmap_is_midx(tdata->bitmap_git)) {
2516+
while (pos < tdata->bitmap_git->midx->num_objects_in_base)
2517+
tdata = tdata->base_tdata;
2518+
}
2519+
25002520
if (bitmap_get(tdata->commits, pos)) {
25012521
bitmap_type = OBJ_COMMIT;
25022522
bitmaps_nr++;
@@ -2560,13 +2580,57 @@ static void test_show_commit(struct commit *commit, void *data)
25602580
display_progress(tdata->prg, ++tdata->seen);
25612581
}
25622582

2583+
static uint32_t bitmap_total_entry_count(struct bitmap_index *bitmap_git)
2584+
{
2585+
uint32_t total = 0;
2586+
do {
2587+
total = st_add(total, bitmap_git->entry_count);
2588+
bitmap_git = bitmap_git->base;
2589+
} while (bitmap_git);
2590+
2591+
return total;
2592+
}
2593+
2594+
static void prepare_bitmap_test_data(struct bitmap_test_data *tdata,
2595+
struct bitmap_index *bitmap_git)
2596+
{
2597+
memset(tdata, 0, sizeof(struct bitmap_test_data));
2598+
2599+
tdata->bitmap_git = bitmap_git;
2600+
tdata->base = bitmap_new();
2601+
tdata->commits = ewah_to_bitmap(bitmap_git->commits);
2602+
tdata->trees = ewah_to_bitmap(bitmap_git->trees);
2603+
tdata->blobs = ewah_to_bitmap(bitmap_git->blobs);
2604+
tdata->tags = ewah_to_bitmap(bitmap_git->tags);
2605+
2606+
if (bitmap_git->base) {
2607+
CALLOC_ARRAY(tdata->base_tdata, 1);
2608+
prepare_bitmap_test_data(tdata->base_tdata, bitmap_git->base);
2609+
}
2610+
}
2611+
2612+
static void free_bitmap_test_data(struct bitmap_test_data *tdata)
2613+
{
2614+
if (!tdata)
2615+
return;
2616+
2617+
free_bitmap_test_data(tdata->base_tdata);
2618+
free(tdata->base_tdata);
2619+
2620+
bitmap_free(tdata->base);
2621+
bitmap_free(tdata->commits);
2622+
bitmap_free(tdata->trees);
2623+
bitmap_free(tdata->blobs);
2624+
bitmap_free(tdata->tags);
2625+
}
2626+
25632627
void test_bitmap_walk(struct rev_info *revs)
25642628
{
25652629
struct object *root;
25662630
struct bitmap *result = NULL;
25672631
size_t result_popcnt;
25682632
struct bitmap_test_data tdata;
2569-
struct bitmap_index *bitmap_git;
2633+
struct bitmap_index *bitmap_git, *found;
25702634
struct ewah_bitmap *bm;
25712635

25722636
if (!(bitmap_git = prepare_bitmap_git(revs->repo)))
@@ -2575,17 +2639,26 @@ void test_bitmap_walk(struct rev_info *revs)
25752639
if (revs->pending.nr != 1)
25762640
die(_("you must specify exactly one commit to test"));
25772641

2578-
fprintf_ln(stderr, "Bitmap v%d test (%d entries%s)",
2642+
fprintf_ln(stderr, "Bitmap v%d test (%d entries%s, %d total)",
25792643
bitmap_git->version,
25802644
bitmap_git->entry_count,
2581-
bitmap_git->table_lookup ? "" : " loaded");
2645+
bitmap_git->table_lookup ? "" : " loaded",
2646+
bitmap_total_entry_count(bitmap_git));
25822647

25832648
root = revs->pending.objects[0].item;
2584-
bm = bitmap_for_commit(bitmap_git, (struct commit *)root);
2649+
bm = find_bitmap_for_commit(bitmap_git, (struct commit *)root, &found);
25852650

25862651
if (bm) {
25872652
fprintf_ln(stderr, "Found bitmap for '%s'. %d bits / %08x checksum",
2588-
oid_to_hex(&root->oid), (int)bm->bit_size, ewah_checksum(bm));
2653+
oid_to_hex(&root->oid),
2654+
(int)bm->bit_size, ewah_checksum(bm));
2655+
2656+
if (bitmap_is_midx(found))
2657+
fprintf_ln(stderr, "Located via MIDX '%s'.",
2658+
hash_to_hex(get_midx_checksum(found->midx)));
2659+
else
2660+
fprintf_ln(stderr, "Located via pack '%s'.",
2661+
hash_to_hex(found->pack->hash));
25892662

25902663
result = ewah_to_bitmap(bm);
25912664
}
@@ -2602,14 +2675,8 @@ void test_bitmap_walk(struct rev_info *revs)
26022675
if (prepare_revision_walk(revs))
26032676
die(_("revision walk setup failed"));
26042677

2605-
tdata.bitmap_git = bitmap_git;
2606-
tdata.base = bitmap_new();
2607-
tdata.commits = ewah_to_bitmap(bitmap_git->commits);
2608-
tdata.trees = ewah_to_bitmap(bitmap_git->trees);
2609-
tdata.blobs = ewah_to_bitmap(bitmap_git->blobs);
2610-
tdata.tags = ewah_to_bitmap(bitmap_git->tags);
2678+
prepare_bitmap_test_data(&tdata, bitmap_git);
26112679
tdata.prg = start_progress("Verifying bitmap entries", result_popcnt);
2612-
tdata.seen = 0;
26132680

26142681
traverse_commit_list(revs, &test_show_commit, &test_show_object, &tdata);
26152682

@@ -2621,11 +2688,7 @@ void test_bitmap_walk(struct rev_info *revs)
26212688
die(_("mismatch in bitmap results"));
26222689

26232690
bitmap_free(result);
2624-
bitmap_free(tdata.base);
2625-
bitmap_free(tdata.commits);
2626-
bitmap_free(tdata.trees);
2627-
bitmap_free(tdata.blobs);
2628-
bitmap_free(tdata.tags);
2691+
free_bitmap_test_data(&tdata);
26292692
free_bitmap_index(bitmap_git);
26302693
}
26312694

0 commit comments

Comments
 (0)