Skip to content

Commit 27afc27

Browse files
ttaylorrgitster
authored andcommitted
midx: implement writing incremental MIDX bitmaps
Now that the pack-bitmap machinery has learned how to read and interact with an incremental MIDX bitmap, teach the pack-bitmap-write.c machinery (and relevant callers from within the MIDX machinery) to write such bitmaps. The details for doing so are mostly straightforward. The main changes are as follows: - find_object_pos() now makes use of an extra MIDX parameter which is used to locate the bit positions of objects which are from previous layers (and thus do not exist in the current layer's pack_order field). (Note also that the pack_order field is moved into struct write_midx_context to further simplify the callers for write_midx_bitmap()). - bitmap_writer_build_type_index() first determines how many objects precede the current bitmap layer and offsets the bits it sets in each respective type-level bitmap by that amount so they can be OR'd together. Signed-off-by: Taylor Blau <[email protected]> Acked-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5999b44 commit 27afc27

File tree

5 files changed

+179
-37
lines changed

5 files changed

+179
-37
lines changed

builtin/pack-objects.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1397,7 +1397,8 @@ static void write_pack_file(void)
13971397

13981398
if (write_bitmap_index) {
13991399
bitmap_writer_init(&bitmap_writer,
1400-
the_repository, &to_pack);
1400+
the_repository, &to_pack,
1401+
NULL);
14011402
bitmap_writer_set_checksum(&bitmap_writer, hash);
14021403
bitmap_writer_build_type_index(&bitmap_writer,
14031404
written_list);

midx-write.c

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -647,16 +647,22 @@ static uint32_t *midx_pack_order(struct write_midx_context *ctx)
647647
return pack_order;
648648
}
649649

650-
static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
651-
struct write_midx_context *ctx)
650+
static void write_midx_reverse_index(struct write_midx_context *ctx,
651+
const char *object_dir,
652+
unsigned char *midx_hash)
652653
{
653654
struct strbuf buf = STRBUF_INIT;
654655
char *tmp_file;
655656

656657
trace2_region_enter("midx", "write_midx_reverse_index", ctx->repo);
657658

658-
strbuf_addf(&buf, "%s-%s.rev", midx_name, hash_to_hex_algop(midx_hash,
659-
ctx->repo->hash_algo));
659+
if (ctx->incremental)
660+
get_split_midx_filename_ext(ctx->repo->hash_algo, &buf,
661+
object_dir, midx_hash,
662+
MIDX_EXT_REV);
663+
else
664+
get_midx_filename_ext(ctx->repo->hash_algo, &buf, object_dir,
665+
midx_hash, MIDX_EXT_REV);
660666

661667
tmp_file = write_rev_file_order(ctx->repo->hash_algo, NULL, ctx->pack_order,
662668
ctx->entries_nr, midx_hash, WRITE_REV);
@@ -829,22 +835,29 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
829835
return cb.commits;
830836
}
831837

832-
static int write_midx_bitmap(struct repository *r, const char *midx_name,
838+
static int write_midx_bitmap(struct write_midx_context *ctx,
839+
const char *object_dir,
833840
const unsigned char *midx_hash,
834841
struct packing_data *pdata,
835842
struct commit **commits,
836843
uint32_t commits_nr,
837-
uint32_t *pack_order,
838844
unsigned flags)
839845
{
840846
int ret, i;
841847
uint16_t options = 0;
842848
struct bitmap_writer writer;
843849
struct pack_idx_entry **index;
844-
char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name,
845-
hash_to_hex_algop(midx_hash, r->hash_algo));
850+
struct strbuf bitmap_name = STRBUF_INIT;
851+
852+
trace2_region_enter("midx", "write_midx_bitmap", ctx->repo);
846853

847-
trace2_region_enter("midx", "write_midx_bitmap", r);
854+
if (ctx->incremental)
855+
get_split_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name,
856+
object_dir, midx_hash,
857+
MIDX_EXT_BITMAP);
858+
else
859+
get_midx_filename_ext(ctx->repo->hash_algo, &bitmap_name,
860+
object_dir, midx_hash, MIDX_EXT_BITMAP);
848861

849862
if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
850863
options |= BITMAP_OPT_HASH_CACHE;
@@ -861,7 +874,8 @@ static int write_midx_bitmap(struct repository *r, const char *midx_name,
861874
for (i = 0; i < pdata->nr_objects; i++)
862875
index[i] = &pdata->objects[i].idx;
863876

864-
bitmap_writer_init(&writer, r, pdata);
877+
bitmap_writer_init(&writer, ctx->repo, pdata,
878+
ctx->incremental ? ctx->base_midx : NULL);
865879
bitmap_writer_show_progress(&writer, flags & MIDX_PROGRESS);
866880
bitmap_writer_build_type_index(&writer, index);
867881

@@ -879,22 +893,22 @@ static int write_midx_bitmap(struct repository *r, const char *midx_name,
879893
* bitmap_writer_finish().
880894
*/
881895
for (i = 0; i < pdata->nr_objects; i++)
882-
index[pack_order[i]] = &pdata->objects[i].idx;
896+
index[ctx->pack_order[i]] = &pdata->objects[i].idx;
883897

884898
bitmap_writer_select_commits(&writer, commits, commits_nr);
885899
ret = bitmap_writer_build(&writer);
886900
if (ret < 0)
887901
goto cleanup;
888902

889903
bitmap_writer_set_checksum(&writer, midx_hash);
890-
bitmap_writer_finish(&writer, index, bitmap_name, options);
904+
bitmap_writer_finish(&writer, index, bitmap_name.buf, options);
891905

892906
cleanup:
893907
free(index);
894-
free(bitmap_name);
908+
strbuf_release(&bitmap_name);
895909
bitmap_writer_free(&writer);
896910

897-
trace2_region_leave("midx", "write_midx_bitmap", r);
911+
trace2_region_leave("midx", "write_midx_bitmap", ctx->repo);
898912

899913
return ret;
900914
}
@@ -1077,8 +1091,6 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
10771091
ctx.repo = r;
10781092

10791093
ctx.incremental = !!(flags & MIDX_WRITE_INCREMENTAL);
1080-
if (ctx.incremental && (flags & MIDX_WRITE_BITMAP))
1081-
die(_("cannot write incremental MIDX with bitmap"));
10821094

10831095
if (ctx.incremental)
10841096
strbuf_addf(&midx_name,
@@ -1119,6 +1131,13 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
11191131
if (ctx.incremental) {
11201132
struct multi_pack_index *m = ctx.base_midx;
11211133
while (m) {
1134+
if (flags & MIDX_WRITE_BITMAP && load_midx_revindex(m)) {
1135+
error(_("could not load reverse index for MIDX %s"),
1136+
hash_to_hex_algop(get_midx_checksum(m),
1137+
m->repo->hash_algo));
1138+
result = 1;
1139+
goto cleanup;
1140+
}
11221141
ctx.num_multi_pack_indexes_before++;
11231142
m = m->base_midx;
11241143
}
@@ -1387,7 +1406,7 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
13871406

13881407
if (flags & MIDX_WRITE_REV_INDEX &&
13891408
git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
1390-
write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
1409+
write_midx_reverse_index(&ctx, object_dir, midx_hash);
13911410

13921411
if (flags & MIDX_WRITE_BITMAP) {
13931412
struct packing_data pdata;
@@ -1410,8 +1429,8 @@ static int write_midx_internal(struct repository *r, const char *object_dir,
14101429
FREE_AND_NULL(ctx.entries);
14111430
ctx.entries_nr = 0;
14121431

1413-
if (write_midx_bitmap(r, midx_name.buf, midx_hash, &pdata,
1414-
commits, commits_nr, ctx.pack_order,
1432+
if (write_midx_bitmap(&ctx, object_dir,
1433+
midx_hash, &pdata, commits, commits_nr,
14151434
flags) < 0) {
14161435
error(_("could not write multi-pack bitmap"));
14171436
result = 1;

pack-bitmap-write.c

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include "alloc.h"
2727
#include "refs.h"
2828
#include "strmap.h"
29+
#include "midx.h"
30+
#include "pack-revindex.h"
2931

3032
struct bitmapped_commit {
3133
struct commit *commit;
@@ -43,14 +45,16 @@ static inline int bitmap_writer_nr_selected_commits(struct bitmap_writer *writer
4345
}
4446

4547
void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r,
46-
struct packing_data *pdata)
48+
struct packing_data *pdata,
49+
struct multi_pack_index *midx)
4750
{
4851
memset(writer, 0, sizeof(struct bitmap_writer));
4952
if (writer->bitmaps)
5053
BUG("bitmap writer already initialized");
5154
writer->bitmaps = kh_init_oid_map();
5255
writer->pseudo_merge_commits = kh_init_oid_map();
5356
writer->to_pack = pdata;
57+
writer->midx = midx;
5458

5559
string_list_init_dup(&writer->pseudo_merge_groups);
5660

@@ -113,6 +117,11 @@ void bitmap_writer_build_type_index(struct bitmap_writer *writer,
113117
struct pack_idx_entry **index)
114118
{
115119
uint32_t i;
120+
uint32_t base_objects = 0;
121+
122+
if (writer->midx)
123+
base_objects = writer->midx->num_objects +
124+
writer->midx->num_objects_in_base;
116125

117126
writer->commits = ewah_new();
118127
writer->trees = ewah_new();
@@ -142,19 +151,19 @@ void bitmap_writer_build_type_index(struct bitmap_writer *writer,
142151

143152
switch (real_type) {
144153
case OBJ_COMMIT:
145-
ewah_set(writer->commits, i);
154+
ewah_set(writer->commits, i + base_objects);
146155
break;
147156

148157
case OBJ_TREE:
149-
ewah_set(writer->trees, i);
158+
ewah_set(writer->trees, i + base_objects);
150159
break;
151160

152161
case OBJ_BLOB:
153-
ewah_set(writer->blobs, i);
162+
ewah_set(writer->blobs, i + base_objects);
154163
break;
155164

156165
case OBJ_TAG:
157-
ewah_set(writer->tags, i);
166+
ewah_set(writer->tags, i + base_objects);
158167
break;
159168

160169
default:
@@ -207,19 +216,37 @@ void bitmap_writer_push_commit(struct bitmap_writer *writer,
207216
static uint32_t find_object_pos(struct bitmap_writer *writer,
208217
const struct object_id *oid, int *found)
209218
{
210-
struct object_entry *entry = packlist_find(writer->to_pack, oid);
219+
struct object_entry *entry;
220+
221+
entry = packlist_find(writer->to_pack, oid);
222+
if (entry) {
223+
uint32_t base_objects = 0;
224+
if (writer->midx)
225+
base_objects = writer->midx->num_objects +
226+
writer->midx->num_objects_in_base;
211227

212-
if (!entry) {
213228
if (found)
214-
*found = 0;
215-
warning("Failed to write bitmap index. Packfile doesn't have full closure "
216-
"(object %s is missing)", oid_to_hex(oid));
217-
return 0;
229+
*found = 1;
230+
return oe_in_pack_pos(writer->to_pack, entry) + base_objects;
231+
} else if (writer->midx) {
232+
uint32_t at, pos;
233+
234+
if (!bsearch_midx(oid, writer->midx, &at))
235+
goto missing;
236+
if (midx_to_pack_pos(writer->midx, at, &pos) < 0)
237+
goto missing;
238+
239+
if (found)
240+
*found = 1;
241+
return pos;
218242
}
219243

244+
missing:
220245
if (found)
221-
*found = 1;
222-
return oe_in_pack_pos(writer->to_pack, entry);
246+
*found = 0;
247+
warning("Failed to write bitmap index. Packfile doesn't have full closure "
248+
"(object %s is missing)", oid_to_hex(oid));
249+
return 0;
223250
}
224251

225252
static void compute_xor_offsets(struct bitmap_writer *writer)
@@ -586,7 +613,7 @@ int bitmap_writer_build(struct bitmap_writer *writer)
586613
struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
587614
struct prio_queue tree_queue = { NULL };
588615
struct bitmap_index *old_bitmap;
589-
uint32_t *mapping;
616+
uint32_t *mapping = NULL;
590617
int closed = 1; /* until proven otherwise */
591618

592619
if (writer->show_progress)
@@ -1021,7 +1048,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
10211048
struct strbuf tmp_file = STRBUF_INIT;
10221049
struct hashfile *f;
10231050
off_t *offsets = NULL;
1024-
uint32_t i;
1051+
uint32_t i, base_objects;
10251052

10261053
struct bitmap_disk_header header;
10271054

@@ -1047,6 +1074,12 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
10471074
if (options & BITMAP_OPT_LOOKUP_TABLE)
10481075
CALLOC_ARRAY(offsets, writer->to_pack->nr_objects);
10491076

1077+
if (writer->midx)
1078+
base_objects = writer->midx->num_objects +
1079+
writer->midx->num_objects_in_base;
1080+
else
1081+
base_objects = 0;
1082+
10501083
for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) {
10511084
struct bitmapped_commit *stored = &writer->selected[i];
10521085
int commit_pos = oid_pos(&stored->commit->object.oid, index,
@@ -1055,7 +1088,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
10551088

10561089
if (commit_pos < 0)
10571090
BUG(_("trying to write commit not in index"));
1058-
stored->commit_pos = commit_pos;
1091+
stored->commit_pos = commit_pos + base_objects;
10591092
}
10601093

10611094
write_selected_commits_v1(writer, f, offsets);

pack-bitmap.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ struct bitmap_writer {
111111

112112
kh_oid_map_t *bitmaps;
113113
struct packing_data *to_pack;
114+
struct multi_pack_index *midx; /* if appending to a MIDX chain */
114115

115116
struct bitmapped_commit *selected;
116117
unsigned int selected_nr, selected_alloc;
@@ -125,7 +126,8 @@ struct bitmap_writer {
125126
};
126127

127128
void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r,
128-
struct packing_data *pdata);
129+
struct packing_data *pdata,
130+
struct multi_pack_index *midx);
129131
void bitmap_writer_show_progress(struct bitmap_writer *writer, int show);
130132
void bitmap_writer_set_checksum(struct bitmap_writer *writer,
131133
const unsigned char *sha1);

0 commit comments

Comments
 (0)