From: Shawn O. Pearce Date: Fri, 9 Jul 2010 17:10:12 +0000 (-0700) Subject: Allow TemporaryBuffer.Heap to allocate smaller than 8 KiB X-Git-Tag: v0.9.1~157^2~17 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fchanges%2F00%2F1100%2F1;p=jgit.git Allow TemporaryBuffer.Heap to allocate smaller than 8 KiB If the heap limit was set to something smaller than 8 KiB, we were still allocating the full 8 KiB block size, and accepting up to the amount we allocated by. Instead actually put a hard cap on the limit. Change-Id: Id1da26fde2102e76510b1da4ede8493928a981cc Signed-off-by: Shawn O. Pearce --- diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java index 0bcdbcea41..b331f9cf54 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java @@ -255,7 +255,7 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase { } public void testUsingHiddenDeltaBaseFails() throws Exception { - final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64); + final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); packHeader(pack, 1); pack.write((Constants.OBJ_REF_DELTA) << 4 | 4); b.copyRawTo(pack); @@ -297,13 +297,13 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase { // But don't include it in the pack. // - final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64); + final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); packHeader(pack, 2); copy(pack, src.open(N)); copy(pack,src.open(s.parseBody(N).getTree())); digest(pack); - final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256); + final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); final PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' ' + "refs/heads/s" + '\0' @@ -339,13 +339,13 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase { // But don't include it in the pack. // - final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64); + final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); packHeader(pack, 2); copy(pack, src.open(N)); copy(pack,src.open(s.parseBody(N).getTree())); digest(pack); - final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256); + final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); final PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' ' + "refs/heads/s" + '\0' @@ -379,12 +379,12 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase { // Don't include the tree in the pack. // - final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64); + final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024); packHeader(pack, 1); copy(pack, src.open(N)); digest(pack); - final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256); + final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024); final PacketLineOut inPckLine = new PacketLineOut(inBuf); inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' ' + "refs/heads/s" + '\0' diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 101b6056bc..baa45c5c61 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -126,7 +126,7 @@ public abstract class TemporaryBuffer extends OutputStream { blocks.add(s); } - final int n = Math.min(Block.SZ - s.count, len); + final int n = Math.min(s.buffer.length - s.count, len); System.arraycopy(b, off, s.buffer, s.count, n); s.count += n; len -= n; @@ -171,7 +171,7 @@ public abstract class TemporaryBuffer extends OutputStream { blocks.add(s); } - final int n = in.read(s.buffer, s.count, Block.SZ - s.count); + int n = in.read(s.buffer, s.count, s.buffer.length - s.count); if (n < 1) return; s.count += n; @@ -192,8 +192,12 @@ public abstract class TemporaryBuffer extends OutputStream { * @return total length of the buffer, in bytes. */ public long length() { + return inCoreLength(); + } + + private long inCoreLength() { final Block last = last(); - return ((long) blocks.size()) * Block.SZ - (Block.SZ - last.count); + return ((long) blocks.size() - 1) * Block.SZ + last.count; } /** @@ -251,8 +255,13 @@ public abstract class TemporaryBuffer extends OutputStream { if (overflow != null) { destroy(); } - blocks = new ArrayList(inCoreLimit / Block.SZ); - blocks.add(new Block()); + if (inCoreLimit < Block.SZ) { + blocks = new ArrayList(1); + blocks.add(new Block(inCoreLimit)); + } else { + blocks = new ArrayList(inCoreLimit / Block.SZ); + blocks.add(new Block()); + } } /** @@ -270,7 +279,7 @@ public abstract class TemporaryBuffer extends OutputStream { } private boolean reachedInCoreLimit() throws IOException { - if (blocks.size() * Block.SZ < inCoreLimit) + if (inCoreLength() < inCoreLimit) return false; switchToOverflow(); @@ -444,12 +453,20 @@ public abstract class TemporaryBuffer extends OutputStream { static class Block { static final int SZ = 8 * 1024; - final byte[] buffer = new byte[SZ]; + final byte[] buffer; int count; + Block() { + buffer = new byte[SZ]; + } + + Block(int sz) { + buffer = new byte[sz]; + } + boolean isFull() { - return count == SZ; + return count == buffer.length; } } }