pseudo-merge: implement support for finding existing merges
This patch implements support for reusing existing pseudo-merge commits when writing bitmaps when there is an existing pseudo-merge bitmap which has exactly the same set of parents as one that we are about to write. Note that unstable pseudo-merges are likely to change between consecutive repacks, and so are generally poor candidates for reuse. However, stable pseudo-merges (see the configuration option 'bitmapPseudoMerge.<name>.stableThreshold') are by definition unlikely to change between runs (as they represent long-running branches). Because there is no index from a *set* of pseudo-merge parents to a matching pseudo-merge bitmap, we have to construct the bitmap corresponding to the set of parents for each pending pseudo-merge commit and see if a matching bitmap exists. This is technically quadratic in the number of pseudo-merges, but is OK in practice for a couple of reasons: - non-matching pseudo-merge bitmaps are rejected quickly as soon as they differ in a single bit - already-matched pseudo-merge bitmaps are discarded from subsequent rounds of search - the number of pseudo-merges is generally small, even for large repositories In order to do this, implement (a) a function that finds a matching pseudo-merge given some uncompressed bitset describing its parents, (b) a function that computes the bitset of parents for a given pseudo-merge commit, and (c) call that function before computing the set of reachable objects for some pending pseudo-merge. 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
94c1addf86
commit
7252d9a036
@ -1316,6 +1316,37 @@ cleanup:
|
||||
return cb.base;
|
||||
}
|
||||
|
||||
struct ewah_bitmap *pseudo_merge_bitmap_for_commit(struct bitmap_index *bitmap_git,
|
||||
struct commit *commit)
|
||||
{
|
||||
struct commit_list *p;
|
||||
struct bitmap *parents;
|
||||
struct pseudo_merge *match = NULL;
|
||||
|
||||
if (!bitmap_git->pseudo_merges.nr)
|
||||
return NULL;
|
||||
|
||||
parents = bitmap_new();
|
||||
|
||||
for (p = commit->parents; p; p = p->next) {
|
||||
int pos = bitmap_position(bitmap_git, &p->item->object.oid);
|
||||
if (pos < 0 || pos >= bitmap_num_objects(bitmap_git))
|
||||
goto done;
|
||||
|
||||
bitmap_set(parents, pos);
|
||||
}
|
||||
|
||||
match = pseudo_merge_for_parents(&bitmap_git->pseudo_merges,
|
||||
parents);
|
||||
|
||||
done:
|
||||
bitmap_free(parents);
|
||||
if (match)
|
||||
return pseudo_merge_bitmap(&bitmap_git->pseudo_merges, match);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void unsatisfy_all_pseudo_merges(struct bitmap_index *bitmap_git)
|
||||
{
|
||||
uint32_t i;
|
||||
@ -2809,6 +2840,7 @@ void free_bitmap_index(struct bitmap_index *b)
|
||||
*/
|
||||
close_midx_revindex(b->midx);
|
||||
}
|
||||
free_pseudo_merge_map(&b->pseudo_merges);
|
||||
free(b);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user