pack-bitmap.c: use pseudo-merges during traversal
Now that all of the groundwork has been laid to support reading and
using pseudo-merges, make use of that work in this commit by teaching
the pack-bitmap machinery to use pseudo-merge(s) when available during
traversal.
The basic operation is as follows:
- When enumerating objects on either side of a reachability query,
first see if any subset of the roots satisfies some pseudo-merge
bitmap. If it does, apply that pseudo-merge bitmap.
- If any pseudo-merge bitmap(s) were applied in the previous step, OR
them into the result[^1]. Then repeat the process over all
pseudo-merge bitmaps (we'll refer to this as "cascading"
pseudo-merges). Once this is done, OR in the resulting bitmap.
- If there is no fill-in traversal to be done, return the bitmap for
that side of the reachability query. If there is fill-in traversal,
then for each commit we encounter via show_commit(), check to see if
any unsatisfied pseudo-merges containing that commit as one of its
parents has been made satisfied by the presence of that commit.
If so, OR in the object set from that pseudo-merge bitmap, and then
cascade. If not, continue traversal.
A similar implementation is present in the boundary-based bitmap
traversal routines.
[^1]: Importantly, we cannot OR in the entire set of roots along with
the objects reachable from whatever pseudo-merge bitmaps were
satisfied. This may leave some dangling bits corresponding to any
unsatisfied root(s) getting OR'd into the resulting bitmap, tricking
other parts of the traversal into thinking we already have a
reachability closure over those commit(s) when we do not.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
8e41468ef3
commit
11d45a6e6a
112
pack-bitmap.c
112
pack-bitmap.c
@ -114,6 +114,9 @@ struct bitmap_index {
|
||||
unsigned int version;
|
||||
};
|
||||
|
||||
static int pseudo_merges_satisfied_nr;
|
||||
static int pseudo_merges_cascades_nr;
|
||||
|
||||
static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
|
||||
{
|
||||
struct ewah_bitmap *parent;
|
||||
@ -1006,6 +1009,22 @@ static void show_commit(struct commit *commit UNUSED,
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned apply_pseudo_merges_for_commit_1(struct bitmap_index *bitmap_git,
|
||||
struct bitmap *result,
|
||||
struct commit *commit,
|
||||
uint32_t commit_pos)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = apply_pseudo_merges_for_commit(&bitmap_git->pseudo_merges,
|
||||
result, commit, commit_pos);
|
||||
|
||||
if (ret)
|
||||
pseudo_merges_satisfied_nr += ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int add_to_include_set(struct bitmap_index *bitmap_git,
|
||||
struct include_data *data,
|
||||
struct commit *commit,
|
||||
@ -1026,6 +1045,10 @@ static int add_to_include_set(struct bitmap_index *bitmap_git,
|
||||
}
|
||||
|
||||
bitmap_set(data->base, bitmap_pos);
|
||||
if (apply_pseudo_merges_for_commit_1(bitmap_git, data->base, commit,
|
||||
bitmap_pos))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1151,6 +1174,20 @@ static void show_boundary_object(struct object *object UNUSED,
|
||||
BUG("should not be called");
|
||||
}
|
||||
|
||||
static unsigned cascade_pseudo_merges_1(struct bitmap_index *bitmap_git,
|
||||
struct bitmap *result,
|
||||
struct bitmap *roots)
|
||||
{
|
||||
int ret = cascade_pseudo_merges(&bitmap_git->pseudo_merges,
|
||||
result, roots);
|
||||
if (ret) {
|
||||
pseudo_merges_cascades_nr++;
|
||||
pseudo_merges_satisfied_nr += ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
|
||||
struct rev_info *revs,
|
||||
struct object_list *roots)
|
||||
@ -1160,6 +1197,7 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
|
||||
unsigned int i;
|
||||
unsigned int tmp_blobs, tmp_trees, tmp_tags;
|
||||
int any_missing = 0;
|
||||
int existing_bitmaps = 0;
|
||||
|
||||
cb.bitmap_git = bitmap_git;
|
||||
cb.base = bitmap_new();
|
||||
@ -1167,6 +1205,25 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
|
||||
|
||||
revs->ignore_missing_links = 1;
|
||||
|
||||
if (bitmap_git->pseudo_merges.nr) {
|
||||
struct bitmap *roots_bitmap = bitmap_new();
|
||||
struct object_list *objects = NULL;
|
||||
|
||||
for (objects = roots; objects; objects = objects->next) {
|
||||
struct object *object = objects->item;
|
||||
int pos;
|
||||
|
||||
pos = bitmap_position(bitmap_git, &object->oid);
|
||||
if (pos < 0)
|
||||
continue;
|
||||
|
||||
bitmap_set(roots_bitmap, pos);
|
||||
}
|
||||
|
||||
if (!cascade_pseudo_merges_1(bitmap_git, cb.base, roots_bitmap))
|
||||
bitmap_free(roots_bitmap);
|
||||
}
|
||||
|
||||
/*
|
||||
* OR in any existing reachability bitmaps among `roots` into
|
||||
* `cb.base`.
|
||||
@ -1178,8 +1235,10 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
|
||||
continue;
|
||||
|
||||
if (add_commit_to_bitmap(bitmap_git, &cb.base,
|
||||
(struct commit *)object))
|
||||
(struct commit *)object)) {
|
||||
existing_bitmaps = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
any_missing = 1;
|
||||
}
|
||||
@ -1187,6 +1246,9 @@ static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
|
||||
if (!any_missing)
|
||||
goto cleanup;
|
||||
|
||||
if (existing_bitmaps)
|
||||
cascade_pseudo_merges_1(bitmap_git, cb.base, NULL);
|
||||
|
||||
tmp_blobs = revs->blob_objects;
|
||||
tmp_trees = revs->tree_objects;
|
||||
tmp_tags = revs->blob_objects;
|
||||
@ -1242,6 +1304,13 @@ cleanup:
|
||||
return cb.base;
|
||||
}
|
||||
|
||||
static void unsatisfy_all_pseudo_merges(struct bitmap_index *bitmap_git)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < bitmap_git->pseudo_merges.nr; i++)
|
||||
bitmap_git->pseudo_merges.v[i].satisfied = 0;
|
||||
}
|
||||
|
||||
static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
|
||||
struct rev_info *revs,
|
||||
struct object_list *roots,
|
||||
@ -1249,9 +1318,32 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
|
||||
{
|
||||
struct bitmap *base = NULL;
|
||||
int needs_walk = 0;
|
||||
unsigned existing_bitmaps = 0;
|
||||
|
||||
struct object_list *not_mapped = NULL;
|
||||
|
||||
unsatisfy_all_pseudo_merges(bitmap_git);
|
||||
|
||||
if (bitmap_git->pseudo_merges.nr) {
|
||||
struct bitmap *roots_bitmap = bitmap_new();
|
||||
struct object_list *objects = NULL;
|
||||
|
||||
for (objects = roots; objects; objects = objects->next) {
|
||||
struct object *object = objects->item;
|
||||
int pos;
|
||||
|
||||
pos = bitmap_position(bitmap_git, &object->oid);
|
||||
if (pos < 0)
|
||||
continue;
|
||||
|
||||
bitmap_set(roots_bitmap, pos);
|
||||
}
|
||||
|
||||
base = bitmap_new();
|
||||
if (!cascade_pseudo_merges_1(bitmap_git, base, roots_bitmap))
|
||||
bitmap_free(roots_bitmap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through all the roots for the walk. The ones that have bitmaps
|
||||
* on the bitmap index will be `or`ed together to form an initial
|
||||
@ -1262,11 +1354,21 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
|
||||
*/
|
||||
while (roots) {
|
||||
struct object *object = roots->item;
|
||||
|
||||
roots = roots->next;
|
||||
|
||||
if (base) {
|
||||
int pos = bitmap_position(bitmap_git, &object->oid);
|
||||
if (pos > 0 && bitmap_get(base, pos)) {
|
||||
object->flags |= SEEN;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (object->type == OBJ_COMMIT &&
|
||||
add_commit_to_bitmap(bitmap_git, &base, (struct commit *)object)) {
|
||||
object->flags |= SEEN;
|
||||
existing_bitmaps = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1282,6 +1384,9 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
|
||||
|
||||
roots = not_mapped;
|
||||
|
||||
if (existing_bitmaps)
|
||||
cascade_pseudo_merges_1(bitmap_git, base, NULL);
|
||||
|
||||
/*
|
||||
* Let's iterate through all the roots that don't have bitmaps to
|
||||
* check if we can determine them to be reachable from the existing
|
||||
@ -1866,6 +1971,11 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
|
||||
object_list_free(&wants);
|
||||
object_list_free(&haves);
|
||||
|
||||
trace2_data_intmax("bitmap", the_repository, "pseudo_merges_satisfied",
|
||||
pseudo_merges_satisfied_nr);
|
||||
trace2_data_intmax("bitmap", the_repository, "pseudo_merges_cascades",
|
||||
pseudo_merges_cascades_nr);
|
||||
|
||||
return bitmap_git;
|
||||
|
||||
cleanup:
|
||||
|
||||
Reference in New Issue
Block a user