Skip to content

Commit

Permalink
Fixes #8810 - ArrayRetainableByteBufferPool inefficiently calculates …
Browse files Browse the repository at this point in the history
…bucket indices

Added constructor that uses IntUnaryOperator to avoid boxing.
Deprecated constructor that uses Function<Integer, Integer>.

Signed-off-by: Simone Bordet <[email protected]>
  • Loading branch information
sbordet committed Nov 10, 2022
1 parent 051588d commit db2d363
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntUnaryOperator;

import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.NanoTime;
Expand Down Expand Up @@ -54,7 +55,7 @@ public class ArrayRetainableByteBufferPool implements RetainableByteBufferPool,
private final long _maxDirectMemory;
private final AtomicLong _currentHeapMemory = new AtomicLong();
private final AtomicLong _currentDirectMemory = new AtomicLong();
private final Function<Integer, Integer> _bucketIndexFor;
private final IntUnaryOperator _bucketIndexFor;

/**
* Creates a new ArrayRetainableByteBufferPool with a default configuration.
Expand Down Expand Up @@ -91,7 +92,7 @@ public ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapacit
*/
public ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
{
this(minCapacity, factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, null, null);
this(minCapacity, factor, maxCapacity, maxBucketSize, null, null, maxHeapMemory, maxDirectMemory);
}

/**
Expand All @@ -105,9 +106,29 @@ public ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapacit
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
* @param bucketIndexFor a {@link Function} that takes a capacity and returns a bucket index
* @param bucketCapacity a {@link Function} that takes a bucket index and returns a capacity
* @deprecated use {@link #ArrayRetainableByteBufferPool(int, int, int, int, IntUnaryOperator, IntUnaryOperator, long, long)}
* instead
*/
@Deprecated
protected ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory,
Function<Integer, Integer> bucketIndexFor, Function<Integer, Integer> bucketCapacity)
{
this(minCapacity, factor, maxCapacity, maxBucketSize, bucketIndexFor::apply, bucketCapacity::apply, maxHeapMemory, maxDirectMemory);
}

/**
* Creates a new ArrayRetainableByteBufferPool with the given configuration.
*
* @param minCapacity the minimum ByteBuffer capacity
* @param factor the capacity factor
* @param maxCapacity the maximum ByteBuffer capacity
* @param maxBucketSize the maximum number of ByteBuffers for each bucket
* @param bucketIndexFor a {@link IntUnaryOperator} that takes a capacity and returns a bucket index
* @param bucketCapacity a {@link IntUnaryOperator} that takes a bucket index and returns a capacity
* @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic
* @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
*/
protected ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, IntUnaryOperator bucketIndexFor, IntUnaryOperator bucketCapacity, long maxHeapMemory, long maxDirectMemory)
{
if (minCapacity <= 0)
minCapacity = 0;
Expand All @@ -123,12 +144,12 @@ protected ArrayRetainableByteBufferPool(int minCapacity, int factor, int maxCapa
if (bucketCapacity == null)
bucketCapacity = i -> (i + 1) * f;

int length = bucketIndexFor.apply(maxCapacity) + 1;
int length = bucketIndexFor.applyAsInt(maxCapacity) + 1;
RetainedBucket[] directArray = new RetainedBucket[length];
RetainedBucket[] indirectArray = new RetainedBucket[length];
for (int i = 0; i < directArray.length; i++)
{
int capacity = Math.min(bucketCapacity.apply(i), maxCapacity);
int capacity = Math.min(bucketCapacity.applyAsInt(i), maxCapacity);
directArray[i] = new RetainedBucket(capacity, maxBucketSize);
indirectArray[i] = new RetainedBucket(capacity, maxBucketSize);
}
Expand Down Expand Up @@ -225,7 +246,7 @@ private RetainedBucket bucketFor(int capacity, boolean direct)
{
if (capacity < _minCapacity)
return null;
int idx = _bucketIndexFor.apply(capacity);
int idx = _bucketIndexFor.applyAsInt(capacity);
RetainedBucket[] buckets = direct ? _direct : _indirect;
if (idx >= buckets.length)
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,11 @@ public LogarithmicRetainablePool(int minCapacity, int maxCapacity, int maxBucket
-1,
maxCapacity,
maxBucketSize,
maxHeapMemory,
maxDirectMemory,
c -> 32 - Integer.numberOfLeadingZeros(c - 1),
i -> 1 << i);
i -> 1 << i,
maxHeapMemory,
maxDirectMemory
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,11 @@ public ExponentialPool(int minCapacity, int maxCapacity, int maxBucketSize, long
-1,
maxCapacity,
maxBucketSize,
maxHeapMemory,
maxDirectMemory,
c -> 32 - Integer.numberOfLeadingZeros(c - 1),
i -> 1 << i);
i -> 1 << i,
maxHeapMemory,
maxDirectMemory
);
}
}

Expand Down

0 comments on commit db2d363

Please sign in to comment.