summaryrefslogtreecommitdiff
path: root/sha1_file.c
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2013-07-12 02:34:57 -0400
committerLibravatar Junio C Hamano <gitster@pobox.com>2013-07-12 10:16:36 -0700
commit5b0864070e1e64683e49464c77a72f3c528c8f71 (patch)
tree42cf6748f5407d896512151b112b587879ee22ab /sha1_file.c
parentpacked_object_info: make type lookup optional (diff)
downloadtgif-5b0864070e1e64683e49464c77a72f3c528c8f71.tar.xz
sha1_object_info_extended: make type calculation optional
Each caller of sha1_object_info_extended sets up an object_info struct to tell the function which elements of the object it wants to get. Until now, getting the type of the object has always been required (and it is returned via the return type rather than a pointer in object_info). This can involve actually opening a loose object file to determine its type, or following delta chains to determine a packed file's base type. These effects produce a measurable slow-down when doing a "cat-file --batch-check" that does not include %(objecttype). This patch adds a "typep" query to struct object_info, so that it can be optionally queried just like size and disk_size. As a result, the return type of the function is no longer the object type, but rather 0/-1 for success/error. As there are only three callers total, we just fix up each caller rather than keep a compatibility wrapper: 1. The simpler sha1_object_info wrapper continues to always ask for and return the type field. 2. The istream_source function wants to know the type, and so always asks for it. 3. The cat-file batch code asks for the type only when %(objecttype) is part of the format string. On linux.git, the best-of-five for running: $ git rev-list --objects --all >objects $ time git cat-file --batch-check='%(objectsize:disk)' on a fully packed repository goes from: real 0m8.680s user 0m8.160s sys 0m0.512s to: real 0m7.205s user 0m6.580s sys 0m0.608s Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'sha1_file.c')
-rw-r--r--sha1_file.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/sha1_file.c b/sha1_file.c
index fa2809884b..d391271310 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2433,24 +2433,26 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
{
struct cached_object *co;
struct pack_entry e;
- int type, rtype;
+ int rtype;
co = find_cached_object(sha1);
if (co) {
+ if (oi->typep)
+ *(oi->typep) = co->type;
if (oi->sizep)
*(oi->sizep) = co->size;
if (oi->disk_sizep)
*(oi->disk_sizep) = 0;
oi->whence = OI_CACHED;
- return co->type;
+ return 0;
}
if (!find_pack_entry(sha1, &e)) {
/* Most likely it's a loose object. */
- if (!sha1_loose_object_info(sha1, &type,
+ if (!sha1_loose_object_info(sha1, oi->typep,
oi->sizep, oi->disk_sizep)) {
oi->whence = OI_LOOSE;
- return type;
+ return 0;
}
/* Not a loose object; someone else may have just packed it. */
@@ -2459,7 +2461,7 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
return -1;
}
- rtype = packed_object_info(e.p, e.offset, &type, oi->sizep,
+ rtype = packed_object_info(e.p, e.offset, oi->typep, oi->sizep,
oi->disk_sizep);
if (rtype < 0) {
mark_bad_packed_object(e.p, sha1);
@@ -2474,15 +2476,19 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
rtype == OBJ_OFS_DELTA);
}
- return type;
+ return 0;
}
int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
{
+ enum object_type type;
struct object_info oi = {0};
+ oi.typep = &type;
oi.sizep = sizep;
- return sha1_object_info_extended(sha1, &oi);
+ if (sha1_object_info_extended(sha1, &oi) < 0)
+ return -1;
+ return type;
}
static void *read_packed_sha1(const unsigned char *sha1,