"git log --stat -10000 v1.4.8 >/dev/null" takes 13s with v4 (8s with
v2). Of course we could do better when v4-aware tree-diff interface is
in place..

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 Oops.. forgot this and broke git.

 Another option is change cache_or_unpack_entry() to force
 OBJ_PV4_TREE to go through unpack_entry(), then update pv4_get_tree() to
 lookup the base cache at the first decode_entries() call. Right now
 it does not (hdr == 0) so we need more processing.

 packv4-parse.c | 22 ++++++++++++++++++++++
 packv4-parse.h |  2 ++
 sha1_file.c    | 11 +++++++++++
 3 files changed, 35 insertions(+)

diff --git a/packv4-parse.c b/packv4-parse.c
index b8855b0..448c91e 100644
--- a/packv4-parse.c
+++ b/packv4-parse.c
@@ -461,6 +461,10 @@ static int decode_entries(struct packed_git *p, struct 
pack_window **w_curs,
        avail -= scp - src;
        src = scp;
 
+       /* special case for pv4_cached_tree_to_canonical() */
+       if (!count && cached)
+               count = nb_entries;
+
        while (count) {
                unsigned int what;
 
@@ -648,3 +652,21 @@ unsigned long pv4_unpack_object_header_buffer(const 
unsigned char *base,
        *sizep = val >> 4;
        return cp - base;
 }
+
+/* offset must already be cached! */
+void *pv4_cached_tree_to_canonical(struct packed_git *p, off_t offset,
+                                  unsigned long size)
+{
+       int ret;
+       unsigned char *dst, *dcp;
+       unsigned char *v4_dstp = NULL;
+       dst = xmallocz(size);
+       dcp = dst;
+       ret = decode_entries(p, NULL, offset, 0, 0,
+                            &dcp, &size, &v4_dstp, NULL, NULL, 1);
+       if (ret < 0 || size != 0) {
+               free(dst);
+               return NULL;
+       }
+       return dst;
+}
diff --git a/packv4-parse.h b/packv4-parse.h
index f584c31..ad21e19 100644
--- a/packv4-parse.h
+++ b/packv4-parse.h
@@ -24,5 +24,7 @@ void *pv4_get_commit(struct packed_git *p, struct pack_window 
**w_curs,
 void *pv4_get_tree(struct packed_git *p, struct pack_window **w_curs,
                   off_t offset, unsigned long size,
                   void **v4_data, unsigned long *v4_size);
+void *pv4_cached_tree_to_canonical(struct packed_git *p, off_t offset,
+                                  unsigned long size);
 
 #endif
diff --git a/sha1_file.c b/sha1_file.c
index 82570be..0944ef6 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2000,6 +2000,17 @@ static void *cache_or_unpack_entry(struct packed_git *p, 
off_t base_offset,
        if (!eq_delta_base_cache_entry(ent, p, base_offset))
                return unpack_entry(p, base_offset, type, base_size);
 
+       if (ent->type == OBJ_PV4_TREE) {
+               ret = pv4_cached_tree_to_canonical(p, base_offset, ent->size);
+               if (!ret)
+                       return NULL;
+               if (!keep_cache)
+                       clear_delta_base_cache_entry(ent);
+               *type = OBJ_TREE;
+               *base_size = ent->size;
+               return ret;
+       }
+
        ret = ent->data;
 
        if (!keep_cache)
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to