Skip to content

Commit

Permalink
#12689 add no-bucket acquire statistics
Browse files Browse the repository at this point in the history
Signed-off-by: Ludovic Orban <[email protected]>
  • Loading branch information
lorban committed Jan 9, 2025
1 parent d477ef8 commit 81c66a9
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicBoolean;
Expand All @@ -40,6 +41,7 @@
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.component.DumpableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -65,7 +67,10 @@ public class ArrayByteBufferPool implements ByteBufferPool, Dumpable
private final long _maxHeapMemory;
private final long _maxDirectMemory;
private final IntUnaryOperator _bucketIndexFor;
private final IntUnaryOperator _bucketCapacity;
private final AtomicBoolean _evictor = new AtomicBoolean(false);
private final ConcurrentMap<Integer, Long> _noBucketDirectSizes = new ConcurrentHashMap<>();
private final ConcurrentMap<Integer, Long> _noBucketIndirectSizes = new ConcurrentHashMap<>();
private boolean _statisticsEnabled;

/**
Expand Down Expand Up @@ -164,6 +169,7 @@ protected ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int
_maxHeapMemory = maxMemory(maxHeapMemory);
_maxDirectMemory = maxMemory(maxDirectMemory);
_bucketIndexFor = bucketIndexFor;
_bucketCapacity = bucketCapacity;
}

private long maxMemory(long maxMemory)
Expand Down Expand Up @@ -205,7 +211,10 @@ public RetainableByteBuffer acquire(int size, boolean direct)

// No bucket, return non-pooled.
if (bucket == null)
{
recordNoBucketAcquire(size, direct);
return RetainableByteBuffer.wrap(BufferUtil.allocate(size, direct));
}

bucket.recordAcquire();

Expand All @@ -223,6 +232,22 @@ public RetainableByteBuffer acquire(int size, boolean direct)
return buffer;
}

private void recordNoBucketAcquire(int size, boolean direct)
{
if (isStatisticsEnabled())
{
ConcurrentMap<Integer, Long> map = direct ? _noBucketDirectSizes : _noBucketIndirectSizes;
int idx = _bucketIndexFor.applyAsInt(size);
int key = _bucketCapacity.applyAsInt(idx);
map.compute(key, (k, v) ->
{
if (v == null)
return 1L;
return v + 1L;
});
}
}

@Override
public boolean removeAndRelease(RetainableByteBuffer buffer)
{
Expand Down Expand Up @@ -427,7 +452,9 @@ public long getAvailableHeapMemory()
public void clear()
{
clearBuckets(_direct);
_noBucketDirectSizes.clear();
clearBuckets(_indirect);
_noBucketIndirectSizes.clear();
}

private void clearBuckets(RetainedBucket[] buckets)
Expand All @@ -446,7 +473,10 @@ public void dump(Appendable out, String indent) throws IOException
indent,
this,
DumpableCollection.fromArray("direct", _direct),
DumpableCollection.fromArray("indirect", _indirect));
new DumpableMap("direct non-pooled acquisitions", _noBucketDirectSizes),
DumpableCollection.fromArray("indirect", _indirect),
new DumpableMap("indirect non-pooled acquisitions", _noBucketIndirectSizes)
);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.junit.jupiter.api.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.lessThan;
Expand All @@ -38,6 +39,30 @@

public class ArrayByteBufferPoolTest
{
@Test
public void testDump()
{
ArrayByteBufferPool pool = new ArrayByteBufferPool(0, 10, 100, Integer.MAX_VALUE, 200, 200);
pool.setStatisticsEnabled(true);

List<RetainableByteBuffer> buffers = new ArrayList<>();

for (int i = 1; i < 151; i++)
buffers.add(pool.acquire(i, true));

buffers.forEach(RetainableByteBuffer::release);

String dump = pool.dump();
assertThat(dump, containsString("direct non-pooled acquisitions size=5\n"));
assertThat(dump, containsString("110: 10\n"));
assertThat(dump, containsString("120: 10\n"));
assertThat(dump, containsString("130: 10\n"));
assertThat(dump, containsString("140: 10\n"));
assertThat(dump, containsString("150: 10\n"));
pool.clear();
assertThat(pool.dump(), containsString("direct non-pooled acquisitions size=0\n"));
}

@Test
public void testMaxMemoryEviction()
{
Expand Down

0 comments on commit 81c66a9

Please sign in to comment.