Class ManagedBufferPool<W extends ManagedBuffer<T>,T extends Buffer>

java.lang.Object
org.jgrapes.io.util.ManagedBufferPool<W,T>
Type Parameters:
W - the type of the wrapped (managed) buffer
T - the type of the content buffer that is wrapped
All Implemented Interfaces:
BufferCollector<W>

public class ManagedBufferPool<W extends ManagedBuffer<T>,T extends Buffer> extends Object implements BufferCollector<W>
A queue based buffer pool.

Using buffers from a pool is an important feature for limiting the computational resources for an IOSubchannel. A producer of Output events that simply creates its own buffers may produce and enqueue a large number of events that are not consumed as fast as they are produced.

Using a buffer pool with a typical size of two synchronizes the producer and the consumers of events nicely. The producer (thread) holds one buffer and fills it, the consumer (thread) holds the other buffer and works with its content. If the producer finishes before the consumer, it has to stop until the consumer has processed previous event and releases the buffer. The consumer can continue without delay, because the data has already been prepared and enqueued as the next event.

One of the biggest problems when using a pool can be to identify leaking buffers, i.e. buffers that are not properly returned to the pool. This implementation therefore tracks all created buffers (with a small overhead) and logs a warning if a buffer is no longer used (referenced) but has not been returned to the pool. If the log level for ManagedBufferPool is set to Level.FINE, the warning also includes a stack trace of the call to acquire() that handed out the buffer. Providing this information in addition obviously requires a larger overhead and is therefore limited to the finer log levels.

  • Field Details

  • Constructor Details

    • ManagedBufferPool

      public ManagedBufferPool(BiFunction<T,BufferCollector<W>,W> wrapper, Supplier<T> bufferFactory, int lowerThreshold, int upperLimit)
      Create a pool that contains a varying number of (wrapped) buffers.

      The pool is initially empty. When buffers are requested and none are left in the pool, new buffers are created up to the given upper limit. Recollected buffers are put in the pool until it holds the number specified by the lower threshold. Any additional recollected buffers are discarded.

      Parameters:
      wrapper - the function that converts buffers to managed buffers
      bufferFactory - a function that creates a new buffer
      lowerThreshold - the number of buffers kept in the pool
      upperLimit - the maximum number of buffers
    • ManagedBufferPool

      public ManagedBufferPool(BiFunction<T,BufferCollector<W>,W> wrapper, Supplier<T> bufferFactory, int buffers)
      Create a pool that keeps up to the given number of (wrapped) buffers in the pool and also uses that number as upper limit.
      Parameters:
      wrapper - the function that converts buffers to managed buffers
      bufferFactory - a function that creates a new buffer
      buffers - the number of buffers
  • Method Details

    • setDefaultDrainDelay

      public static void setDefaultDrainDelay(long delay)
      Sets the default delay after which buffers are removed from the pool.

      The default value is 1500ms.

      Parameters:
      delay - the delay in ms
    • defaultDrainDelay

      public static long defaultDrainDelay()
      Returns the default drain delay.
      Returns:
      the delay
    • setName

      Sets a name for this pool (to be used in status reports).
      Parameters:
      name - the name
      Returns:
      the object for easy chaining
    • name

      public String name()
      Returns the name of this pool.
      Returns:
      the name
    • setDrainDelay

      public ManagedBufferPool<W,T> setDrainDelay(long delay)
      Sets the delay after which buffers are removed from the pool.
      Parameters:
      delay - the delay
      Returns:
      the object for easy chaining
    • bufferSize

      public int bufferSize()
      Returns the size of the buffers managed by this pool.
      Returns:
      the buffer size
    • acquire

      public W acquire() throws InterruptedException
      Acquires a managed buffer from the pool.

      If the pool is empty, waits for a buffer to become available. The acquired buffer has a lock count of one.

      Returns:
      the acquired buffer
      Throws:
      InterruptedException - if the current thread is interrupted
    • recollect

      public void recollect(W buffer)
      Re-adds the buffer to the pool.

      The buffer is cleared.

      Specified by:
      recollect in interface BufferCollector<W extends ManagedBuffer<T>>
      Parameters:
      buffer - the buffer
      See Also:
    • toString

      public String toString()
      Overrides:
      toString in class Object