Class RingBuffer<T>


  • public class RingBuffer<T>
    extends java.lang.Object
    Ring buffer of fixed capacity designed for multiple writers but only a single reader. Advancing the read or write index blocks until it is possible to do so.
    Since:
    4.0
    Author:
    Bela Ban
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected T[] buf  
      protected int count  
      protected java.util.concurrent.locks.Lock lock  
      protected java.util.concurrent.locks.Condition not_empty  
      protected java.util.concurrent.locks.Condition not_full  
      protected int ri  
      protected int wi  
    • Constructor Summary

      Constructors 
      Constructor Description
      RingBuffer​(java.lang.Class<T> element_type)  
      RingBuffer​(java.lang.Class<T> element_type, int capacity)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void _waitForMessages()  
      T[] buf()  
      int capacity()  
      RingBuffer<T> clear()  
      int countLockLockless()  
      int drainTo​(java.util.Collection<? super T> c)
      Removes as many messages as possible and adds them to c.
      int drainTo​(java.util.Collection<? super T> c, int max_elements)
      Removes a number of messages and adds them to c.
      int drainTo​(T[] c)
      Removes messages and adds them to c.
      int drainToBlocking​(java.util.Collection<? super T> c)
      Removes as many messages as possible and adds them to c.
      int drainToBlocking​(java.util.Collection<? super T> c, int max_elements)
      Removes a number of messages and adds them to c.
      int drainToBlocking​(T[] c)
      Removes messages and adds them to c.
      boolean isEmpty()  
      RingBuffer<T> publishReadIndex​(int num_elements_read)  
      RingBuffer<T> put​(T element)
      Tries to add a new element at the current write index and advances the write index.
      int readIndex()  
      int readIndexLockless()  
      protected int realIndex​(int index)
      Apparently much more efficient than mod (%)
      int size()  
      T take()
      Removes the next available element, blocking until one is available (if needed).
      java.lang.String toString()  
      int waitForMessages()
      Blocks until messages are available
      int waitForMessages​(int num_spins, java.util.function.BiConsumer<java.lang.Integer,​java.lang.Integer> wait_strategy)
      Blocks until messages are available
      int writeIndex()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • buf

        protected final T[] buf
      • ri

        protected int ri
      • wi

        protected int wi
      • count

        protected int count
      • lock

        protected final java.util.concurrent.locks.Lock lock
      • not_empty

        protected final java.util.concurrent.locks.Condition not_empty
      • not_full

        protected final java.util.concurrent.locks.Condition not_full
    • Constructor Detail

      • RingBuffer

        public RingBuffer​(java.lang.Class<T> element_type)
      • RingBuffer

        public RingBuffer​(java.lang.Class<T> element_type,
                          int capacity)
    • Method Detail

      • buf

        public T[] buf()
      • capacity

        public int capacity()
      • readIndexLockless

        public int readIndexLockless()
      • countLockLockless

        public int countLockLockless()
      • readIndex

        public int readIndex()
      • writeIndex

        public int writeIndex()
      • size

        public int size()
      • isEmpty

        public boolean isEmpty()
      • put

        public RingBuffer<T> put​(T element)
                          throws java.lang.InterruptedException
        Tries to add a new element at the current write index and advances the write index. If the write index is at the same position as the read index, this will block until the read index is advanced.
        Parameters:
        element - the element to be added. Must not be null, or else this operation returns immediately
        Throws:
        java.lang.InterruptedException
      • take

        public T take()
               throws java.lang.InterruptedException
        Removes the next available element, blocking until one is available (if needed).
        Returns:
        The next available element
        Throws:
        java.lang.InterruptedException
      • drainTo

        public int drainTo​(java.util.Collection<? super T> c)
        Removes as many messages as possible and adds them to c. Same semantics as BlockingQueue.drainTo(Collection).
        Parameters:
        c - The collection to which to add the removed messages.
        Returns:
        The number of messages removed
        Throws:
        java.lang.NullPointerException - If c is null
      • drainToBlocking

        public int drainToBlocking​(java.util.Collection<? super T> c)
                            throws java.lang.InterruptedException
        Removes as many messages as possible and adds them to c. Contrary to drainTo(Collection), this method blocks until at least one message is available, or the caller thread is interrupted.
        Parameters:
        c - The collection to which to add the removed messages.
        Returns:
        The number of messages removed
        Throws:
        java.lang.NullPointerException - If c is null
        java.lang.InterruptedException
      • drainTo

        public int drainTo​(java.util.Collection<? super T> c,
                           int max_elements)
        Removes a number of messages and adds them to c. Same semantics as BlockingQueue.drainTo(Collection,int).
        Parameters:
        c - The collection to which to add the removed messages.
        max_elements - The max number of messages to remove. The actual number of messages removed may be smaller if the buffer has fewer elements
        Returns:
        The number of messages removed
        Throws:
        java.lang.NullPointerException - If c is null
      • drainToBlocking

        public int drainToBlocking​(java.util.Collection<? super T> c,
                                   int max_elements)
                            throws java.lang.InterruptedException
        Removes a number of messages and adds them to c. Contrary to drainTo(Collection,int), this method blocks until at least one message is available, or the caller thread is interrupted.
        Parameters:
        c - The collection to which to add the removed messages.
        max_elements - The max number of messages to remove. The actual number of messages removed may be smaller if the buffer has fewer elements
        Returns:
        The number of messages removed
        Throws:
        java.lang.NullPointerException - If c is null
        java.lang.InterruptedException
      • drainTo

        public int drainTo​(T[] c)
        Removes messages and adds them to c.
        Parameters:
        c - The array to add messages to.
        Returns:
        The number of messages removed and added to c. This is min(count, c.length). If no messages are present, this method returns immediately
      • drainToBlocking

        public int drainToBlocking​(T[] c)
                            throws java.lang.InterruptedException
        Removes messages and adds them to c.
        Parameters:
        c - The array to add messages to.
        Returns:
        The number of messages removed and added to c. This is min(count, c.length). Contrary to drainTo(Object[]), this method blocks until at least one message is available or the caller thread is interrupted.
        Throws:
        java.lang.InterruptedException
      • publishReadIndex

        public RingBuffer<T> publishReadIndex​(int num_elements_read)
      • waitForMessages

        public int waitForMessages()
                            throws java.lang.InterruptedException
        Blocks until messages are available
        Throws:
        java.lang.InterruptedException
      • waitForMessages

        public int waitForMessages​(int num_spins,
                                   java.util.function.BiConsumer<java.lang.Integer,​java.lang.Integer> wait_strategy)
                            throws java.lang.InterruptedException
        Blocks until messages are available
        Parameters:
        num_spins - the number of times we should spin before acquiring a lock
        wait_strategy - the strategy used to spin. The first parameter is the iteration count and the second parameter is the max number of spins
        Throws:
        java.lang.InterruptedException
      • _waitForMessages

        public void _waitForMessages()
                              throws java.lang.InterruptedException
        Throws:
        java.lang.InterruptedException
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • realIndex

        protected int realIndex​(int index)
        Apparently much more efficient than mod (%)