Many invocations of for_each_object_in_pack() and for_each_packed_object() (which invokes the former) subsequently check at least the type of the packed object, necessitating accessing the packfile itself. For locality reasons, it is thus better to iterate in pack order, instead of index order. Teach for_each_object_in_pack() to iterate in pack order by first creating a reverse index. This is based off work by Jeff King. Signed-off-by: Jonathan Tan <jonathantanmy@xxxxxxxxxx> --- After writing this patch and looking at it further, I'm not sure if this is a clear benefit, but here's the patch anyway. In particular, builtin/fsck.c and builtin/cat-file.c just deal with the OID directly and does not access the packfile at all (at least at the time of invoking for_each_packed_object). And revision.c, if we are excluding promisor objects, parses each packed promisor object, but it seems possible to avoid doing that (replacing the parse_object() by lookup_unknown_object() still passes tests). --- packfile.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packfile.c b/packfile.c index 6974903e5..371b64e9b 100644 --- a/packfile.c +++ b/packfile.c @@ -15,6 +15,7 @@ #include "tree-walk.h" #include "tree.h" #include "object-store.h" +#include "pack-revindex.h" char *odb_pack_name(struct strbuf *buf, const unsigned char *sha1, @@ -1890,14 +1891,17 @@ int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void uint32_t i; int r = 0; + load_pack_revindex(p); + for (i = 0; i < p->num_objects; i++) { + uint32_t pack_nr = p->revindex[i].nr; struct object_id oid; - if (!nth_packed_object_oid(&oid, p, i)) + if (!nth_packed_object_oid(&oid, p, pack_nr)) return error("unable to get sha1 of object %u in %s", - i, p->pack_name); + pack_nr, p->pack_name); - r = cb(&oid, p, i, data); + r = cb(&oid, p, pack_nr, data); if (r) break; } -- 2.18.0.597.ga71716f1ad-goog