Browse Source

Improve capacity calculcation in DefaultDataBuffer

This commit improves the capacity calculation for the DefaultDataBuffer,
so that the capacity typically doubles instead of improving by the
minimal required amount.

Issue: SPR-15647
pull/1457/merge
Arjen Poutsma 9 years ago
parent
commit
7085a30382
  1. 45
      spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java

45
spring-core/src/main/java/org/springframework/core/io/buffer/DefaultDataBuffer.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -39,6 +39,11 @@ import org.springframework.util.ObjectUtils; @@ -39,6 +39,11 @@ import org.springframework.util.ObjectUtils;
*/
public class DefaultDataBuffer implements DataBuffer {
private static final int MAX_CAPACITY = Integer.MAX_VALUE;
private static final int CAPACITY_THRESHOLD = 1024 * 1024 * 4;
private final DefaultDataBufferFactory dataBufferFactory;
private ByteBuffer byteBuffer;
@ -259,17 +264,45 @@ public class DefaultDataBuffer implements DataBuffer { @@ -259,17 +264,45 @@ public class DefaultDataBuffer implements DataBuffer {
}
private void ensureExtraCapacity(int extraCapacity) {
int neededCapacity = this.writePosition + extraCapacity;
int neededCapacity = calculateCapacity(this.writePosition + extraCapacity);
if (neededCapacity > this.byteBuffer.capacity()) {
grow(neededCapacity);
}
}
void grow(int minCapacity) {
/**
* @see io.netty.buffer.AbstractByteBufAllocator#calculateNewCapacity(int, int)
*/
private int calculateCapacity(int neededCapacity) {
Assert.isTrue(neededCapacity >= 0, "'neededCapacity' must >= 0");
if (neededCapacity == CAPACITY_THRESHOLD) {
return CAPACITY_THRESHOLD;
}
else if (neededCapacity > CAPACITY_THRESHOLD) {
int newCapacity = neededCapacity / CAPACITY_THRESHOLD * CAPACITY_THRESHOLD;
if (newCapacity > MAX_CAPACITY - CAPACITY_THRESHOLD) {
newCapacity = MAX_CAPACITY;
}
else {
newCapacity += CAPACITY_THRESHOLD;
}
return newCapacity;
}
else {
int newCapacity = 64;
while (newCapacity < neededCapacity) {
newCapacity <<= 1;
}
return Math.min(newCapacity, MAX_CAPACITY);
}
}
void grow(int capacity) {
ByteBuffer oldBuffer = this.byteBuffer;
ByteBuffer newBuffer =
(oldBuffer.isDirect() ? ByteBuffer.allocateDirect(minCapacity) :
ByteBuffer.allocate(minCapacity));
(oldBuffer.isDirect() ? ByteBuffer.allocateDirect(capacity) :
ByteBuffer.allocate(capacity));
// Explicit cast for compatibility with covariant return type on JDK 9's ByteBuffer
final int remaining = readableByteCount();
@ -362,7 +395,7 @@ public class DefaultDataBuffer implements DataBuffer { @@ -362,7 +395,7 @@ public class DefaultDataBuffer implements DataBuffer {
}
@Override
void grow(int minCapacity) {
void grow(int capacity) {
throw new UnsupportedOperationException(
"Growing the capacity of a sliced buffer is not supported");
}

Loading…
Cancel
Save