Add an option to struct object_info to suppress population of additional
information about a packed object if unneeded. This allows an
optimization in which sha1_object_info_extended() does not even need to
access the pack if no information besides provenance is requested. A
subsequent patch will make use of this optimization.
Signed-off-by: Jonathan Tan <jonathanta...@google.com>
---
 cache.h     |  1 +
 sha1_file.c | 17 +++++++++++++----
 streaming.c |  1 +
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/cache.h b/cache.h
index 7cf2ca466..2e1cc3fe2 100644
--- a/cache.h
+++ b/cache.h
@@ -1828,6 +1828,7 @@ struct object_info {
        unsigned char *delta_base_sha1;
        struct strbuf *typename;
        void **contentp;
+       unsigned populate_u : 1;
 
        /* Response */
        enum {
diff --git a/sha1_file.c b/sha1_file.c
index 24f7a146e..68e3a3400 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -3020,6 +3020,13 @@ int sha1_object_info_extended(const unsigned char *sha1, 
struct object_info *oi,
                }
        }
 
+       if (!oi->typep && !oi->sizep && !oi->disk_sizep &&
+           !oi->delta_base_sha1 && !oi->typename && !oi->contentp &&
+           !oi->populate_u) {
+               oi->whence = OI_PACKED;
+               return 0;
+       }
+
        rtype = packed_object_info(e.p, e.offset, oi);
        if (rtype < 0) {
                mark_bad_packed_object(e.p, real);
@@ -3028,10 +3035,12 @@ int sha1_object_info_extended(const unsigned char 
*sha1, struct object_info *oi,
                oi->whence = OI_DBCACHED;
        } else {
                oi->whence = OI_PACKED;
-               oi->u.packed.offset = e.offset;
-               oi->u.packed.pack = e.p;
-               oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
-                                        rtype == OBJ_OFS_DELTA);
+               if (oi->populate_u) {
+                       oi->u.packed.offset = e.offset;
+                       oi->u.packed.pack = e.p;
+                       oi->u.packed.is_delta = (rtype == OBJ_REF_DELTA ||
+                                                rtype == OBJ_OFS_DELTA);
+               }
        }
 
        return 0;
diff --git a/streaming.c b/streaming.c
index 9afa66b8b..deebc18a8 100644
--- a/streaming.c
+++ b/streaming.c
@@ -113,6 +113,7 @@ static enum input_source istream_source(const unsigned char 
*sha1,
 
        oi->typep = type;
        oi->sizep = &size;
+       oi->populate_u = 1;
        status = sha1_object_info_extended(sha1, oi, 0);
        if (status < 0)
                return stream_error;
-- 
2.13.1.611.g7e3b11ae1-goog

Reply via email to