teach sha1_object_info_extended a "disk_size" query
Using sha1_object_info_extended, a caller can find out the type of an object, its size, and information about where it is stored. In addition to the object's "true" size, it can also be useful to know the size that the object takes on disk (e.g., to generate statistics about which refs consume space). This patch adds a "disk_sizep" field to "struct object_info", and fills it in during sha1_object_info_extended if it is non-NULL. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Jul 7, 2013 at 06:04 UTC
161f00e708874bac646da2ac05c66a18ade2c074
2 files changed
+17
-4
cache.h
+1
@@ -1099,6 +1099,7 @@ extern int unpack_object_header(struct packed_git *, struct pack_window **, off_
1099
struct object_info {
1100
/* Request */
1101
unsigned long *sizep;
1102
+ unsigned long *disk_sizep;
1103
1104
/* Response */
1105
enum {
sha1_file.c
+16
-4
@@ -1694,7 +1694,8 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
1694
#define POI_STACK_PREALLOC 64
1695
1696
static int packed_object_info(struct packed_git *p, off_t obj_offset,
1697
- unsigned long *sizep, int *rtype)
1697
+ unsigned long *sizep, int *rtype,
1698
+ unsigned long *disk_sizep)
1699
{
1700
struct pack_window *w_curs = NULL;
1701
unsigned long size;
@@ -1728,6 +1729,11 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
1729
}
1730
}
1731
1732
+ if (disk_sizep) {
1733
+ struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1734
+ *disk_sizep = revidx[1].offset - obj_offset;
1735
+ }
1736
+
1737
while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1738
off_t base_offset;
1739
/* Push the object we're going to leave behind */
@@ -2338,7 +2344,8 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1,
2344
2345
}
2346
2341
-static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *sizep)
2347
+static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *sizep,
2348
+ unsigned long *disk_sizep)
2349
{
2350
int status;
2351
unsigned long mapsize, size;
@@ -2349,6 +2356,8 @@ static int sha1_loose_object_info(const unsigned char *sha1, unsigned long *size
2356
map = map_sha1_file(sha1, &mapsize);
2357
if (!map)
2358
return error("unable to find %s", sha1_to_hex(sha1));
2359
+ if (disk_sizep)
2360
+ *disk_sizep = mapsize;
2361
if (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)
2362
status = error("unable to unpack %s header",
2363
sha1_to_hex(sha1));
@@ -2372,13 +2381,15 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
2381
if (co) {
2382
if (oi->sizep)
2383
*(oi->sizep) = co->size;
2384
+ if (oi->disk_sizep)
2385
+ *(oi->disk_sizep) = 0;
2386
oi->whence = OI_CACHED;
2387
return co->type;
2388
}
2389
2390
if (!find_pack_entry(sha1, &e)) {
2391
/* Most likely it's a loose object. */
2381
- status = sha1_loose_object_info(sha1, oi->sizep);
2392
+ status = sha1_loose_object_info(sha1, oi->sizep, oi->disk_sizep);
2393
if (status >= 0) {
2394
oi->whence = OI_LOOSE;
2395
return status;
@@ -2390,7 +2401,8 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi)
2401
return status;
2402
}
2403
2393
- status = packed_object_info(e.p, e.offset, oi->sizep, &rtype);
2404
+ status = packed_object_info(e.p, e.offset, oi->sizep, &rtype,
2405
+ oi->disk_sizep);
2406
if (status < 0) {
2407
mark_bad_packed_object(e.p, sha1);
2408
status = sha1_object_info_extended(sha1, oi);