]> source.dussan.org Git - jgit.git/commitdiff
Allow TemporaryBuffer.Heap to allocate smaller than 8 KiB 00/1100/1
authorShawn O. Pearce <spearce@spearce.org>
Fri, 9 Jul 2010 17:10:12 +0000 (10:10 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Fri, 9 Jul 2010 17:37:47 +0000 (10:37 -0700)
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 <spearce@spearce.org>
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java
org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java

index 0bcdbcea418fa8e6bc8097c9140656ba6534ec1f..b331f9cf54a5201b5a367e9c9e41e0456930a369 100644 (file)
@@ -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'
index 101b6056bccea244436d8f4b694ae996bf8568e2..baa45c5c610a3b4d9b56f967a2f718da0ab9613e 100644 (file)
@@ -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<Block>(inCoreLimit / Block.SZ);
-               blocks.add(new Block());
+               if (inCoreLimit < Block.SZ) {
+                       blocks = new ArrayList<Block>(1);
+                       blocks.add(new Block(inCoreLimit));
+               } else {
+                       blocks = new ArrayList<Block>(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;
                }
        }
 }