Skip to content

Commit 3f83fd5

Browse files
peffgitster
authored andcommitted
pack-objects: read delta base oid into object_id struct
When we're considering reusing an on-disk delta, we get the oid of the base as a pointer to unsigned char bytes of the hash, either into the packfile itself (for REF_DELTA) or into the pack idx (using the revindex to convert the offset into an index entry). Instead, we'd prefer to use a more type-safe object_id as much as possible. We can get the pack idx using nth_packed_object_id() instead. For the packfile bytes, we can copy them out using oidread(). This doesn't even incur an extra copy overall, since the next thing we'd always do with that pointer is pass it to can_reuse_delta(), which needs an object_id anyway (and called oidread() itself). So this patch also converts that function to take the object_id directly. Note that we did previously use NULL as a sentinel value when the object isn't a delta. We could probably get away with using the null oid for this, but instead we'll use an explicit boolean flag, which should make things more obvious for people reading the code later. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0763671 commit 3f83fd5

File tree

1 file changed

+18
-17
lines changed

1 file changed

+18
-17
lines changed

builtin/pack-objects.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,23 +1618,17 @@ static void cleanup_preferred_base(void)
16181618
* deltify other objects against, in order to avoid
16191619
* circular deltas.
16201620
*/
1621-
static int can_reuse_delta(const unsigned char *base_sha1,
1621+
static int can_reuse_delta(const struct object_id *base_oid,
16221622
struct object_entry *delta,
16231623
struct object_entry **base_out)
16241624
{
16251625
struct object_entry *base;
1626-
struct object_id base_oid;
1627-
1628-
if (!base_sha1)
1629-
return 0;
1630-
1631-
oidread(&base_oid, base_sha1);
16321626

16331627
/*
16341628
* First see if we're already sending the base (or it's explicitly in
16351629
* our "excluded" list).
16361630
*/
1637-
base = packlist_find(&to_pack, &base_oid);
1631+
base = packlist_find(&to_pack, base_oid);
16381632
if (base) {
16391633
if (!in_same_island(&delta->idx.oid, &base->idx.oid))
16401634
return 0;
@@ -1647,9 +1641,9 @@ static int can_reuse_delta(const unsigned char *base_sha1,
16471641
* even if it was buried too deep in history to make it into the
16481642
* packing list.
16491643
*/
1650-
if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, &base_oid)) {
1644+
if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, base_oid)) {
16511645
if (use_delta_islands) {
1652-
if (!in_same_island(&delta->idx.oid, &base_oid))
1646+
if (!in_same_island(&delta->idx.oid, base_oid))
16531647
return 0;
16541648
}
16551649
*base_out = NULL;
@@ -1666,7 +1660,8 @@ static void check_object(struct object_entry *entry)
16661660
if (IN_PACK(entry)) {
16671661
struct packed_git *p = IN_PACK(entry);
16681662
struct pack_window *w_curs = NULL;
1669-
const unsigned char *base_ref = NULL;
1663+
int have_base = 0;
1664+
struct object_id base_ref;
16701665
struct object_entry *base_entry;
16711666
unsigned long used, used_0;
16721667
unsigned long avail;
@@ -1707,9 +1702,13 @@ static void check_object(struct object_entry *entry)
17071702
unuse_pack(&w_curs);
17081703
return;
17091704
case OBJ_REF_DELTA:
1710-
if (reuse_delta && !entry->preferred_base)
1711-
base_ref = use_pack(p, &w_curs,
1712-
entry->in_pack_offset + used, NULL);
1705+
if (reuse_delta && !entry->preferred_base) {
1706+
oidread(&base_ref,
1707+
use_pack(p, &w_curs,
1708+
entry->in_pack_offset + used,
1709+
NULL));
1710+
have_base = 1;
1711+
}
17131712
entry->in_pack_header_size = used + the_hash_algo->rawsz;
17141713
break;
17151714
case OBJ_OFS_DELTA:
@@ -1739,13 +1738,15 @@ static void check_object(struct object_entry *entry)
17391738
revidx = find_pack_revindex(p, ofs);
17401739
if (!revidx)
17411740
goto give_up;
1742-
base_ref = nth_packed_object_sha1(p, revidx->nr);
1741+
if (!nth_packed_object_id(&base_ref, p, revidx->nr))
1742+
have_base = 1;
17431743
}
17441744
entry->in_pack_header_size = used + used_0;
17451745
break;
17461746
}
17471747

1748-
if (can_reuse_delta(base_ref, entry, &base_entry)) {
1748+
if (have_base &&
1749+
can_reuse_delta(&base_ref, entry, &base_entry)) {
17491750
oe_set_type(entry, entry->in_pack_type);
17501751
SET_SIZE(entry, in_pack_size); /* delta size */
17511752
SET_DELTA_SIZE(entry, in_pack_size);
@@ -1755,7 +1756,7 @@ static void check_object(struct object_entry *entry)
17551756
entry->delta_sibling_idx = base_entry->delta_child_idx;
17561757
SET_DELTA_CHILD(base_entry, entry);
17571758
} else {
1758-
SET_DELTA_EXT(entry, base_ref);
1759+
SET_DELTA_EXT(entry, base_ref.hash);
17591760
}
17601761

17611762
unuse_pack(&w_curs);

0 commit comments

Comments
 (0)