From 0763671b8e0b3ef873df13c741a911b809e6813d Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 23 Feb 2020 23:27:36 -0500 Subject: nth_packed_object_oid(): use customary integer return Our nth_packed_object_sha1() function returns NULL for error. So when we wrapped it with nth_packed_object_oid(), we kept the same semantics. But it's a bit funny, because the caller actually passes in an out parameter, and the pointer we return is just that same struct they passed to us (or NULL). It's not too terrible, but it does make the interface a little non-idiomatic. Let's switch to our usual "0 for success, negative for error" return value. Most callers either don't check it, or are trivially converted. The one that requires the biggest change is actually improved, as we can ditch an extra aliased pointer variable. Since we are changing the interface in a subtle way that the compiler wouldn't catch, let's also change the name to catch any topics in flight. We can drop the 'o' and make it nth_packed_object_id(). That's slightly shorter, but also less redundant since the 'o' stands for "object" already. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/pack-objects.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin/pack-objects.c') diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 940fbcb7b3..de8335e2bd 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3053,7 +3053,7 @@ static void add_objects_in_unpacked_packs(void) in_pack.alloc); for (i = 0; i < p->num_objects; i++) { - nth_packed_object_oid(&oid, p, i); + nth_packed_object_id(&oid, p, i); o = lookup_unknown_object(&oid); if (!(o->flags & OBJECT_ADDED)) mark_in_pack_object(o, p, &in_pack); @@ -3157,7 +3157,7 @@ static void loosen_unused_packed_objects(void) die(_("cannot open pack index")); for (i = 0; i < p->num_objects; i++) { - nth_packed_object_oid(&oid, p, i); + nth_packed_object_id(&oid, p, i); if (!packlist_find(&to_pack, &oid) && !has_sha1_pack_kept_or_nonlocal(&oid) && !loosened_object_can_be_discarded(&oid, p->mtime)) -- cgit v1.2.3 From 3f83fd5e44c1f038c8a7033cb77399e9ef4f43a9 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 23 Feb 2020 23:29:44 -0500 Subject: 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 Signed-off-by: Junio C Hamano --- builtin/pack-objects.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'builtin/pack-objects.c') diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index de8335e2bd..8692ab3fe6 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1618,23 +1618,17 @@ static void cleanup_preferred_base(void) * deltify other objects against, in order to avoid * circular deltas. */ -static int can_reuse_delta(const unsigned char *base_sha1, +static int can_reuse_delta(const struct object_id *base_oid, struct object_entry *delta, struct object_entry **base_out) { struct object_entry *base; - struct object_id base_oid; - - if (!base_sha1) - return 0; - - oidread(&base_oid, base_sha1); /* * First see if we're already sending the base (or it's explicitly in * our "excluded" list). */ - base = packlist_find(&to_pack, &base_oid); + base = packlist_find(&to_pack, base_oid); if (base) { if (!in_same_island(&delta->idx.oid, &base->idx.oid)) return 0; @@ -1647,9 +1641,9 @@ static int can_reuse_delta(const unsigned char *base_sha1, * even if it was buried too deep in history to make it into the * packing list. */ - if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, &base_oid)) { + if (thin && bitmap_has_oid_in_uninteresting(bitmap_git, base_oid)) { if (use_delta_islands) { - if (!in_same_island(&delta->idx.oid, &base_oid)) + if (!in_same_island(&delta->idx.oid, base_oid)) return 0; } *base_out = NULL; @@ -1666,7 +1660,8 @@ static void check_object(struct object_entry *entry) if (IN_PACK(entry)) { struct packed_git *p = IN_PACK(entry); struct pack_window *w_curs = NULL; - const unsigned char *base_ref = NULL; + int have_base = 0; + struct object_id base_ref; struct object_entry *base_entry; unsigned long used, used_0; unsigned long avail; @@ -1707,9 +1702,13 @@ static void check_object(struct object_entry *entry) unuse_pack(&w_curs); return; case OBJ_REF_DELTA: - if (reuse_delta && !entry->preferred_base) - base_ref = use_pack(p, &w_curs, - entry->in_pack_offset + used, NULL); + if (reuse_delta && !entry->preferred_base) { + oidread(&base_ref, + use_pack(p, &w_curs, + entry->in_pack_offset + used, + NULL)); + have_base = 1; + } entry->in_pack_header_size = used + the_hash_algo->rawsz; break; case OBJ_OFS_DELTA: @@ -1739,13 +1738,15 @@ static void check_object(struct object_entry *entry) revidx = find_pack_revindex(p, ofs); if (!revidx) goto give_up; - base_ref = nth_packed_object_sha1(p, revidx->nr); + if (!nth_packed_object_id(&base_ref, p, revidx->nr)) + have_base = 1; } entry->in_pack_header_size = used + used_0; break; } - if (can_reuse_delta(base_ref, entry, &base_entry)) { + if (have_base && + can_reuse_delta(&base_ref, entry, &base_entry)) { oe_set_type(entry, entry->in_pack_type); SET_SIZE(entry, in_pack_size); /* delta size */ SET_DELTA_SIZE(entry, in_pack_size); @@ -1755,7 +1756,7 @@ static void check_object(struct object_entry *entry) entry->delta_sibling_idx = base_entry->delta_child_idx; SET_DELTA_CHILD(base_entry, entry); } else { - SET_DELTA_EXT(entry, base_ref); + SET_DELTA_EXT(entry, base_ref.hash); } unuse_pack(&w_curs); -- cgit v1.2.3 From a93c141ddef25dc999fff73c590b42d3af606ff3 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 23 Feb 2020 23:30:07 -0500 Subject: pack-objects: convert oe_set_delta_ext() to use object_id We already store an object_id internally, and now our sole caller also has one. Let's stop passing around the internal hash array, which adds a bit of type safety. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/pack-objects.c | 2 +- pack-objects.c | 4 ++-- pack-objects.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'builtin/pack-objects.c') diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 8692ab3fe6..44f44fcb1a 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1756,7 +1756,7 @@ static void check_object(struct object_entry *entry) entry->delta_sibling_idx = base_entry->delta_child_idx; SET_DELTA_CHILD(base_entry, entry); } else { - SET_DELTA_EXT(entry, base_ref.hash); + SET_DELTA_EXT(entry, &base_ref); } unuse_pack(&w_curs); diff --git a/pack-objects.c b/pack-objects.c index 5e5a3c62d9..f2a433885a 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -203,14 +203,14 @@ struct object_entry *packlist_alloc(struct packing_data *pdata, void oe_set_delta_ext(struct packing_data *pdata, struct object_entry *delta, - const unsigned char *sha1) + const struct object_id *oid) { struct object_entry *base; ALLOC_GROW(pdata->ext_bases, pdata->nr_ext + 1, pdata->alloc_ext); base = &pdata->ext_bases[pdata->nr_ext++]; memset(base, 0, sizeof(*base)); - hashcpy(base->idx.oid.hash, sha1); + oidcpy(&base->idx.oid, oid); /* These flags mark that we are not part of the actual pack output. */ base->preferred_base = 1; diff --git a/pack-objects.h b/pack-objects.h index d3975e079b..9d88e3e518 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -292,7 +292,7 @@ static inline void oe_set_delta(struct packing_data *pack, void oe_set_delta_ext(struct packing_data *pack, struct object_entry *e, - const unsigned char *sha1); + const struct object_id *oid); static inline struct object_entry *oe_delta_child( const struct packing_data *pack, -- cgit v1.2.3 From f66d4e025059b734ba8da40ec059bb0fb8991306 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sun, 23 Feb 2020 23:31:22 -0500 Subject: pack-objects: use object_id struct in pack-reuse code When the pack-reuse code is dumping an OFS_DELTA entry to a client that doesn't support it, we re-write it as a REF_DELTA. To do so, we use nth_packed_object_sha1() to get the oid, but that function is soon going away in favor of the more type-safe nth_packed_object_id(). Let's switch now in preparation. Note that this does incur an extra hash copy (from the pack idx mmap to the object_id and then to the output, rather than straight from mmap to the output). But this is not worth worrying about. It's probably not measurable even when it triggers, and this is fallback code that we expect to trigger very rarely (since everybody supports OFS_DELTA these days anyway). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/pack-objects.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'builtin/pack-objects.c') diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 44f44fcb1a..73fca2cb17 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -872,14 +872,15 @@ static void write_reused_pack_one(size_t pos, struct hashfile *out, /* Convert to REF_DELTA if we must... */ if (!allow_ofs_delta) { int base_pos = find_revindex_position(reuse_packfile, base_offset); - const unsigned char *base_sha1 = - nth_packed_object_sha1(reuse_packfile, - reuse_packfile->revindex[base_pos].nr); + struct object_id base_oid; + + nth_packed_object_id(&base_oid, reuse_packfile, + reuse_packfile->revindex[base_pos].nr); len = encode_in_pack_object_header(header, sizeof(header), OBJ_REF_DELTA, size); hashwrite(out, header, len); - hashwrite(out, base_sha1, 20); + hashwrite(out, base_oid.hash, 20); copy_pack_data(out, reuse_packfile, w_curs, cur, next - cur); return; } -- cgit v1.2.3