]> source.dussan.org Git - jgit.git/commit
Support cutting existing delta chains longer than the max depth 85/11685/1
authorShawn Pearce <spearce@spearce.org>
Fri, 5 Apr 2013 17:02:01 +0000 (10:02 -0700)
committerShawn Pearce <spearce@spearce.org>
Fri, 5 Apr 2013 17:07:14 +0000 (10:07 -0700)
commit5d446f410d7044fba165ad3deee7ac83864f0e96
treec96dae3e2552233a4ea392c398608fe81c690642
parent01a0699acc09bc10646411bdd7cd1cf8004f7d65
Support cutting existing delta chains longer than the max depth

Some packs built by JGit have incredibly long delta chains due to a
long standing bug in PackWriter. Google has packs created by JGit's
DfsGarbageCollector with chains of 6000 objects long, or more.

Inflating objects at the end of this 6000 long chain is impossible
to complete within a reasonable time bound. It could take a beefy
system hours to perform even using the heavily optimized native C
implementation of Git, let alone with JGit.

Enable pack.cutDeltaChains to be set in a configuration file to
permit the PackWriter to determine the length of each delta chain
and clip the chain at arbitrary points to fit within pack.depth.

Delta chain cycles are still possible, but no attempt is made to
detect them. A trivial chain of A->B->A will iterate for the full
pack.depth configured limit (e.g. 50) and then pick an object to
store as non-delta.

When cutting chains the object list is walked in reverse to try
and take advantage of existing chain computations. The assumption
here is most deltas are near the end of the list, and their bases
are near the front of the list. Going up from the tail attempts to
reuse chainLength computations by relying on the memoized value in
the delta base.

The chainLength field in ObjectToPack is overloaded into the depth
field normally used by DeltaWindow. This is acceptable because the
chain cut happens before delta search, and the chainLength is reset
to 0 if delta search will follow.

Change-Id: Ida4fde9558f3abbbb77ade398d2af3941de9c812
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/ObjectToPack.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java