All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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