Skip to content

Commit 5b08640

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 412916e commit 5b08640

File tree

4 files changed

+19
-11
lines changed

4 files changed

+19
-11
lines changed

builtin/cat-file.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ static void expand_atom(struct strbuf *sb, const char *atom, int len,
150150
if (!data->mark_query)
151151
strbuf_addstr(sb, sha1_to_hex(data->sha1));
152152
} else if (is_atom("objecttype", atom, len)) {
153-
if (!data->mark_query)
153+
if (data->mark_query)
154+
data->info.typep = &data->type;
155+
else
154156
strbuf_addstr(sb, typename(data->type));
155157
} else if (is_atom("objectsize", atom, len)) {
156158
if (data->mark_query)
@@ -229,8 +231,7 @@ static int batch_one_object(const char *obj_name, struct batch_options *opt,
229231
return 0;
230232
}
231233

232-
data->type = sha1_object_info_extended(data->sha1, &data->info);
233-
if (data->type <= 0) {
234+
if (sha1_object_info_extended(data->sha1, &data->info) < 0) {
234235
printf("%s missing\n", obj_name);
235236
fflush(stdout);
236237
return 0;

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,6 +1099,7 @@ extern int unpack_object_header(struct packed_git *, struct pack_window **, off_
10991099

11001100
struct object_info {
11011101
/* Request */
1102+
enum object_type *typep;
11021103
unsigned long *sizep;
11031104
unsigned long *disk_sizep;
11041105

sha1_file.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,24 +2433,26 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
24332433
{
24342434
struct cached_object *co;
24352435
struct pack_entry e;
2436-
int type, rtype;
2436+
int rtype;
24372437

24382438
co = find_cached_object(sha1);
24392439
if (co) {
2440+
if (oi->typep)
2441+
*(oi->typep) = co->type;
24402442
if (oi->sizep)
24412443
*(oi->sizep) = co->size;
24422444
if (oi->disk_sizep)
24432445
*(oi->disk_sizep) = 0;
24442446
oi->whence = OI_CACHED;
2445-
return co->type;
2447+
return 0;
24462448
}
24472449

24482450
if (!find_pack_entry(sha1, &e)) {
24492451
/* Most likely it's a loose object. */
2450-
if (!sha1_loose_object_info(sha1, &type,
2452+
if (!sha1_loose_object_info(sha1, oi->typep,
24512453
oi->sizep, oi->disk_sizep)) {
24522454
oi->whence = OI_LOOSE;
2453-
return type;
2455+
return 0;
24542456
}
24552457

24562458
/* 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)
24592461
return -1;
24602462
}
24612463

2462-
rtype = packed_object_info(e.p, e.offset, &type, oi->sizep,
2464+
rtype = packed_object_info(e.p, e.offset, oi->typep, oi->sizep,
24632465
oi->disk_sizep);
24642466
if (rtype < 0) {
24652467
mark_bad_packed_object(e.p, sha1);
@@ -2474,15 +2476,19 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
24742476
rtype == OBJ_OFS_DELTA);
24752477
}
24762478

2477-
return type;
2479+
return 0;
24782480
}
24792481

24802482
int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
24812483
{
2484+
enum object_type type;
24822485
struct object_info oi = {0};
24832486

2487+
oi.typep = &type;
24842488
oi.sizep = sizep;
2485-
return sha1_object_info_extended(sha1, &oi);
2489+
if (sha1_object_info_extended(sha1, &oi) < 0)
2490+
return -1;
2491+
return type;
24862492
}
24872493

24882494
static void *read_packed_sha1(const unsigned char *sha1,

streaming.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ static enum input_source istream_source(const unsigned char *sha1,
111111
unsigned long size;
112112
int status;
113113

114+
oi->typep = type;
114115
oi->sizep = &size;
115116
status = sha1_object_info_extended(sha1, oi);
116117
if (status < 0)
117118
return stream_error;
118-
*type = status;
119119

120120
switch (oi->whence) {
121121
case OI_LOOSE:

0 commit comments

Comments
 (0)