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
@@ -19,6 +19,10 @@
|
||||
#include "tree-walk.h"
|
||||
#include "pseudo-merge.h"
|
||||
#include "oid-array.h"
|
||||
#include "config.h"
|
||||
#include "alloc.h"
|
||||
#include "refs.h"
|
||||
#include "strmap.h"
|
||||
|
||||
struct bitmapped_commit {
|
||||
struct commit *commit;
|
||||
@@ -465,6 +469,7 @@ static int fill_bitmap_tree(struct bitmap_writer *writer,
|
||||
}
|
||||
|
||||
static int reused_bitmaps_nr;
|
||||
static int reused_pseudo_merge_bitmaps_nr;
|
||||
|
||||
static int fill_bitmap_commit(struct bitmap_writer *writer,
|
||||
struct bb_commit *ent,
|
||||
@@ -490,7 +495,7 @@ static int fill_bitmap_commit(struct bitmap_writer *writer,
|
||||
struct bitmap *remapped = bitmap_new();
|
||||
|
||||
if (commit->object.flags & BITMAP_PSEUDO_MERGE)
|
||||
old = NULL;
|
||||
old = pseudo_merge_bitmap_for_commit(old_bitmap, c);
|
||||
else
|
||||
old = bitmap_for_commit(old_bitmap, c);
|
||||
/*
|
||||
@@ -501,7 +506,10 @@ static int fill_bitmap_commit(struct bitmap_writer *writer,
|
||||
if (old && !rebuild_bitmap(mapping, old, remapped)) {
|
||||
bitmap_or(ent->bitmap, remapped);
|
||||
bitmap_free(remapped);
|
||||
reused_bitmaps_nr++;
|
||||
if (commit->object.flags & BITMAP_PSEUDO_MERGE)
|
||||
reused_pseudo_merge_bitmaps_nr++;
|
||||
else
|
||||
reused_bitmaps_nr++;
|
||||
continue;
|
||||
}
|
||||
bitmap_free(remapped);
|
||||
@@ -631,6 +639,9 @@ int bitmap_writer_build(struct bitmap_writer *writer,
|
||||
the_repository);
|
||||
trace2_data_intmax("pack-bitmap-write", the_repository,
|
||||
"building_bitmaps_reused", reused_bitmaps_nr);
|
||||
trace2_data_intmax("pack-bitmap-write", the_repository,
|
||||
"building_bitmaps_pseudo_merge_reused",
|
||||
reused_pseudo_merge_bitmaps_nr);
|
||||
|
||||
stop_progress(&writer->progress);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user