Re-create allocations tester
This commit is contained in:
parent
851f73481a
commit
0ca6f4c2c5
12
pom.xml
12
pom.xml
@ -101,7 +101,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
<version>5.8.0-M1</version>
|
<version>5.8.2</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
<exclusion>
|
<exclusion>
|
||||||
<groupId>org.hamcrest</groupId>
|
<groupId>org.hamcrest</groupId>
|
||||||
@ -112,12 +112,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>5.8.0-M1</version>
|
<version>5.8.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-params</artifactId>
|
<artifactId>junit-jupiter-params</artifactId>
|
||||||
<version>5.8.0-M1</version>
|
<version>5.8.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- This will get hamcrest-core automatically -->
|
<!-- This will get hamcrest-core automatically -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -184,6 +184,7 @@
|
|||||||
<groupId>org.apache.lucene</groupId>
|
<groupId>org.apache.lucene</groupId>
|
||||||
<artifactId>lucene-test-framework</artifactId>
|
<artifactId>lucene-test-framework</artifactId>
|
||||||
<version>9.0.0</version>
|
<version>9.0.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
@ -534,7 +535,7 @@
|
|||||||
<annotationProcessorPath>
|
<annotationProcessorPath>
|
||||||
<groupId>io.soabase.record-builder</groupId>
|
<groupId>io.soabase.record-builder</groupId>
|
||||||
<artifactId>record-builder-processor</artifactId>
|
<artifactId>record-builder-processor</artifactId>
|
||||||
<version>32</version>
|
<version>33</version>
|
||||||
</annotationProcessorPath>
|
</annotationProcessorPath>
|
||||||
</annotationProcessorPaths>
|
</annotationProcessorPaths>
|
||||||
<annotationProcessors>
|
<annotationProcessors>
|
||||||
@ -583,10 +584,11 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-engine</artifactId>
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
<version>5.8.0-M1</version>
|
<version>5.8.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<useModulePath>false</useModulePath>
|
||||||
<argLine>--add-modules jdk.incubator.foreign -Dforeign.restricted=permit --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --enable-native-access=ALL-UNNAMED</argLine>
|
<argLine>--add-modules jdk.incubator.foreign -Dforeign.restricted=permit --add-opens=java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --enable-native-access=ALL-UNNAMED</argLine>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
<property>
|
||||||
|
@ -6,12 +6,15 @@ import java.lang.invoke.MethodHandle;
|
|||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Netty5 hides some metrics. This utility class can read them.
|
* Netty5 hides some metrics. This utility class can read them.
|
||||||
*/
|
*/
|
||||||
public class MetricUtils {
|
public class MetricUtils {
|
||||||
|
|
||||||
|
private static final Logger LOG = LogManager.getLogger(MetricUtils.class);
|
||||||
private static final MethodHandle GET_ARENA_METRICS;
|
private static final MethodHandle GET_ARENA_METRICS;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -24,12 +27,16 @@ public class MetricUtils {
|
|||||||
var pooledBufferClass = Class.forName("io.netty5.buffer.api.pool.PooledBufferAllocatorMetric");
|
var pooledBufferClass = Class.forName("io.netty5.buffer.api.pool.PooledBufferAllocatorMetric");
|
||||||
// Find the handle of the method
|
// Find the handle of the method
|
||||||
handle = lookup.findVirtual(pooledBufferClass, "arenaMetrics", MethodType.methodType(List.class));
|
handle = lookup.findVirtual(pooledBufferClass, "arenaMetrics", MethodType.methodType(List.class));
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException ignored) {
|
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException ex) {
|
||||||
|
logMetricsNotAccessible(ex);
|
||||||
}
|
}
|
||||||
GET_ARENA_METRICS = handle;
|
GET_ARENA_METRICS = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void logMetricsNotAccessible(Throwable ex) {
|
||||||
|
LOG.debug("Failed to open pooled buffer allocator metrics", ex);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the metrics of each pool arena of a pooled allocator
|
* Get the metrics of each pool arena of a pooled allocator
|
||||||
* @param allocator Pooled allocator
|
* @param allocator Pooled allocator
|
||||||
|
@ -15,6 +15,8 @@ module dbengine {
|
|||||||
exports it.cavallium.dbengine.client.query;
|
exports it.cavallium.dbengine.client.query;
|
||||||
exports it.cavallium.dbengine.database.memory;
|
exports it.cavallium.dbengine.database.memory;
|
||||||
exports it.cavallium.dbengine.netty;
|
exports it.cavallium.dbengine.netty;
|
||||||
|
opens it.cavallium.dbengine.database.remote;
|
||||||
|
exports it.cavallium.dbengine;
|
||||||
requires org.jetbrains.annotations;
|
requires org.jetbrains.annotations;
|
||||||
requires reactor.core;
|
requires reactor.core;
|
||||||
requires com.google.common;
|
requires com.google.common;
|
||||||
@ -35,6 +37,8 @@ module dbengine {
|
|||||||
requires java.compiler;
|
requires java.compiler;
|
||||||
requires org.apache.lucene.analysis.common;
|
requires org.apache.lucene.analysis.common;
|
||||||
requires org.apache.lucene.misc;
|
requires org.apache.lucene.misc;
|
||||||
|
requires org.apache.lucene.codecs;
|
||||||
|
requires org.apache.lucene.backward_codecs;
|
||||||
requires lucene.relevance;
|
requires lucene.relevance;
|
||||||
requires io.netty.buffer;
|
requires io.netty.buffer;
|
||||||
requires io.netty.transport;
|
requires io.netty.transport;
|
||||||
@ -49,5 +53,4 @@ module dbengine {
|
|||||||
requires io.netty.incubator.codec.classes.quic;
|
requires io.netty.incubator.codec.classes.quic;
|
||||||
requires org.apache.lucene.queryparser;
|
requires org.apache.lucene.queryparser;
|
||||||
requires reactor.netty.incubator.quic;
|
requires reactor.netty.incubator.quic;
|
||||||
|
|
||||||
}
|
}
|
@ -41,10 +41,10 @@ public class DbTestUtils {
|
|||||||
return "0123456789".repeat(1024);
|
return "0123456789".repeat(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
public record TestAllocator(PooledBufferAllocator allocator) {}
|
public record TestAllocator(TestAllocatorImpl allocator) {}
|
||||||
|
|
||||||
public static TestAllocator newAllocator() {
|
public static TestAllocator newAllocator() {
|
||||||
return new TestAllocator(new PooledBufferAllocator(MemoryManager.instance(), true, 1, 8192, 9, 0, 0, true));
|
return new TestAllocator(TestAllocatorImpl.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void destroyAllocator(TestAllocator testAllocator) {
|
public static void destroyAllocator(TestAllocator testAllocator) {
|
||||||
@ -52,20 +52,10 @@ public class DbTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
@SuppressWarnings("SameParameterValue")
|
||||||
private static long getActiveAllocations(PooledBufferAllocator allocator, boolean printStats) {
|
private static long getActiveAllocations(TestAllocatorImpl allocator, boolean printStats) {
|
||||||
allocator.trimCurrentThreadCache();
|
long activeAllocations = allocator.getActiveAllocations();
|
||||||
var metrics = MetricUtils.getPoolArenaMetrics(allocator);
|
|
||||||
int allocations = 0;
|
|
||||||
int deallocations = 0;
|
|
||||||
int activeAllocations = 0;
|
|
||||||
for (PoolArenaMetric metric : metrics) {
|
|
||||||
allocations += metric.numAllocations();
|
|
||||||
deallocations += metric.numDeallocations();
|
|
||||||
activeAllocations += metric.numActiveAllocations();
|
|
||||||
}
|
|
||||||
if (printStats) {
|
if (printStats) {
|
||||||
System.out.println("allocations=" + allocations + ", deallocations=" + deallocations
|
System.out.println("activeAllocations=" + activeAllocations);
|
||||||
+ ", activeAllocations=" + activeAllocations);
|
|
||||||
}
|
}
|
||||||
return activeAllocations;
|
return activeAllocations;
|
||||||
}
|
}
|
||||||
@ -102,7 +92,7 @@ public class DbTestUtils {
|
|||||||
return canUse;
|
return canUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ensureNoLeaks(PooledBufferAllocator allocator, boolean printStats, boolean useClassicException) {
|
public static void ensureNoLeaks(TestAllocatorImpl allocator, boolean printStats, boolean useClassicException) {
|
||||||
if (allocator != null) {
|
if (allocator != null) {
|
||||||
var allocs = getActiveAllocations(allocator, printStats);
|
var allocs = getActiveAllocations(allocator, printStats);
|
||||||
if (useClassicException) {
|
if (useClassicException) {
|
||||||
@ -203,7 +193,7 @@ public class DbTestUtils {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U> DatabaseMapDictionaryHashed<String, String, Integer> tempDatabaseMapDictionaryHashMap(
|
public static DatabaseMapDictionaryHashed<String, String, Integer> tempDatabaseMapDictionaryHashMap(
|
||||||
LLDictionary dictionary) {
|
LLDictionary dictionary) {
|
||||||
return DatabaseMapDictionaryHashed.simple(dictionary,
|
return DatabaseMapDictionaryHashed.simple(dictionary,
|
||||||
Serializer.UTF8_SERIALIZER,
|
Serializer.UTF8_SERIALIZER,
|
||||||
|
144
src/test/java/it/cavallium/dbengine/TestAllocatorImpl.java
Normal file
144
src/test/java/it/cavallium/dbengine/TestAllocatorImpl.java
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
package it.cavallium.dbengine;
|
||||||
|
|
||||||
|
import static io.netty5.buffer.api.internal.Statics.allocatorClosedException;
|
||||||
|
import static io.netty5.buffer.api.internal.Statics.standardDrop;
|
||||||
|
|
||||||
|
import io.netty5.buffer.api.AllocationType;
|
||||||
|
import io.netty5.buffer.api.AllocatorControl;
|
||||||
|
import io.netty5.buffer.api.Buffer;
|
||||||
|
import io.netty5.buffer.api.BufferAllocator;
|
||||||
|
import io.netty5.buffer.api.Drop;
|
||||||
|
import io.netty5.buffer.api.MemoryManager;
|
||||||
|
import io.netty5.buffer.api.StandardAllocationTypes;
|
||||||
|
import io.netty5.buffer.api.internal.Statics;
|
||||||
|
import io.netty5.buffer.api.pool.PooledBufferAllocator;
|
||||||
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class TestAllocatorImpl implements BufferAllocator, AllocatorControl {
|
||||||
|
|
||||||
|
private final TestMemoryManager manager;
|
||||||
|
private final AllocationType allocationType = StandardAllocationTypes.ON_HEAP;
|
||||||
|
private volatile boolean closed;
|
||||||
|
|
||||||
|
private TestAllocatorImpl(TestMemoryManager testMemoryManager) {
|
||||||
|
this.manager = testMemoryManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TestAllocatorImpl create() {
|
||||||
|
return new TestAllocatorImpl(new TestMemoryManager(MemoryManager.instance()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPooling() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AllocationType getAllocationType() {
|
||||||
|
return allocationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buffer allocate(int size) {
|
||||||
|
if (closed) {
|
||||||
|
throw allocatorClosedException();
|
||||||
|
}
|
||||||
|
Statics.assertValidBufferSize(size);
|
||||||
|
return manager.allocateShared(this, size, Statics.standardDrop(manager), allocationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Supplier<Buffer> constBufferSupplier(byte[] bytes) {
|
||||||
|
if (closed) {
|
||||||
|
throw allocatorClosedException();
|
||||||
|
}
|
||||||
|
Buffer constantBuffer = manager.allocateShared(
|
||||||
|
this, bytes.length, standardDrop(manager), allocationType);
|
||||||
|
constantBuffer.writeBytes(bytes).makeReadOnly();
|
||||||
|
return () -> manager.allocateConstChild(constantBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
closed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getActiveAllocations() {
|
||||||
|
return this.manager.getActiveAllocations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BufferAllocator getAllocator() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestMemoryManager implements MemoryManager {
|
||||||
|
|
||||||
|
private final MemoryManager instance;
|
||||||
|
private final LongAdder activeAllocations = new LongAdder();
|
||||||
|
|
||||||
|
public TestMemoryManager(MemoryManager instance) {
|
||||||
|
this.instance = instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buffer allocateShared(AllocatorControl allocatorControl,
|
||||||
|
long size,
|
||||||
|
Function<Drop<Buffer>, Drop<Buffer>> dropDecorator,
|
||||||
|
AllocationType allocationType) {
|
||||||
|
return instance.allocateShared(allocatorControl, size, this::createDrop, allocationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buffer allocateConstChild(Buffer readOnlyConstParent) {
|
||||||
|
return instance.allocateConstChild(readOnlyConstParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object unwrapRecoverableMemory(Buffer buf) {
|
||||||
|
return instance.unwrapRecoverableMemory(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Buffer recoverMemory(AllocatorControl allocatorControl, Object recoverableMemory, Drop<Buffer> drop) {
|
||||||
|
return instance.recoverMemory(allocatorControl, recoverableMemory, drop);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object sliceMemory(Object memory, int offset, int length) {
|
||||||
|
return instance.sliceMemory(memory, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String implementationName() {
|
||||||
|
return instance.implementationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drop<Buffer> createDrop(Drop<Buffer> drop) {
|
||||||
|
activeAllocations.increment();
|
||||||
|
return new Drop<>() {
|
||||||
|
@Override
|
||||||
|
public void drop(Buffer obj) {
|
||||||
|
activeAllocations.decrement();
|
||||||
|
drop.drop(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Drop<Buffer> fork() {
|
||||||
|
return createDrop(drop.fork());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void attach(Buffer obj) {
|
||||||
|
drop.attach(obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getActiveAllocations() {
|
||||||
|
return activeAllocations.longValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user