Skip to content

Commit acbec18

Browse files
committed
Merge branch 'ds/midx-with-less-memory'
The codepath to write multi-pack index has been taught to release a large chunk of memory that holds an array of objects in the packs, as soon as it is done with the array, to reduce memory consumption. * ds/midx-with-less-memory: write_midx_bitmap(): drop unused refs_snapshot parameter midx: reduce memory pressure while writing bitmaps midx: extract bitmap write setup pack-bitmap-write: use const for hashes
2 parents 350dc9f + 51d1b69 commit acbec18

File tree

3 files changed

+48
-28
lines changed

3 files changed

+48
-28
lines changed

midx.c

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,40 +1053,34 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr
10531053
return cb.commits;
10541054
}
10551055

1056-
static int write_midx_bitmap(char *midx_name, unsigned char *midx_hash,
1057-
struct write_midx_context *ctx,
1058-
const char *refs_snapshot,
1056+
static int write_midx_bitmap(const char *midx_name,
1057+
const unsigned char *midx_hash,
1058+
struct packing_data *pdata,
1059+
struct commit **commits,
1060+
uint32_t commits_nr,
1061+
uint32_t *pack_order,
10591062
unsigned flags)
10601063
{
1061-
struct packing_data pdata;
1062-
struct pack_idx_entry **index;
1063-
struct commit **commits = NULL;
1064-
uint32_t i, commits_nr;
1064+
int ret, i;
10651065
uint16_t options = 0;
1066-
char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name, hash_to_hex(midx_hash));
1067-
int ret;
1068-
1069-
if (!ctx->entries_nr)
1070-
BUG("cannot write a bitmap without any objects");
1066+
struct pack_idx_entry **index;
1067+
char *bitmap_name = xstrfmt("%s-%s.bitmap", midx_name,
1068+
hash_to_hex(midx_hash));
10711069

10721070
if (flags & MIDX_WRITE_BITMAP_HASH_CACHE)
10731071
options |= BITMAP_OPT_HASH_CACHE;
10741072

1075-
prepare_midx_packing_data(&pdata, ctx);
1076-
1077-
commits = find_commits_for_midx_bitmap(&commits_nr, refs_snapshot, ctx);
1078-
10791073
/*
10801074
* Build the MIDX-order index based on pdata.objects (which is already
10811075
* in MIDX order; c.f., 'midx_pack_order_cmp()' for the definition of
10821076
* this order).
10831077
*/
1084-
ALLOC_ARRAY(index, pdata.nr_objects);
1085-
for (i = 0; i < pdata.nr_objects; i++)
1086-
index[i] = &pdata.objects[i].idx;
1078+
ALLOC_ARRAY(index, pdata->nr_objects);
1079+
for (i = 0; i < pdata->nr_objects; i++)
1080+
index[i] = &pdata->objects[i].idx;
10871081

10881082
bitmap_writer_show_progress(flags & MIDX_PROGRESS);
1089-
bitmap_writer_build_type_index(&pdata, index, pdata.nr_objects);
1083+
bitmap_writer_build_type_index(pdata, index, pdata->nr_objects);
10901084

10911085
/*
10921086
* bitmap_writer_finish expects objects in lex order, but pack_order
@@ -1101,16 +1095,16 @@ static int write_midx_bitmap(char *midx_name, unsigned char *midx_hash,
11011095
* happens between bitmap_writer_build_type_index() and
11021096
* bitmap_writer_finish().
11031097
*/
1104-
for (i = 0; i < pdata.nr_objects; i++)
1105-
index[ctx->pack_order[i]] = &pdata.objects[i].idx;
1098+
for (i = 0; i < pdata->nr_objects; i++)
1099+
index[pack_order[i]] = &pdata->objects[i].idx;
11061100

11071101
bitmap_writer_select_commits(commits, commits_nr, -1);
1108-
ret = bitmap_writer_build(&pdata);
1102+
ret = bitmap_writer_build(pdata);
11091103
if (ret < 0)
11101104
goto cleanup;
11111105

11121106
bitmap_writer_set_checksum(midx_hash);
1113-
bitmap_writer_finish(index, pdata.nr_objects, bitmap_name, options);
1107+
bitmap_writer_finish(index, pdata->nr_objects, bitmap_name, options);
11141108

11151109
cleanup:
11161110
free(index);
@@ -1443,14 +1437,40 @@ static int write_midx_internal(const char *object_dir,
14431437
if (flags & MIDX_WRITE_REV_INDEX &&
14441438
git_env_bool("GIT_TEST_MIDX_WRITE_REV", 0))
14451439
write_midx_reverse_index(midx_name.buf, midx_hash, &ctx);
1440+
14461441
if (flags & MIDX_WRITE_BITMAP) {
1447-
if (write_midx_bitmap(midx_name.buf, midx_hash, &ctx,
1448-
refs_snapshot, flags) < 0) {
1442+
struct packing_data pdata;
1443+
struct commit **commits;
1444+
uint32_t commits_nr;
1445+
1446+
if (!ctx.entries_nr)
1447+
BUG("cannot write a bitmap without any objects");
1448+
1449+
prepare_midx_packing_data(&pdata, &ctx);
1450+
1451+
commits = find_commits_for_midx_bitmap(&commits_nr, refs_snapshot, &ctx);
1452+
1453+
/*
1454+
* The previous steps translated the information from
1455+
* 'entries' into information suitable for constructing
1456+
* bitmaps. We no longer need that array, so clear it to
1457+
* reduce memory pressure.
1458+
*/
1459+
FREE_AND_NULL(ctx.entries);
1460+
ctx.entries_nr = 0;
1461+
1462+
if (write_midx_bitmap(midx_name.buf, midx_hash, &pdata,
1463+
commits, commits_nr, ctx.pack_order,
1464+
flags) < 0) {
14491465
error(_("could not write multi-pack bitmap"));
14501466
result = 1;
14511467
goto cleanup;
14521468
}
14531469
}
1470+
/*
1471+
* NOTE: Do not use ctx.entries beyond this point, since it might
1472+
* have been freed in the previous if block.
1473+
*/
14541474

14551475
if (ctx.m)
14561476
close_object_store(the_repository->objects);

pack-bitmap-write.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ static void write_hash_cache(struct hashfile *f,
683683
}
684684
}
685685

686-
void bitmap_writer_set_checksum(unsigned char *sha1)
686+
void bitmap_writer_set_checksum(const unsigned char *sha1)
687687
{
688688
hashcpy(writer.pack_checksum, sha1);
689689
}

pack-bitmap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ int bitmap_has_oid_in_uninteresting(struct bitmap_index *, const struct object_i
7575
off_t get_disk_usage_from_bitmap(struct bitmap_index *, struct rev_info *);
7676

7777
void bitmap_writer_show_progress(int show);
78-
void bitmap_writer_set_checksum(unsigned char *sha1);
78+
void bitmap_writer_set_checksum(const unsigned char *sha1);
7979
void bitmap_writer_build_type_index(struct packing_data *to_pack,
8080
struct pack_idx_entry **index,
8181
uint32_t index_nr);

0 commit comments

Comments
 (0)