Skip to content

Commit eac5837

Browse files
committed
Merge branch 'tb/prepare-midx-pack-cleanup' into jch
Improvement on Multi-pack-index API. * tb/prepare-midx-pack-cleanup: midx: return a `packed_git` pointer from `prepare_midx_pack()` midx-write.c: extract inner loop from fill_packs_from_midx() midx-write.c: guard against incremental MIDXs in want_included_pack() midx: access pack names through `nth_midxed_pack_name()`
2 parents 75d72b5 + 00fd49d commit eac5837

File tree

5 files changed

+119
-95
lines changed

5 files changed

+119
-95
lines changed

midx-write.c

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -920,44 +920,52 @@ static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
920920
return get_multi_pack_index(source);
921921
}
922922

923+
static int fill_packs_from_midx_1(struct write_midx_context *ctx,
924+
struct multi_pack_index *m,
925+
int prepare_packs)
926+
{
927+
for (uint32_t i = 0; i < m->num_packs; i++) {
928+
struct packed_git *p = NULL;
929+
930+
ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
931+
if (prepare_packs) {
932+
p = prepare_midx_pack(ctx->repo, m,
933+
m->num_packs_in_base + i);
934+
if (!p) {
935+
error(_("could not load pack"));
936+
return 1;
937+
}
938+
939+
if (open_pack_index(p))
940+
die(_("could not open index for %s"),
941+
p->pack_name);
942+
}
943+
944+
fill_pack_info(&ctx->info[ctx->nr++], p, m->pack_names[i],
945+
m->num_packs_in_base + i);
946+
}
947+
948+
return 0;
949+
}
950+
923951
static int fill_packs_from_midx(struct write_midx_context *ctx,
924952
const char *preferred_pack_name, uint32_t flags)
925953
{
926954
struct multi_pack_index *m;
955+
int prepare_packs;
927956

928-
for (m = ctx->m; m; m = m->base_midx) {
929-
uint32_t i;
930-
931-
for (i = 0; i < m->num_packs; i++) {
932-
ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
933-
934-
/*
935-
* If generating a reverse index, need to have
936-
* packed_git's loaded to compare their
937-
* mtimes and object count.
938-
*
939-
* If a preferred pack is specified, need to
940-
* have packed_git's loaded to ensure the chosen
941-
* preferred pack has a non-zero object count.
942-
*/
943-
if (flags & MIDX_WRITE_REV_INDEX ||
944-
preferred_pack_name) {
945-
if (prepare_midx_pack(ctx->repo, m,
946-
m->num_packs_in_base + i)) {
947-
error(_("could not load pack"));
948-
return 1;
949-
}
950-
951-
if (open_pack_index(m->packs[i]))
952-
die(_("could not open index for %s"),
953-
m->packs[i]->pack_name);
954-
}
957+
/*
958+
* If generating a reverse index, need to have packed_git's
959+
* loaded to compare their mtimes and object count.
960+
*/
961+
prepare_packs = !!(flags & MIDX_WRITE_REV_INDEX || preferred_pack_name);
955962

956-
fill_pack_info(&ctx->info[ctx->nr++], m->packs[i],
957-
m->pack_names[i],
958-
m->num_packs_in_base + i);
959-
}
963+
for (m = ctx->m; m; m = m->base_midx) {
964+
int ret = fill_packs_from_midx_1(ctx, m, prepare_packs);
965+
if (ret)
966+
return ret;
960967
}
968+
961969
return 0;
962970
}
963971

@@ -1560,20 +1568,19 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
15601568
_("Finding and deleting unreferenced packfiles"),
15611569
m->num_packs);
15621570
for (i = 0; i < m->num_packs; i++) {
1571+
struct packed_git *p;
15631572
char *pack_name;
15641573
display_progress(progress, i + 1);
15651574

15661575
if (count[i])
15671576
continue;
15681577

1569-
if (prepare_midx_pack(r, m, i))
1570-
continue;
1571-
1572-
if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
1578+
p = prepare_midx_pack(r, m, i);
1579+
if (!p || p->pack_keep || p->is_cruft)
15731580
continue;
15741581

1575-
pack_name = xstrdup(m->packs[i]->pack_name);
1576-
close_pack(m->packs[i]);
1582+
pack_name = xstrdup(p->pack_name);
1583+
close_pack(p);
15771584

15781585
string_list_insert(&packs_to_drop, m->pack_names[i]);
15791586
unlink_pack_path(pack_name, 0);
@@ -1618,9 +1625,12 @@ static int want_included_pack(struct repository *r,
16181625
uint32_t pack_int_id)
16191626
{
16201627
struct packed_git *p;
1621-
if (prepare_midx_pack(r, m, pack_int_id))
1628+
1629+
ASSERT(m && !m->base_midx);
1630+
1631+
p = prepare_midx_pack(r, m, pack_int_id);
1632+
if (!p)
16221633
return 0;
1623-
p = m->packs[pack_int_id];
16241634
if (!pack_kept_objects && p->pack_keep)
16251635
return 0;
16261636
if (p->is_cruft)
@@ -1637,6 +1647,8 @@ static void fill_included_packs_all(struct repository *r,
16371647
uint32_t i;
16381648
int pack_kept_objects = 0;
16391649

1650+
ASSERT(m && !m->base_midx);
1651+
16401652
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
16411653

16421654
for (i = 0; i < m->num_packs; i++) {
@@ -1657,17 +1669,18 @@ static void fill_included_packs_batch(struct repository *r,
16571669
struct repack_info *pack_info;
16581670
int pack_kept_objects = 0;
16591671

1672+
ASSERT(m && !m->base_midx);
1673+
16601674
CALLOC_ARRAY(pack_info, m->num_packs);
16611675

16621676
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
16631677

16641678
for (i = 0; i < m->num_packs; i++) {
1665-
pack_info[i].pack_int_id = i;
1666-
1667-
if (prepare_midx_pack(r, m, i))
1668-
continue;
1679+
struct packed_git *p = prepare_midx_pack(r, m, i);
16691680

1670-
pack_info[i].mtime = m->packs[i]->mtime;
1681+
pack_info[i].pack_int_id = i;
1682+
if (p)
1683+
pack_info[i].mtime = p->mtime;
16711684
}
16721685

16731686
for (i = 0; i < m->num_objects; i++) {

midx.c

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -450,50 +450,48 @@ static uint32_t midx_for_pack(struct multi_pack_index **_m,
450450
return pack_int_id - m->num_packs_in_base;
451451
}
452452

453-
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m,
454-
uint32_t pack_int_id)
453+
struct packed_git *prepare_midx_pack(struct repository *r,
454+
struct multi_pack_index *m,
455+
uint32_t pack_int_id)
455456
{
456-
struct strbuf pack_name = STRBUF_INIT;
457-
struct strbuf key = STRBUF_INIT;
458-
struct packed_git *p;
459-
460-
pack_int_id = midx_for_pack(&m, pack_int_id);
461-
462-
if (m->packs[pack_int_id] == MIDX_PACK_ERROR)
463-
return 1;
464-
if (m->packs[pack_int_id])
465-
return 0;
466-
467-
strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir,
468-
m->pack_names[pack_int_id]);
469-
470-
/* pack_map holds the ".pack" name, but we have the .idx */
471-
strbuf_addbuf(&key, &pack_name);
472-
strbuf_strip_suffix(&key, ".idx");
473-
strbuf_addstr(&key, ".pack");
474-
p = hashmap_get_entry_from_hash(&r->objects->pack_map,
475-
strhash(key.buf), key.buf,
476-
struct packed_git, packmap_ent);
477-
if (!p) {
478-
p = add_packed_git(r, pack_name.buf, pack_name.len, m->local);
479-
if (p) {
480-
install_packed_git(r, p);
481-
list_add_tail(&p->mru, &r->objects->packed_git_mru);
457+
uint32_t pack_pos = midx_for_pack(&m, pack_int_id);
458+
459+
if (!m->packs[pack_pos]) {
460+
struct strbuf pack_name = STRBUF_INIT;
461+
struct strbuf key = STRBUF_INIT;
462+
struct packed_git *p;
463+
464+
strbuf_addf(&pack_name, "%s/pack/%s", m->object_dir,
465+
m->pack_names[pack_pos]);
466+
467+
/* pack_map holds the ".pack" name, but we have the .idx */
468+
strbuf_addbuf(&key, &pack_name);
469+
strbuf_strip_suffix(&key, ".idx");
470+
strbuf_addstr(&key, ".pack");
471+
p = hashmap_get_entry_from_hash(&r->objects->pack_map,
472+
strhash(key.buf), key.buf,
473+
struct packed_git, packmap_ent);
474+
if (!p) {
475+
p = add_packed_git(r, pack_name.buf, pack_name.len,
476+
m->local);
477+
if (p) {
478+
install_packed_git(r, p);
479+
list_add_tail(&p->mru,
480+
&r->objects->packed_git_mru);
481+
}
482482
}
483-
}
484483

485-
strbuf_release(&pack_name);
486-
strbuf_release(&key);
484+
strbuf_release(&pack_name);
485+
strbuf_release(&key);
487486

488-
if (!p) {
489-
m->packs[pack_int_id] = MIDX_PACK_ERROR;
490-
return 1;
487+
m->packs[pack_pos] = p ? p : MIDX_PACK_ERROR;
488+
if (p)
489+
p->multi_pack_index = 1;
491490
}
492491

493-
p->multi_pack_index = 1;
494-
m->packs[pack_int_id] = p;
495-
496-
return 0;
492+
if (m->packs[pack_pos] == MIDX_PACK_ERROR)
493+
return NULL;
494+
return m->packs[pack_pos];
497495
}
498496

499497
struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
@@ -505,6 +503,13 @@ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
505503
return m->packs[local_pack_int_id];
506504
}
507505

506+
const char *nth_midxed_pack_name(struct multi_pack_index *m,
507+
uint32_t pack_int_id)
508+
{
509+
uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
510+
return m->pack_names[local_pack_int_id];
511+
}
512+
508513
#define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t))
509514

510515
int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
@@ -515,10 +520,11 @@ int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
515520
if (!m->chunk_bitmapped_packs)
516521
return error(_("MIDX does not contain the BTMP chunk"));
517522

518-
if (prepare_midx_pack(r, m, pack_int_id))
519-
return error(_("could not load bitmapped pack %"PRIu32), pack_int_id);
523+
bp->p = prepare_midx_pack(r, m, pack_int_id);
524+
if (!bp->p)
525+
return error(_("could not load bitmapped pack %"PRIu32),
526+
pack_int_id);
520527

521-
bp->p = m->packs[local_pack_int_id];
522528
bp->bitmap_pos = get_be32((char *)m->chunk_bitmapped_packs +
523529
MIDX_CHUNK_BITMAPPED_PACKS_WIDTH * local_pack_int_id);
524530
bp->bitmap_nr = get_be32((char *)m->chunk_bitmapped_packs +
@@ -615,9 +621,9 @@ int fill_midx_entry(struct repository *r,
615621
midx_for_object(&m, pos);
616622
pack_int_id = nth_midxed_pack_int_id(m, pos);
617623

618-
if (prepare_midx_pack(r, m, pack_int_id))
624+
p = prepare_midx_pack(r, m, pack_int_id);
625+
if (!p)
619626
return 0;
620-
p = m->packs[pack_int_id - m->num_packs_in_base];
621627

622628
/*
623629
* We are about to tell the caller where they can locate the
@@ -911,7 +917,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
911917
_("Looking for referenced packfiles"),
912918
m->num_packs + m->num_packs_in_base);
913919
for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
914-
if (prepare_midx_pack(r, m, i))
920+
if (!prepare_midx_pack(r, m, i))
915921
midx_report("failed to load pack in position %d", i);
916922

917923
display_progress(progress, i + 1);

midx.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,13 @@ void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo,
103103
struct multi_pack_index *load_multi_pack_index(struct repository *r,
104104
const char *object_dir,
105105
int local);
106-
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
106+
struct packed_git *prepare_midx_pack(struct repository *r,
107+
struct multi_pack_index *m,
108+
uint32_t pack_int_id);
107109
struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
108110
uint32_t pack_int_id);
111+
const char *nth_midxed_pack_name(struct multi_pack_index *m,
112+
uint32_t pack_int_id);
109113
int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
110114
struct bitmapped_pack *bp, uint32_t pack_int_id);
111115
int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m,

pack-bitmap.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,9 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
493493
}
494494

495495
for (i = 0; i < bitmap_git->midx->num_packs + bitmap_git->midx->num_packs_in_base; i++) {
496-
if (prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) {
496+
if (!prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) {
497497
warning(_("could not open pack %s"),
498-
bitmap_git->midx->pack_names[i]);
498+
nth_midxed_pack_name(bitmap_git->midx, i));
499499
goto cleanup;
500500
}
501501
}
@@ -2468,7 +2468,7 @@ void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
24682468
struct bitmapped_pack pack;
24692469
if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) {
24702470
warning(_("unable to load pack: '%s', disabling pack-reuse"),
2471-
bitmap_git->midx->pack_names[i]);
2471+
nth_midxed_pack_name(bitmap_git->midx, i));
24722472
free(packs);
24732473
return;
24742474
}

t/helper/test-read-midx.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ static int read_midx_file(const char *object_dir, const char *checksum,
5353
printf("\nnum_objects: %d\n", m->num_objects);
5454

5555
printf("packs:\n");
56-
for (i = 0; i < m->num_packs; i++)
57-
printf("%s\n", m->pack_names[i]);
56+
for (i = m->num_packs_in_base; i < m->num_packs + m->num_packs_in_base;
57+
i++)
58+
printf("%s\n", nth_midxed_pack_name(m, i));
5859

5960
printf("object-dir: %s\n", m->object_dir);
6061

@@ -108,7 +109,7 @@ static int read_midx_preferred_pack(const char *object_dir)
108109
return 1;
109110
}
110111

111-
printf("%s\n", midx->pack_names[preferred_pack]);
112+
printf("%s\n", nth_midxed_pack_name(midx, preferred_pack));
112113
close_midx(midx);
113114
return 0;
114115
}

0 commit comments

Comments
 (0)