aboutsummaryrefslogtreecommitdiffstats
path: root/pack-bitmap-write.c
diff options
context:
space:
mode:
authorTaylor Blau <me@ttaylorr.com>2024-05-23 17:27:21 -0400
committerJunio C Hamano <gitster@pobox.com>2024-05-24 11:40:44 -0700
commit7252d9a036fabb10f60dc09937fc39e252f3c4d4 (patch)
tree7c011869a40a48d7fc450cd9e76fa00c3773c2da /pack-bitmap-write.c
parentewah: `bitmap_equals_ewah()` (diff)
downloadgit-7252d9a036fabb10f60dc09937fc39e252f3c4d4.tar.gz
git-7252d9a036fabb10f60dc09937fc39e252f3c4d4.zip
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>
Diffstat (limited to 'pack-bitmap-write.c')
-rw-r--r--pack-bitmap-write.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c
index 47250398aa..6e8060f8a0 100644
--- a/pack-bitmap-write.c
+++ b/pack-bitmap-write.c
@@ -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);