@@ -943,8 +943,9 @@ static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_
return NULL;
}
-struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
- struct commit *commit)
+static struct ewah_bitmap *find_bitmap_for_commit(struct bitmap_index *bitmap_git,
+ struct commit *commit,
+ struct bitmap_index **found)
{
khiter_t hash_pos;
if (!bitmap_git)
@@ -954,18 +955,30 @@ struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
if (hash_pos >= kh_end(bitmap_git->bitmaps)) {
struct stored_bitmap *bitmap = NULL;
if (!bitmap_git->table_lookup)
- return bitmap_for_commit(bitmap_git->base, commit);
+ return find_bitmap_for_commit(bitmap_git->base, commit,
+ found);
/* this is a fairly hot codepath - no trace2_region please */
/* NEEDSWORK: cache misses aren't recorded */
bitmap = lazy_bitmap_for_commit(bitmap_git, commit);
if (!bitmap)
- return bitmap_for_commit(bitmap_git->base, commit);
+ return find_bitmap_for_commit(bitmap_git->base, commit,
+ found);
+ if (found)
+ *found = bitmap_git;
return lookup_stored_bitmap(bitmap);
}
+ if (found)
+ *found = bitmap_git;
return lookup_stored_bitmap(kh_value(bitmap_git->bitmaps, hash_pos));
}
+struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
+ struct commit *commit)
+{
+ return find_bitmap_for_commit(bitmap_git, commit, NULL);
+}
+
static inline int bitmap_position_extended(struct bitmap_index *bitmap_git,
const struct object_id *oid)
{
@@ -2489,6 +2502,8 @@ struct bitmap_test_data {
struct bitmap *tags;
struct progress *prg;
size_t seen;
+
+ struct bitmap_test_data *base_tdata;
};
static void test_bitmap_type(struct bitmap_test_data *tdata,
@@ -2497,6 +2512,11 @@ static void test_bitmap_type(struct bitmap_test_data *tdata,
enum object_type bitmap_type = OBJ_NONE;
int bitmaps_nr = 0;
+ if (bitmap_is_midx(tdata->bitmap_git)) {
+ while (pos < tdata->bitmap_git->midx->num_objects_in_base)
+ tdata = tdata->base_tdata;
+ }
+
if (bitmap_get(tdata->commits, pos)) {
bitmap_type = OBJ_COMMIT;
bitmaps_nr++;
@@ -2560,13 +2580,57 @@ static void test_show_commit(struct commit *commit, void *data)
display_progress(tdata->prg, ++tdata->seen);
}
+static uint32_t bitmap_total_entry_count(struct bitmap_index *bitmap_git)
+{
+ uint32_t total = 0;
+ do {
+ total = st_add(total, bitmap_git->entry_count);
+ bitmap_git = bitmap_git->base;
+ } while (bitmap_git);
+
+ return total;
+}
+
+static void prepare_bitmap_test_data(struct bitmap_test_data *tdata,
+ struct bitmap_index *bitmap_git)
+{
+ memset(tdata, 0, sizeof(struct bitmap_test_data));
+
+ tdata->bitmap_git = bitmap_git;
+ tdata->base = bitmap_new();
+ tdata->commits = ewah_to_bitmap(bitmap_git->commits);
+ tdata->trees = ewah_to_bitmap(bitmap_git->trees);
+ tdata->blobs = ewah_to_bitmap(bitmap_git->blobs);
+ tdata->tags = ewah_to_bitmap(bitmap_git->tags);
+
+ if (bitmap_git->base) {
+ CALLOC_ARRAY(tdata->base_tdata, 1);
+ prepare_bitmap_test_data(tdata->base_tdata, bitmap_git->base);
+ }
+}
+
+static void free_bitmap_test_data(struct bitmap_test_data *tdata)
+{
+ if (!tdata)
+ return;
+
+ free_bitmap_test_data(tdata->base_tdata);
+ free(tdata->base_tdata);
+
+ bitmap_free(tdata->base);
+ bitmap_free(tdata->commits);
+ bitmap_free(tdata->trees);
+ bitmap_free(tdata->blobs);
+ bitmap_free(tdata->tags);
+}
+
void test_bitmap_walk(struct rev_info *revs)
{
struct object *root;
struct bitmap *result = NULL;
size_t result_popcnt;
struct bitmap_test_data tdata;
- struct bitmap_index *bitmap_git;
+ struct bitmap_index *bitmap_git, *found;
struct ewah_bitmap *bm;
if (!(bitmap_git = prepare_bitmap_git(revs->repo)))
@@ -2575,17 +2639,26 @@ void test_bitmap_walk(struct rev_info *revs)
if (revs->pending.nr != 1)
die(_("you must specify exactly one commit to test"));
- fprintf_ln(stderr, "Bitmap v%d test (%d entries%s)",
+ fprintf_ln(stderr, "Bitmap v%d test (%d entries%s, %d total)",
bitmap_git->version,
bitmap_git->entry_count,
- bitmap_git->table_lookup ? "" : " loaded");
+ bitmap_git->table_lookup ? "" : " loaded",
+ bitmap_total_entry_count(bitmap_git));
root = revs->pending.objects[0].item;
- bm = bitmap_for_commit(bitmap_git, (struct commit *)root);
+ bm = find_bitmap_for_commit(bitmap_git, (struct commit *)root, &found);
if (bm) {
fprintf_ln(stderr, "Found bitmap for '%s'. %d bits / %08x checksum",
- oid_to_hex(&root->oid), (int)bm->bit_size, ewah_checksum(bm));
+ oid_to_hex(&root->oid),
+ (int)bm->bit_size, ewah_checksum(bm));
+
+ if (bitmap_is_midx(found))
+ fprintf_ln(stderr, "Located via MIDX '%s'.",
+ hash_to_hex(get_midx_checksum(found->midx)));
+ else
+ fprintf_ln(stderr, "Located via pack '%s'.",
+ hash_to_hex(found->pack->hash));
result = ewah_to_bitmap(bm);
}
@@ -2602,14 +2675,8 @@ void test_bitmap_walk(struct rev_info *revs)
if (prepare_revision_walk(revs))
die(_("revision walk setup failed"));
- tdata.bitmap_git = bitmap_git;
- tdata.base = bitmap_new();
- tdata.commits = ewah_to_bitmap(bitmap_git->commits);
- tdata.trees = ewah_to_bitmap(bitmap_git->trees);
- tdata.blobs = ewah_to_bitmap(bitmap_git->blobs);
- tdata.tags = ewah_to_bitmap(bitmap_git->tags);
+ prepare_bitmap_test_data(&tdata, bitmap_git);
tdata.prg = start_progress("Verifying bitmap entries", result_popcnt);
- tdata.seen = 0;
traverse_commit_list(revs, &test_show_commit, &test_show_object, &tdata);
@@ -2621,11 +2688,7 @@ void test_bitmap_walk(struct rev_info *revs)
die(_("mismatch in bitmap results"));
bitmap_free(result);
- bitmap_free(tdata.base);
- bitmap_free(tdata.commits);
- bitmap_free(tdata.trees);
- bitmap_free(tdata.blobs);
- bitmap_free(tdata.tags);
+ free_bitmap_test_data(&tdata);
free_bitmap_index(bitmap_git);
}
Signed-off-by: Taylor Blau <me@ttaylorr.com> --- pack-bitmap.c | 105 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 21 deletions(-)