From: Taylor Blau <me@ttaylorr.com>
To: git@vger.kernel.org
Cc: Patrick Steinhardt <ps@pks.im>, Jeff King <peff@peff.net>,
Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 0/4] midx: improve prepare_midx_pack() ergonomics
Date: Wed, 28 May 2025 18:58:57 -0400 [thread overview]
Message-ID: <cover.1748473122.git.me@ttaylorr.com> (raw)
In-Reply-To: <cover.1748198489.git.me@ttaylorr.com>
This series has been updated to be based on v3 of
ps/midx-negative-packfile-cache, which is 1f34bf3e08 (midx: stop
repeatedly looking up nonexistent packfiles, 2025-05-28) at the time of
writing.
There are a couple of minor changes from last time, including:
- using the new MIDX_PACK_ERROR macro instead of casting '-1' to a void
pointer
- converting some direct m->pack_names lookups (outside of midx.c and
midx-write.c with one exception) to use a similar pattern to access
the nth pack name
As usual, a range-diff against v1 is below for convenience.
Thanks again for your review!
Taylor Blau (4):
midx: access pack names through `nth_midxed_pack_name()`
midx-write.c: guard against incremental MIDXs in want_included_pack()
midx-write.c: extract inner loop from fill_packs_from_midx()
midx: return a `packed_git` pointer from `prepare_midx_pack()`
midx-write.c | 101 +++++++++++++++++++++-----------------
midx.c | 88 +++++++++++++++++----------------
midx.h | 6 ++-
pack-bitmap.c | 6 +--
t/helper/test-read-midx.c | 7 +--
5 files changed, 116 insertions(+), 92 deletions(-)
Range-diff against v1:
1: a7082dc7f0 < -: ---------- packfile: explain ordering of how we look up auxiliary pack files
2: 73fe0882ee < -: ---------- midx: stop repeatedly looking up nonexistent packfiles
3: ad7295b11b < -: ---------- pack-bitmap.c: fix broken warning() when missing MIDX'd pack
5: 5d97b706e1 ! 1: d3508d3cfb midx-write.c: simplify fill_packs_from_midx()
@@ Metadata
Author: Taylor Blau <me@ttaylorr.com>
## Commit message ##
- midx-write.c: simplify fill_packs_from_midx()
+ midx: access pack names through `nth_midxed_pack_name()`
- When enumerating packs within fill_packs_from_midx(), we open the pack's
- index iff we are either writing a reverse index, have a preferred pack
- (by name) or both.
+ Accessing a MIDX's 'pack_names' array is somewhat error-prone when
+ dealing with incremental MIDX chains, where the (global) pack_int_id for
+ some pack may differ from the containing layer's index for that pack.
- Let's simplify this into a single case by setting the
- MIDX_WRITE_REV_INDEX flag bit when we have a preferred_pack_name. This
- is a little bit of a shortcut to reduce the line length in the loop
- below. But it sets us up nicely to extract the inner loop of this
- function out into its own function, where we will no longer have to pass
- the preferred_pack_name.
+ Introduce `nth_midxed_pack_name()` in an effort to reduce a common
+ source of errors by discouraging external callers from accessing a
+ layer's `pack_names` array directly.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
- ## midx-write.c ##
-@@ midx-write.c: static int fill_packs_from_midx(struct write_midx_context *ctx,
- {
- struct multi_pack_index *m;
+ ## midx.c ##
+@@ midx.c: struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
+ return m->packs[local_pack_int_id];
+ }
-+ if (preferred_pack_name) {
-+ /*
-+ * If a preferred pack is specified, need to have
-+ * packed_git's loaded to ensure the chosen preferred
-+ * pack has a non-zero object count.
-+ *
-+ * Trick ourselves into thinking that we're writing a
-+ * reverse index in this case in order to open up the
-+ * pack index file.
-+ */
-+ flags |= MIDX_WRITE_REV_INDEX;
-+ }
++const char *nth_midxed_pack_name(struct multi_pack_index *m,
++ uint32_t pack_int_id)
++{
++ uint32_t local_pack_int_id = midx_for_pack(&m, pack_int_id);
++ return m->pack_names[local_pack_int_id];
++}
+
- for (m = ctx->m; m; m = m->base_midx) {
- uint32_t i;
+ #define MIDX_CHUNK_BITMAPPED_PACKS_WIDTH (2 * sizeof(uint32_t))
-@@ midx-write.c: static int fill_packs_from_midx(struct write_midx_context *ctx,
- * If generating a reverse index, need to have
- * packed_git's loaded to compare their
- * mtimes and object count.
-- *
-- * If a preferred pack is specified, need to
-- * have packed_git's loaded to ensure the chosen
-- * preferred pack has a non-zero object count.
- */
-- if (flags & MIDX_WRITE_REV_INDEX ||
-- preferred_pack_name) {
-+ if (flags & MIDX_WRITE_REV_INDEX) {
- if (prepare_midx_pack(ctx->repo, m,
- m->num_packs_in_base + i)) {
- error(_("could not load pack"));
+ int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
+
+ ## midx.h ##
+@@ midx.h: struct multi_pack_index *load_multi_pack_index(struct repository *r,
+ int prepare_midx_pack(struct repository *r, struct multi_pack_index *m, uint32_t pack_int_id);
+ struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
+ uint32_t pack_int_id);
++const char *nth_midxed_pack_name(struct multi_pack_index *m,
++ uint32_t pack_int_id);
+ int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
+ struct bitmapped_pack *bp, uint32_t pack_int_id);
+ int bsearch_one_midx(const struct object_id *oid, struct multi_pack_index *m,
+
+ ## pack-bitmap.c ##
+@@ pack-bitmap.c: static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
+ for (i = 0; i < bitmap_git->midx->num_packs + bitmap_git->midx->num_packs_in_base; i++) {
+ if (prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) {
+ warning(_("could not open pack %s"),
+- bitmap_git->midx->pack_names[i]);
++ nth_midxed_pack_name(bitmap_git->midx, i));
+ goto cleanup;
+ }
+ }
+@@ pack-bitmap.c: void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
+ struct bitmapped_pack pack;
+ if (nth_bitmapped_pack(r, bitmap_git->midx, &pack, i) < 0) {
+ warning(_("unable to load pack: '%s', disabling pack-reuse"),
+- bitmap_git->midx->pack_names[i]);
++ nth_midxed_pack_name(bitmap_git->midx, i));
+ free(packs);
+ return;
+ }
+
+ ## t/helper/test-read-midx.c ##
+@@ t/helper/test-read-midx.c: static int read_midx_file(const char *object_dir, const char *checksum,
+ printf("\nnum_objects: %d\n", m->num_objects);
+
+ printf("packs:\n");
+- for (i = 0; i < m->num_packs; i++)
+- printf("%s\n", m->pack_names[i]);
++ for (i = m->num_packs_in_base; i < m->num_packs + m->num_packs_in_base;
++ i++)
++ printf("%s\n", nth_midxed_pack_name(m, i));
+
+ printf("object-dir: %s\n", m->object_dir);
+
+@@ t/helper/test-read-midx.c: static int read_midx_preferred_pack(const char *object_dir)
+ return 1;
+ }
+
+- printf("%s\n", midx->pack_names[preferred_pack]);
++ printf("%s\n", nth_midxed_pack_name(midx, preferred_pack));
+ close_midx(midx);
+ return 0;
+ }
4: d2f9645aa1 ! 2: cf3ab81a08 midx-write.c: guard against incremental MIDXs in want_included_pack()
@@ Commit message
if (m->base_midx)
die(_("cannot repack an incremental multi-pack-index"));
- So want_included_pack() is OK becuase it will never encounter a
+ So want_included_pack() is OK because it will never encounter a
situation where it has to chase backwards through the '->base_midx'
pointer. But that is not immediately clear from reading the code, and is
too fragile for my comfort. Make this more clear by adding an ASSERT()
6: a4080c12df ! 3: e54988bfea midx-write.c: extract inner loop from fill_packs_from_midx()
@@ midx-write.c: static struct multi_pack_index *lookup_multi_pack_index(struct rep
+static int fill_packs_from_midx_1(struct write_midx_context *ctx,
+ struct multi_pack_index *m,
-+ uint32_t flags)
++ int prepare_packs)
+{
+ for (uint32_t i = 0; i < m->num_packs; i++) {
-+ ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
-+
+ /*
+ * If generating a reverse index, need to have
+ * packed_git's loaded to compare their
+ * mtimes and object count.
+ */
-+ if (flags & MIDX_WRITE_REV_INDEX) {
++ if (prepare_packs) {
+ if (prepare_midx_pack(ctx->repo, m,
+ m->num_packs_in_base + i)) {
+ error(_("could not load pack"));
@@ midx-write.c: static struct multi_pack_index *lookup_multi_pack_index(struct rep
static int fill_packs_from_midx(struct write_midx_context *ctx,
const char *preferred_pack_name, uint32_t flags)
{
-@@ midx-write.c: static int fill_packs_from_midx(struct write_midx_context *ctx,
- }
+ struct multi_pack_index *m;
++ int prepare_packs;
++
++ /*
++ * If generating a reverse index, need to have packed_git's
++ * loaded to compare their mtimes and object count.
++ */
++ prepare_packs = !!(flags & MIDX_WRITE_REV_INDEX || preferred_pack_name);
for (m = ctx->m; m; m = m->base_midx) {
- uint32_t i;
@@ midx-write.c: static int fill_packs_from_midx(struct write_midx_context *ctx,
- * If generating a reverse index, need to have
- * packed_git's loaded to compare their
- * mtimes and object count.
+- *
+- * If a preferred pack is specified, need to
+- * have packed_git's loaded to ensure the chosen
+- * preferred pack has a non-zero object count.
- */
-- if (flags & MIDX_WRITE_REV_INDEX) {
+- if (flags & MIDX_WRITE_REV_INDEX ||
+- preferred_pack_name) {
- if (prepare_midx_pack(ctx->repo, m,
- m->num_packs_in_base + i)) {
- error(_("could not load pack"));
@@ midx-write.c: static int fill_packs_from_midx(struct write_midx_context *ctx,
- m->pack_names[i],
- m->num_packs_in_base + i);
- }
-+ int ret = fill_packs_from_midx_1(ctx, m, flags);
++ int ret = fill_packs_from_midx_1(ctx, m, prepare_packs);
+ if (ret)
+ return ret;
}
7: 80699bb3ee ! 4: e3e21db673 midx: return a `packed_git` pointer from `prepare_midx_pack()`
@@ Commit message
## midx-write.c ##
@@ midx-write.c: static int fill_packs_from_midx_1(struct write_midx_context *ctx,
- uint32_t flags)
+ int prepare_packs)
{
for (uint32_t i = 0; i < m->num_packs; i++) {
+- /*
+- * If generating a reverse index, need to have
+- * packed_git's loaded to compare their
+- * mtimes and object count.
+- */
+ struct packed_git *p = NULL;
+
- ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
-
- /*
-@@ midx-write.c: static int fill_packs_from_midx_1(struct write_midx_context *ctx,
- * mtimes and object count.
- */
- if (flags & MIDX_WRITE_REV_INDEX) {
++ ALLOC_GROW(ctx->info, ctx->nr + 1, ctx->alloc);
+ if (prepare_packs) {
- if (prepare_midx_pack(ctx->repo, m,
- m->num_packs_in_base + i)) {
+ p = prepare_midx_pack(ctx->repo, m,
@@ midx-write.c: static int fill_packs_from_midx_1(struct write_midx_context *ctx,
}
- fill_pack_info(&ctx->info[ctx->nr++], m->packs[i],
-+ fill_pack_info(&ctx->info[ctx->nr++], p,
- m->pack_names[i],
+- m->pack_names[i],
++ fill_pack_info(&ctx->info[ctx->nr++], p, m->pack_names[i],
m->num_packs_in_base + i);
}
+
@@ midx-write.c: int expire_midx_packs(struct repository *r, const char *object_dir, unsigned fla
_("Finding and deleting unreferenced packfiles"),
m->num_packs);
@@ midx.c: static uint32_t midx_for_pack(struct multi_pack_index **_m,
+ struct strbuf key = STRBUF_INIT;
+ struct packed_git *p;
-- if (m->packs[pack_int_id] == (void *)(intptr_t)-1)
+- if (m->packs[pack_int_id] == MIDX_PACK_ERROR)
- return 1;
- if (m->packs[pack_int_id])
- return 0;
@@ midx.c: static uint32_t midx_for_pack(struct multi_pack_index **_m,
+ strbuf_release(&key);
- if (!p) {
-- m->packs[pack_int_id] = (void *)(intptr_t)-1;
+- m->packs[pack_int_id] = MIDX_PACK_ERROR;
- return 1;
-+ m->packs[pack_pos] = p ? p : (void *)(intptr_t)-1;
++ m->packs[pack_pos] = p ? p : MIDX_PACK_ERROR;
+ if (p)
+ p->multi_pack_index = 1;
}
@@ midx.c: static uint32_t midx_for_pack(struct multi_pack_index **_m,
- m->packs[pack_int_id] = p;
-
- return 0;
-+ if (m->packs[pack_pos] == (void *)(intptr_t)-1)
++ if (m->packs[pack_pos] == MIDX_PACK_ERROR)
+ return NULL;
+ return m->packs[pack_pos];
}
@@ midx.h: void get_split_midx_filename_ext(const struct git_hash_algo *hash_algo,
+ uint32_t pack_int_id);
struct packed_git *nth_midxed_pack(struct multi_pack_index *m,
uint32_t pack_int_id);
- int nth_bitmapped_pack(struct repository *r, struct multi_pack_index *m,
+ const char *nth_midxed_pack_name(struct multi_pack_index *m,
## pack-bitmap.c ##
@@ pack-bitmap.c: static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
@@ pack-bitmap.c: static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
- if (prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) {
+ if (!prepare_midx_pack(bitmap_repo(bitmap_git), bitmap_git->midx, i)) {
warning(_("could not open pack %s"),
- bitmap_git->midx->pack_names[i - bitmap_git->midx->num_packs_in_base]);
+ nth_midxed_pack_name(bitmap_git->midx, i));
goto cleanup;
base-commit: 1f34bf3e082741e053d25b76a0ffe31d9d967594
--
2.49.0.640.ga4de40e6a8
next prev parent reply other threads:[~2025-05-28 22:58 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-16 8:55 [PATCH] packfile: avoid access(3p) calls for missing packs Patrick Steinhardt
2025-05-16 18:34 ` Junio C Hamano
2025-05-19 6:52 ` Jeff King
2025-05-19 15:46 ` Junio C Hamano
2025-05-20 6:45 ` Patrick Steinhardt
2025-05-22 5:28 ` Jeff King
2025-05-23 1:02 ` Taylor Blau
2025-05-23 2:03 ` Jeff King
2025-05-20 9:53 ` [PATCH v2 0/2] " Patrick Steinhardt
2025-05-20 9:53 ` [PATCH v2 1/2] packfile: explain ordering of how we look up auxiliary pack files Patrick Steinhardt
2025-05-23 1:03 ` Taylor Blau
2025-05-20 9:53 ` [PATCH v2 2/2] midx: stop repeatedly looking up nonexistent packfiles Patrick Steinhardt
2025-05-22 5:32 ` Jeff King
2025-05-22 15:47 ` Junio C Hamano
2025-05-22 16:59 ` Jeff King
2025-05-22 18:44 ` Junio C Hamano
2025-05-23 1:22 ` Taylor Blau
2025-05-23 2:08 ` Jeff King
2025-05-23 17:46 ` Taylor Blau
2025-05-25 18:41 ` [PATCH 0/5] midx: improve prepare_midx_pack() ergonomics Taylor Blau
2025-05-25 18:41 ` [PATCH 1/5] pack-bitmap.c: fix broken warning() when missing MIDX'd pack Taylor Blau
2025-05-26 7:23 ` Patrick Steinhardt
2025-05-28 2:00 ` Taylor Blau
2025-05-25 18:41 ` [PATCH 2/5] midx-write.c: guard against incremental MIDXs in want_included_pack() Taylor Blau
2025-05-26 7:23 ` Patrick Steinhardt
2025-05-28 2:08 ` Taylor Blau
2025-05-25 18:41 ` [PATCH 3/5] midx-write.c: simplify fill_packs_from_midx() Taylor Blau
2025-05-26 7:23 ` Patrick Steinhardt
2025-05-28 2:15 ` Taylor Blau
2025-05-25 18:42 ` [PATCH 4/5] midx-write.c: extract inner loop from fill_packs_from_midx() Taylor Blau
2025-05-25 18:42 ` [PATCH 5/5] midx: return a `packed_git` pointer from `prepare_midx_pack()` Taylor Blau
2025-05-26 7:24 ` Patrick Steinhardt
2025-05-28 2:18 ` Taylor Blau
2025-05-28 11:53 ` Patrick Steinhardt
2025-05-28 22:58 ` Taylor Blau [this message]
2025-05-28 22:59 ` [PATCH v2 1/4] midx: access pack names through `nth_midxed_pack_name()` Taylor Blau
2025-05-29 20:47 ` Junio C Hamano
2025-06-03 22:22 ` Taylor Blau
2025-05-29 20:51 ` Junio C Hamano
2025-06-03 22:23 ` Taylor Blau
2025-05-28 22:59 ` [PATCH v2 2/4] midx-write.c: guard against incremental MIDXs in want_included_pack() Taylor Blau
2025-05-28 22:59 ` [PATCH v2 3/4] midx-write.c: extract inner loop from fill_packs_from_midx() Taylor Blau
2025-05-28 22:59 ` [PATCH v2 4/4] midx: return a `packed_git` pointer from `prepare_midx_pack()` Taylor Blau
2025-05-30 6:50 ` Jeff King
2025-06-03 22:27 ` Taylor Blau
2025-08-28 23:25 ` Junio C Hamano
2025-05-23 1:31 ` [PATCH v2 2/2] midx: stop repeatedly looking up nonexistent packfiles Taylor Blau
2025-05-23 2:18 ` Jeff King
2025-05-21 13:24 ` [PATCH v2 0/2] packfile: avoid access(3p) calls for missing packs Junio C Hamano
2025-05-28 12:24 ` [PATCH v3 " Patrick Steinhardt
2025-05-28 12:24 ` [PATCH v3 1/2] packfile: explain ordering of how we look up auxiliary pack files Patrick Steinhardt
2025-05-28 12:24 ` [PATCH v3 2/2] midx: stop repeatedly looking up nonexistent packfiles Patrick Steinhardt
2025-05-30 6:27 ` [PATCH v3 0/2] packfile: avoid access(3p) calls for missing packs Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover.1748473122.git.me@ttaylorr.com \
--to=me@ttaylorr.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.