Because there is no delta object cache for tree objects yet, walking tree entries may result in a lot of recursion. Let's add --min-tree-copy=N where N is the minimum number of copied entries in a single copy sequence allowed for encoding tree deltas. The default is 1. Specifying 0 disables tree deltas entirely. This allows for experiments with the delta width and see the influence on pack size vs runtime access cost. Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx> --- packv4-create.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/packv4-create.c b/packv4-create.c index 9d6ffc0..34dcebf 100644 --- a/packv4-create.c +++ b/packv4-create.c @@ -19,6 +19,7 @@ static int pack_compression_seen; static int pack_compression_level = Z_DEFAULT_COMPRESSION; +static int min_tree_copy = 1; struct data_entry { unsigned offset; @@ -441,7 +442,7 @@ void *pv4_encode_tree(void *_buffer, unsigned long *sizep, if (!size) return NULL; - if (!delta_size) + if (!delta_size || !min_tree_copy) delta = NULL; /* @@ -530,7 +531,6 @@ void *pv4_encode_tree(void *_buffer, unsigned long *sizep, cp += encode_varint(copy_count, cp); if (first_delta) cp += encode_sha1ref(delta_sha1, cp); - copy_count = 0; /* * Now let's make sure this is going to take less @@ -538,12 +538,14 @@ void *pv4_encode_tree(void *_buffer, unsigned long *sizep, * created in parallel. If so we dump the copy * sequence over those entries in the output buffer. */ - if (cp - copy_buf < out - &buffer[copy_pos]) { + if (copy_count >= min_tree_copy && + cp - copy_buf < out - &buffer[copy_pos]) { out = buffer + copy_pos; memcpy(out, copy_buf, cp - copy_buf); out += cp - copy_buf; first_delta = 0; } + copy_count = 0; } if (end - out < 48) { @@ -574,7 +576,8 @@ void *pv4_encode_tree(void *_buffer, unsigned long *sizep, cp += encode_varint(copy_count, cp); if (first_delta) cp += encode_sha1ref(delta_sha1, cp); - if (cp - copy_buf < out - &buffer[copy_pos]) { + if (copy_count >= min_tree_copy && + cp - copy_buf < out - &buffer[copy_pos]) { out = buffer + copy_pos; memcpy(out, copy_buf, cp - copy_buf); out += cp - copy_buf; @@ -1078,14 +1081,24 @@ static int git_pack_config(const char *k, const char *v, void *cb) int main(int argc, char *argv[]) { - if (argc != 3) { - fprintf(stderr, "Usage: %s <src_packfile> <dst_packfile>\n", argv[0]); + char *src_pack, *dst_pack; + + if (argc == 3) { + src_pack = argv[1]; + dst_pack = argv[2]; + } else if (argc == 4 && !prefixcmp(argv[1], "--min-tree-copy=")) { + min_tree_copy = atoi(argv[1] + strlen("--min-tree-copy=")); + src_pack = argv[2]; + dst_pack = argv[3]; + } else { + fprintf(stderr, "Usage: %s [--min-tree-copy=<n>] <src_packfile> <dst_packfile>\n", argv[0]); exit(1); } + git_config(git_pack_config, NULL); if (!pack_compression_seen && core_compression_seen) pack_compression_level = core_compression_level; - process_one_pack(argv[1], argv[2]); + process_one_pack(src_pack, dst_pack); if (0) dict_dump(); return 0; -- 1.8.4.38.g317e65b -- 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