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 <spearce@spearce.org>
This commit is contained in:
parent
711bd3e3d0
commit
97311cd3e0
|
@ -255,7 +255,7 @@ public void testCreateBranchAtHiddenCommitFails() throws Exception {
|
|||
}
|
||||
|
||||
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 void testUsingHiddenCommonBlobFails() throws Exception {
|
|||
|
||||
// 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 void testUsingUnknownBlobFails() throws Exception {
|
|||
|
||||
// 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 void testUsingUnknownTreeFails() throws Exception {
|
|||
|
||||
// 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'
|
||||
|
|
|
@ -126,7 +126,7 @@ public void write(final byte[] b, int off, int len) throws IOException {
|
|||
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 void copy(final InputStream in) throws IOException {
|
|||
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 void copy(final InputStream in) throws IOException {
|
|||
* @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 void reset() {
|
|||
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 @@ private Block last() {
|
|||
}
|
||||
|
||||
private boolean reachedInCoreLimit() throws IOException {
|
||||
if (blocks.size() * Block.SZ < inCoreLimit)
|
||||
if (inCoreLength() < inCoreLimit)
|
||||
return false;
|
||||
|
||||
switchToOverflow();
|
||||
|
@ -444,12 +453,20 @@ protected OutputStream overflow() throws IOException {
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue