sha1_file: refactor read_object
authorJonathan Tan <jonathantanmy@google.com>
Thu, 22 Jun 2017 00:40:21 +0000 (17:40 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 22 Jun 2017 01:54:43 +0000 (18:54 -0700)
read_object() and sha1_object_info_extended() both implement mechanisms
such as object replacement, retrying the packed store after failing to
find the object in the packed store then the loose store, and being able
to mark a packed object as bad and then retrying the whole process.
Consolidating these mechanisms would be a great help to maintainability.

Therefore, consolidate them by extending sha1_object_info_extended() to
support the functionality needed, and then modifying read_object() to
use sha1_object_info_extended().

Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
cache.h
sha1_file.c
diff --git a/cache.h b/cache.h
index a3631b2374696efef69129e2f590501cdaec9e67..48aea923b24dd001b75db47ad7c28db2764c3a46 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1827,6 +1827,7 @@ struct object_info {
        off_t *disk_sizep;
        unsigned char *delta_base_sha1;
        struct strbuf *typename;
+       void **contentp;
 
        /* Response */
        enum {
index 0c996370de83ef96be93282d8af0413904161c1a..615a27dac60bcad608c5a59575c4860e9487e1e7 100644 (file)
@@ -2005,19 +2005,6 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
        return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type *type, unsigned long *size, const unsigned char *sha1)
-{
-       int ret;
-       git_zstream stream;
-       char hdr[8192];
-
-       ret = unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr));
-       if (ret < Z_OK || (*type = parse_sha1_header(hdr, size)) < 0)
-               return NULL;
-
-       return unpack_sha1_rest(&stream, hdr, *size, sha1);
-}
-
 unsigned long get_size_from_delta(struct packed_git *p,
                                  struct pack_window **w_curs,
                                  off_t curpos)
@@ -2326,8 +2313,10 @@ static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
        if (!ent)
                return unpack_entry(p, base_offset, type, base_size);
 
-       *type = ent->type;
-       *base_size = ent->size;
+       if (type)
+               *type = ent->type;
+       if (base_size)
+               *base_size = ent->size;
        return xmemdupz(ent->data, ent->size);
 }
 
@@ -2388,9 +2377,16 @@ int packed_object_info(struct packed_git *p, off_t obj_offset,
         * We always get the representation type, but only convert it to
         * a "real" type later if the caller is interested.
         */
-       type = unpack_object_header(p, &w_curs, &curpos, &size);
+       if (oi->contentp) {
+               *oi->contentp = cache_or_unpack_entry(p, obj_offset, oi->sizep,
+                                                     &type);
+               if (!*oi->contentp)
+                       type = OBJ_BAD;
+       } else {
+               type = unpack_object_header(p, &w_curs, &curpos, &size);
+       }
 
-       if (oi->sizep) {
+       if (!oi->contentp && oi->sizep) {
                if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
                        off_t tmp_pos = curpos;
                        off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
@@ -2679,8 +2675,10 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
                free(external_base);
        }
 
-       *final_type = type;
-       *final_size = size;
+       if (final_type)
+               *final_type = type;
+       if (final_size)
+               *final_size = size;
 
        unuse_pack(&w_curs);
 
@@ -2914,6 +2912,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
        git_zstream stream;
        char hdr[32];
        struct strbuf hdrbuf = STRBUF_INIT;
+       unsigned long size_scratch;
 
        if (oi->delta_base_sha1)
                hashclr(oi->delta_base_sha1);
@@ -2926,7 +2925,7 @@ static int sha1_loose_object_info(const unsigned char *sha1,
         * return value implicitly indicates whether the
         * object even exists.
         */
-       if (!oi->typep && !oi->typename && !oi->sizep) {
+       if (!oi->typep && !oi->typename && !oi->sizep && !oi->contentp) {
                const char *path;
                struct stat st;
                if (stat_sha1_file(sha1, &st, &path) < 0)
@@ -2939,6 +2938,10 @@ static int sha1_loose_object_info(const unsigned char *sha1,
        map = map_sha1_file(sha1, &mapsize);
        if (!map)
                return -1;
+
+       if (!oi->sizep)
+               oi->sizep = &size_scratch;
+
        if (oi->disk_sizep)
                *oi->disk_sizep = mapsize;
        if ((flags & OBJECT_INFO_ALLOW_UNKNOWN_TYPE)) {
@@ -2956,10 +2959,18 @@ static int sha1_loose_object_info(const unsigned char *sha1,
                                       sha1_to_hex(sha1));
        } else if ((status = parse_sha1_header_extended(hdr, oi, flags)) < 0)
                status = error("unable to parse %s header", sha1_to_hex(sha1));
-       git_inflate_end(&stream);
+
+       if (status >= 0 && oi->contentp)
+               *oi->contentp = unpack_sha1_rest(&stream, hdr,
+                                                *oi->sizep, sha1);
+       else
+               git_inflate_end(&stream);
+
        munmap(map, mapsize);
        if (status && oi->typep)
                *oi->typep = status;
+       if (oi->sizep == &size_scratch)
+               oi->sizep = NULL;
        strbuf_release(&hdrbuf);
        return (status < 0) ? status : 0;
 }
@@ -2985,6 +2996,8 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
                        hashclr(oi->delta_base_sha1);
                if (oi->typename)
                        strbuf_addstr(oi->typename, typename(co->type));
+               if (oi->contentp)
+                       *oi->contentp = xmemdupz(co->buf, co->size);
                oi->whence = OI_CACHED;
                return 0;
        }
@@ -3078,28 +3091,15 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
 static void *read_object(const unsigned char *sha1, enum object_type *type,
                         unsigned long *size)
 {
-       unsigned long mapsize;
-       void *map, *buf;
-       struct cached_object *co;
-
-       co = find_cached_object(sha1);
-       if (co) {
-               *type = co->type;
-               *size = co->size;
-               return xmemdupz(co->buf, co->size);
-       }
+       struct object_info oi = OBJECT_INFO_INIT;
+       void *content;
+       oi.typep = type;
+       oi.sizep = size;
+       oi.contentp = &content;
 
-       buf = read_packed_sha1(sha1, type, size);
-       if (buf)
-               return buf;
-       map = map_sha1_file(sha1, &mapsize);
-       if (map) {
-               buf = unpack_sha1_file(map, mapsize, type, size, sha1);
-               munmap(map, mapsize);
-               return buf;
-       }
-       reprepare_packed_git();
-       return read_packed_sha1(sha1, type, size);
+       if (sha1_object_info_extended(sha1, &oi, 0) < 0)
+               return NULL;
+       return content;
 }
 
 /*