You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
midx: return a packed_git pointer from prepare_midx_pack()
The prepare_midx_pack() function is designed to convert a MIDX-specific
pack_int_id for a given pack into a pointer into an actual `packed_git`
structure.
In general, these calls look something like:
struct packed_git *p;
if (prepare_midx_pack(the_repository, some_midx, some_pack_int_id))
die("could not load pack xyz");
p = some_midx->packs[some_pack_int_id];
, and in a pre-incremental MIDX world, this pattern works well. However,
in a post-incremental MIDX world, this pattern is a little more prone to
errors.
These errors can happen when the given 'pack_int_id' is not usable as an
index into the 'm->packs' array. And this happens in all layers but the
bottom-most one in an incremental MIDX chain. Each layer stores only the
packs that are local to that layer of the chain, and offsets them by the
total number of packs in the base MIDX(s).
But there is other awkwardness here. Thinking back to the above snippet,
suppose that the pack with ID 'some_pack_int_id' is in a layer in the
middle of the MIDX chain. Then it is still invalid to do:
p = some_midx->packs[some_pack_int_id - some_midx->num_packs_in_base];
, becuase the top-most layer (here 'some_midx') may not even have that
pack! So we would have to chase down the '->base_midx' pointer in order
to get the correct result. midx.c has a helper to do this (called
'midx_for_pack()'), but it is meant only for internal use.
That means that a full, working version of the above adjusted to handle
incremental MIDXs would look something like:
struct packed_git *p;
if (prepare_midx_pack(the_repository, some_midx, some_pack_int_id))
die("could not load pack xyz");
while (m && pack_int_id < m->num_packs_in_base)
m = m->base_midx;
if (!m)
BUG("broken midx?");
if (pack_int_id >= m->num_packs + m->num_packs_in_base)
BUG("broken pack_int_id?");
p = m->packs[pack_int_id - m->num_packs_in_base];
, which is far too verbose to access a single pack by its pack_int_id in
a MIDX chain.
Let's instead have prepare_midx_pack() return a pointer to the
packed_git structure itself, hiding the above as an implementation
detail of prepare_midx_pack(). This patch turns the above snippet into:
struct packed_git *p = prepare_midx_pack(the_repository, some_midx,
some_pack_int_id);
if (!p)
die("could not load pack xyz");
making it far easier and less error-prone to access packs by their
pack_int_id in a MIDX chain.
(In the future, we may want to consider similar treatment for, e.g., the
pack_names array. Likewise, it might make sense to rename the "packs"
member of the MIDX structure to suggest that it shouldn't be accessed
directly outside of midx.c.)
Suggested-by: Jeff King <[email protected]>
Signed-off-by: Taylor Blau <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
0 commit comments