aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2010-12-07 14:05:40 -0800
committerChris Aniszczyk <caniszczyk@gmail.com>2010-12-08 11:30:11 -0600
commitc181e1ab8ac52ff8ce02f95affc8f79cfbfff323 (patch)
treecb2f2eb7594d00b15c181b93c0a06cf8225f93e7 /org.eclipse.jgit.test
parentbc1130c6aac83a5db0da47fc2cbd25f1a61e3601 (diff)
downloadjgit-c181e1ab8ac52ff8ce02f95affc8f79cfbfff323.tar.gz
jgit-c181e1ab8ac52ff8ce02f95affc8f79cfbfff323.zip
IndexPack: Use streaming for large whole blobs
When indexing large blobs that are stored whole (non-delta form), avoid allocating the entire blob in memory and instead stream it through the SHA-1 checksum computation. This reduces the size of memory required by IndexPack when processing very big blobs, such as a 500 MiB uncompressable binary. If the large blob already exists in the local repository, its contents needs to be compared byte-for-byte after the entire pack has been indexed, to ensure there isn't an unexpected SHA-1 collision which may result in later data corruption. This compare is performed as a streaming compare, again avoiding the large object allocation. This change doesn't improve on memory utilization for large objects stored as deltas. The change also doesn't improve handling for any large commits, trees or annotated tags. There isn't much to be done here for those objects, because they need to be passed down to the ObjectChecker as a byte[]. Fortunately it isn't common for these object types to be that large, Bug: 312868 Change-Id: I862afd4cb78013ee033d4ec68c067b1774a05be8 Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com> CC: Roberto Tyley <roberto.tyley@guardian.co.uk>
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java20
1 files changed, 20 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java
index 110804f91a..6015428d99 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java
@@ -58,6 +58,7 @@ import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.revwalk.RevBlob;
@@ -151,6 +152,25 @@ public class IndexPackTest extends RepositoryTestCase {
ip.renameAndOpenPack();
}
+ public void testPackWithDuplicateBlob() throws Exception {
+ final byte[] data = Constants.encode("0123456789abcdefg");
+ TestRepository<Repository> d = new TestRepository<Repository>(db);
+ assertTrue(db.hasObject(d.blob(data)));
+
+ TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
+ packHeader(pack, 1);
+ pack.write((Constants.OBJ_BLOB) << 4 | 0x80 | 1);
+ pack.write(1);
+ deflate(pack, data);
+ digest(pack);
+
+ final byte[] raw = pack.toByteArray();
+ IndexPack ip = IndexPack.create(db, new ByteArrayInputStream(raw));
+ ip.setStreamFileThreshold(1);
+ ip.index(NullProgressMonitor.INSTANCE);
+ ip.renameAndOpenPack();
+ }
+
private void packHeader(TemporaryBuffer.Heap tinyPack, int cnt)
throws IOException {
final byte[] hdr = new byte[8];