Skip to content

Commit ab34120

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 04ad566 + 00fd49d commit ab34120

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
@@ -938,44 +938,52 @@ static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
938938
return result;
939939
}
940940

941+
static int fill_packs_from_midx_1(struct write_midx_context *ctx,
942+
struct multi_pack_index *m,
943+
int prepare_packs)
944+
{
945+
for (uint32_t i = 0; i < m->num_packs; i++) {
946+
struct packed_git *p = NULL;
947+
948+
ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
949+
if (prepare_packs) {
950+
p = prepare_midx_pack(ctx->repo, m,
951+
m->num_packs_in_base + i);
952+
if (!p) {
953+
error(_("could not load pack"));
954+
return 1;
955+
}
956+
957+
if (open_pack_index(p))
958+
die(_("could not open index for %s"),
959+
p->pack_name);
960+
}
961+
962+
fill_pack_info(&ctx->info[ctx->nr++], p, m->pack_names[i],
963+
m->num_packs_in_base + i);
964+
}
965+
966+
return 0;
967+
}
968+
941969
static int fill_packs_from_midx(struct write_midx_context *ctx,
942970
const char *preferred_pack_name, uint32_t flags)
943971
{
944972
struct multi_pack_index *m;
973+
int prepare_packs;
945974

946-
for (m = ctx->m; m; m = m->base_midx) {
947-
uint32_t i;
948-
949-
for (i = 0; i < m->num_packs; i++) {
950-
ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
951-
952-
/*
953-
* If generating a reverse index, need to have
954-
* packed_git's loaded to compare their
955-
* mtimes and object count.
956-
*
957-
* If a preferred pack is specified, need to
958-
* have packed_git's loaded to ensure the chosen
959-
* preferred pack has a non-zero object count.
960-
*/
961-
if (flags & MIDX_WRITE_REV_INDEX ||
962-
preferred_pack_name) {
963-
if (prepare_midx_pack(ctx->repo, m,
964-
m->num_packs_in_base + i)) {
965-
error(_("could not load pack"));
966-
return 1;
967-
}
968-
969-
if (open_pack_index(m->packs[i]))
970-
die(_("could not open index for %s"),
971-
m->packs[i]->pack_name);
972-
}
975+
/*
976+
* If generating a reverse index, need to have packed_git's
977+
* loaded to compare their mtimes and object count.
978+
*/
979+
prepare_packs = !!(flags & MIDX_WRITE_REV_INDEX || preferred_pack_name);
973980

974-
fill_pack_info(&ctx->info[ctx->nr++], m->packs[i],
975-
m->pack_names[i],
976-
m->num_packs_in_base + i);
977-
}
981+
for (m = ctx->m; m; m = m->base_midx) {
982+
int ret = fill_packs_from_midx_1(ctx, m, prepare_packs);
983+
if (ret)
984+
return ret;
978985
}
986+
979987
return 0;
980988
}
981989

@@ -1578,20 +1586,19 @@ int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
15781586
_("Finding and deleting unreferenced packfiles"),
15791587
m->num_packs);
15801588
for (i = 0; i < m->num_packs; i++) {
1589+
struct packed_git *p;
15811590
char *pack_name;
15821591
display_progress(progress, i + 1);
15831592

15841593
if (count[i])
15851594
continue;
15861595

1587-
if (prepare_midx_pack(r, m, i))
1588-
continue;
1589-
1590-
if (m->packs[i]->pack_keep || m->packs[i]->is_cruft)
1596+
p = prepare_midx_pack(r, m, i);
1597+
if (!p || p->pack_keep || p->is_cruft)
15911598
continue;
15921599

1593-
pack_name = xstrdup(m->packs[i]->pack_name);
1594-
close_pack(m->packs[i]);
1600+
pack_name = xstrdup(p->pack_name);
1601+
close_pack(p);
15951602

15961603
string_list_insert(&packs_to_drop, m->pack_names[i]);
15971604
unlink_pack_path(pack_name, 0);
@@ -1636,9 +1643,12 @@ static int want_included_pack(struct repository *r,
16361643
uint32_t pack_int_id)
16371644
{
16381645
struct packed_git *p;
1639-
if (prepare_midx_pack(r, m, pack_int_id))
1646+
1647+
ASSERT(m && !m->base_midx);
1648+
1649+
p = prepare_midx_pack(r, m, pack_int_id);
1650+
if (!p)
16401651
return 0;
1641-
p = m->packs[pack_int_id];
16421652
if (!pack_kept_objects && p->pack_keep)
16431653
return 0;
16441654
if (p->is_cruft)
@@ -1655,6 +1665,8 @@ static void fill_included_packs_all(struct repository *r,
16551665
uint32_t i;
16561666
int pack_kept_objects = 0;
16571667

1668+
ASSERT(m && !m->base_midx);
1669+
16581670
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
16591671

16601672
for (i = 0; i < m->num_packs; i++) {
@@ -1675,17 +1687,18 @@ static void fill_included_packs_batch(struct repository *r,
16751687
struct repack_info *pack_info;
16761688
int pack_kept_objects = 0;
16771689

1690+
ASSERT(m && !m->base_midx);
1691+
16781692
CALLOC_ARRAY(pack_info, m->num_packs);
16791693

16801694
repo_config_get_bool(r, "repack.packkeptobjects", &pack_kept_objects);
16811695

16821696
for (i = 0; i < m->num_packs; i++) {
1683-
pack_info[i].pack_int_id = i;
1684-
1685-
if (prepare_midx_pack(r, m, i))
1686-
continue;
1697+
struct packed_git *p = prepare_midx_pack(r, m, i);
16871698

1688-
pack_info[i].mtime = m->packs[i]->mtime;
1699+
pack_info[i].pack_int_id = i;
1700+
if (p)
1701+
pack_info[i].mtime = p->mtime;
16891702
}
16901703

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

midx.c

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

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

486-
strbuf_release(&pack_name);
487-
strbuf_release(&key);
485+
strbuf_release(&pack_name);
486+
strbuf_release(&key);
488487

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

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

500498
struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
@@ -506,6 +504,13 @@ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
506504
return m->packs[local_pack_int_id];
507505
}
508506

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

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

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

522-
bp->p = m->packs[local_pack_int_id];
523529
bp->bitmap_pos = get_be32((char *)m->chunk_bitmapped_packs +
524530
MIDX_CHUNK_BITMAPPED_PACKS_WIDTH * local_pack_int_id);
525531
bp->bitmap_nr = get_be32((char *)m->chunk_bitmapped_packs +
@@ -616,9 +622,9 @@ int fill_midx_entry(struct repository *r,
616622
midx_for_object(&m, pos);
617623
pack_int_id = nth_midxed_pack_int_id(m, pos);
618624

619-
if (prepare_midx_pack(r, m, pack_int_id))
625+
p = prepare_midx_pack(r, m, pack_int_id);
626+
if (!p)
620627
return 0;
621-
p = m->packs[pack_int_id - m->num_packs_in_base];
622628

623629
/*
624630
* We are about to tell the caller where they can locate the
@@ -919,7 +925,7 @@ int verify_midx_file(struct repository *r, const char *object_dir, unsigned flag
919925
_("Looking for referenced packfiles"),
920926
m->num_packs + m->num_packs_in_base);
921927
for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
922-
if (prepare_midx_pack(r, m, i))
928+
if (!prepare_midx_pack(r, m, i))
923929
midx_report("failed to load pack in position %d", i);
924930

925931
display_progress(progress, i + 1);

midx.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,13 @@ void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo,
104104
struct multi_pack_index *load_multi_pack_index(struct repository *r,
105105
const char *object_dir,
106106
int local);
107-
int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
107+
struct packed_git *prepare_midx_pack(struct repository *r,
108+
struct multi_pack_index *m,
109+
uint32_t pack_int_id);
108110
struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
109111
uint32_t pack_int_id);
112+
const char *nth_midxed_pack_name(struct multi_pack_index *m,
113+
uint32_t pack_int_id);
110114
int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
111115
struct bitmapped_pack *bp, uint32_t pack_int_id);
112116
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
}
@@ -2466,7 +2466,7 @@ void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
24662466
struct bitmapped_pack pack;
24672467
if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) {
24682468
warning(_("unable to load pack: '%s', disabling pack-reuse"),
2469-
bitmap_git->midx->pack_names[i]);
2469+
nth_midxed_pack_name(bitmap_git->midx, i));
24702470
free(packs);
24712471
return;
24722472
}

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)