"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 <pclouds@xxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html