unpack-trees: avoid duplicate ODB lookups during checkout
authorJeff Hostetler <jeffhost@microsoft.com>
Fri, 14 Apr 2017 19:25:54 +0000 (19:25 +0000)
committerJunio C Hamano <gitster@pobox.com>
Sat, 15 Apr 2017 09:50:44 +0000 (02:50 -0700)
commitd12a8cf0af18804c2000efc7a0224da631e04cd1
tree2664f50eb8d230c799f6860203b1542769a1d3f1
parent49800c940790cc7465d1b03e08d472ffd8684808
unpack-trees: avoid duplicate ODB lookups during checkout

Teach traverse_trees_recursive() to not do redundant ODB
lookups when both directories refer to the same OID.

In operations such as read-tree and checkout, there will
likely be many peer directories that have the same OID when
the differences between the commits are relatively small.
In these cases we can avoid hitting the ODB multiple times
for the same OID.

This patch handles n=2 and n=3 cases and simply copies the
data rather than repeating the fill_tree_descriptor().

================
On the Windows repo (500K trees, 3.1M files, 450MB index),
this reduced the overall time by 0.75 seconds when cycling
between 2 commits with a single file difference.

(avg) before: 22.699
(avg) after:  21.955
===============

================
On Linux using p0006-read-tree-checkout.sh with linux.git:

Test                                                          HEAD^              HEAD
-------------------------------------------------------------------------------------------------------
0006.2: read-tree br_base br_ballast (57994)                  0.24(0.20+0.03)    0.24(0.22+0.01) +0.0%
0006.3: switch between br_base br_ballast (57994)             10.58(6.23+2.86)   10.67(5.94+2.87) +0.9%
0006.4: switch between br_ballast br_ballast_plus_1 (57994)   0.60(0.44+0.17)    0.57(0.44+0.14) -5.0%
0006.5: switch between aliases (57994)                        0.59(0.48+0.13)    0.57(0.44+0.15) -3.4%
================

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
unpack-trees.c