![JAR search and dependency download from the Maven repository](/logo.png)
io.hyperfoil.core.impl.ElasticPoolImpl Maven / Gradle / Ivy
package io.hyperfoil.core.impl;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Supplier;
import io.hyperfoil.api.collection.ElasticPool;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
public class ElasticPoolImpl implements ElasticPool {
private Logger log = LoggerFactory.getLogger(ElasticPoolImpl.class);
private final Supplier initSupplier;
private final Supplier depletionSupplier;
private BlockingQueue primaryQueue;
private final BlockingQueue secondaryQueue = new LinkedBlockingQueue<>();
private final LongAdder used = new LongAdder();
private int minUsed = Integer.MAX_VALUE, maxUsed;
public ElasticPoolImpl(Supplier initSupplier, Supplier depletionSupplier) {
this.initSupplier = initSupplier;
this.depletionSupplier = depletionSupplier;
}
@Override
public T acquire() {
T object = primaryQueue.poll();
if (object != null) {
used.increment();
long currentlyUsed = used.longValue();
if (currentlyUsed > maxUsed) {
maxUsed = (int) currentlyUsed;
}
return object;
}
secondaryQueue.drainTo(primaryQueue, primaryQueue.remainingCapacity());
object = primaryQueue.poll();
if (object != null) {
used.increment();
return object;
}
return depletionSupplier.get();
}
@Override
public void release(T object) {
used.decrement();
long currentlyUsed = used.longValue();
if (currentlyUsed < minUsed) {
minUsed = (int) currentlyUsed;
}
if (primaryQueue.offer(object)) {
return;
}
secondaryQueue.add(object);
}
@Override
public void reserve(int capacity) {
if (primaryQueue == null || primaryQueue.size() < capacity) {
primaryQueue = new ArrayBlockingQueue<>(capacity);
}
while (primaryQueue.size() < capacity) {
primaryQueue.add(initSupplier.get());
}
}
@Override
public void forEach(Consumer consumer) {
if (primaryQueue.remainingCapacity() < secondaryQueue.size()) {
BlockingQueue newQueue = new ArrayBlockingQueue<>(primaryQueue.size() + secondaryQueue.size());
primaryQueue.drainTo(newQueue);
primaryQueue = newQueue;
}
secondaryQueue.drainTo(primaryQueue, primaryQueue.remainingCapacity());
assert secondaryQueue.isEmpty();
primaryQueue.forEach(consumer);
}
@Override
public int minUsed() {
return minUsed;
}
@Override
public int maxUsed() {
return maxUsed;
}
@Override
public void resetStats() {
minUsed = Integer.MAX_VALUE;
maxUsed = 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy