From 746ebda381b10a3dffa0b2fd83c4e5dd8585844f Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Fri, 20 Aug 2010 09:25:47 -0700 Subject: [PATCH] Try really hard to load a commit or tag When we need the canonical form of a commit or a tag in order to parse it into our RevCommit or RevTag fields, we really need it as a single contiguous byte array. However the ObjectDatabase may choose to give us a large loader. In general commits or tags are always under the several MiB limit, so even if the loader calls it "large" we should still be able to afford the JVM heap memory required to get a single byte array. Coerce even large loaders into a single byte array anyway. Change-Id: I04efbaa7b31c5f4b0a68fc074821930b1132cfcf Signed-off-by: Shawn O. Pearce --- .../org/eclipse/jgit/revwalk/RevObject.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java index 85191224df..b31bc37687 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevObject.java @@ -47,15 +47,39 @@ import java.io.IOException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.LargeObjectException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectLoader; +import org.eclipse.jgit.lib.ObjectStream; +import org.eclipse.jgit.util.IO; /** Base object type accessed during revision walking. */ public abstract class RevObject extends ObjectId { static final int PARSED = 1; + static byte[] asByteArray(RevObject obj, ObjectLoader loader) throws IOException { + if (loader.isLarge()) { + ObjectStream in = loader.openStream(); + try { + long sz = in.getSize(); + if (Integer.MAX_VALUE <= sz){ + if (obj != null) + throw new LargeObjectException(obj.copy()); + throw new LargeObjectException(); + } + byte[] buf = new byte[(int) sz]; + IO.readFully(in, buf, 0, buf.length); + return buf; + } finally { + in.close(); + } + } + return loader.getCachedBytes(); + } + int flags; RevObject(final AnyObjectId name) { @@ -77,7 +101,7 @@ public abstract class RevObject extends ObjectId { final byte[] loadCanonical(final RevWalk walk) throws IOException, MissingObjectException, IncorrectObjectTypeException, CorruptObjectException { - return walk.reader.open(this, getType()).getCachedBytes(); + return asByteArray(this, walk.reader.open(this, getType())); } /** -- 2.39.5