public class LFRingbuffer<T> extends Object implements Ringbuffer<T>
Ringbuffer
,
exposing lock-free
get*(..)
and put*(..)
methods.
Implementation utilizes the Always Keep One Slot Open,
hence implementation maintains an internal array of capacity
plus one!
Implementation is thread safe if:
get*(..)
operations are performed from one thread only.put*(..)
operations are performed from one thread only.get*(..)
and put*(..)
thread may be the same.Following methods utilize global synchronization:
User needs to synchronize above methods w/ the lock-free w/get*(..)
and put*(..)
methods,
e.g. by controlling their threads before invoking the above.
Characteristics:
Empty | writePos == readPos | size == 0 |
Full | writePos == readPos - 1 | size == capacity |
Constructor and Description |
---|
LFRingbuffer(Class<? extends T[]> arrayType,
int capacity)
Create an empty ring buffer instance w/ the given net
capacity . |
LFRingbuffer(T[] copyFrom)
Create a full ring buffer instance w/ the given array's net capacity and content.
|
Modifier and Type | Method and Description |
---|---|
int |
capacity()
Returns the net capacity of this ring buffer.
|
void |
clear()
Resets the read and write position according to an empty ring buffer
and set all ring buffer slots to
null . |
void |
dump(PrintStream stream,
String prefix)
Debug functionality - Dumps the contents of the internal array.
|
T |
get()
Dequeues the oldest enqueued element if available, otherwise null.
|
T |
getBlocking()
Dequeues the oldest enqueued element.
|
int |
getFreeSlots()
Returns the number of free slots available to put.
|
T[] |
getInternalArray()
Returns the internal array as-is, i.e.
|
void |
growEmptyBuffer(T[] newElements)
Grows an empty ring buffer, increasing it's capacity about the amount.
|
void |
growFullBuffer(int growAmount)
Grows a full ring buffer, increasing it's capacity about the amount.
|
boolean |
isEmpty()
Returns true if this ring buffer is empty, otherwise false.
|
boolean |
isFull()
Returns true if this ring buffer is full, otherwise false.
|
T |
peek()
Peeks the next element at the read position w/o modifying pointer, nor blocking.
|
T |
peekBlocking()
Peeks the next element at the read position w/o modifying pointer, but w/ blocking.
|
boolean |
put(T e)
Enqueues the given element.
|
void |
putBlocking(T e)
Enqueues the given element.
|
boolean |
putSame(boolean blocking)
Enqueues the same element at it's write position, if not full.
|
void |
resetFull(T[] copyFrom)
Resets the read and write position according to a full ring buffer
and fill all slots w/ elements of array
copyFrom . |
int |
size()
Returns the number of elements in this ring buffer.
|
String |
toString()
Returns a short string representation incl.
|
void |
waitForFreeSlots(int count)
Blocks until at least
count free slots become available. |
public LFRingbuffer(T[] copyFrom) throws IllegalArgumentException
Example for a 10 element Integer array:
Integer[] source = new Integer[10]; // fill source with content .. Ringbufferrb = new LFRingbuffer (source);
isFull()
returns true on the newly created full ring buffer.
Implementation will allocate an internal array with size of array copyFrom
plus one,
and copy all elements from array copyFrom
into the internal array.
copyFrom
- mandatory source array determining ring buffer's net capacity()
and initial content.IllegalArgumentException
- if copyFrom
is null
public LFRingbuffer(Class<? extends T[]> arrayType, int capacity)
capacity
.
Example for a 10 element Integer array:
Ringbufferrb = new LFRingbuffer (10, Integer[].class);
isEmpty()
returns true on the newly created empty ring buffer.
Implementation will allocate an internal array of size capacity
plus one.
arrayType
- the array type of the created empty internal array.capacity
- the initial net capacity of the ring bufferpublic final String toString()
Ringbuffer
toString
in interface Ringbuffer<T>
toString
in class Object
public final void dump(PrintStream stream, String prefix)
Ringbuffer
dump
in interface Ringbuffer<T>
public final T[] getInternalArray()
Ringbuffer
The layout and size of the internal array is implementation dependent.
Users shall not modify or rely on the returned array.
getInternalArray
in interface Ringbuffer<T>
public final int capacity()
Ringbuffer
capacity
in interface Ringbuffer<T>
public final void clear()
Ringbuffer
null
.
Ringbuffer.isEmpty()
will return true
after calling this method.
clear
in interface Ringbuffer<T>
public final void resetFull(T[] copyFrom) throws IllegalArgumentException
Ringbuffer
copyFrom
.
Array's copyFrom
elements will be copied into the internal array,
hence it's length must be equal to Ringbuffer.capacity()
.
resetFull
in interface Ringbuffer<T>
copyFrom
- Mandatory array w/ length Ringbuffer.capacity()
to be copied into the internal array.IllegalArgumentException
- if copyFrom
is null
.public final int size()
Ringbuffer
size
in interface Ringbuffer<T>
public final int getFreeSlots()
Ringbuffer
getFreeSlots
in interface Ringbuffer<T>
public final boolean isEmpty()
Ringbuffer
isEmpty
in interface Ringbuffer<T>
public final boolean isFull()
Ringbuffer
isFull
in interface Ringbuffer<T>
public final T get()
The returned ring buffer slot will be set to null
to release the reference
and move ownership to the caller.
Method is non blocking and returns immediately;.
Implementation advances the read position and returns the element at it, if not empty.
get
in interface Ringbuffer<T>
public final T getBlocking() throws InterruptedException
The returned ring buffer slot will be set to null
to release the reference
and move ownership to the caller.
Methods blocks until an element becomes available via put.
Implementation advances the read position and returns the element at it, if not empty.
getBlocking
in interface Ringbuffer<T>
InterruptedException
public final T peek()
Ringbuffer
peek
in interface Ringbuffer<T>
null
if empty, otherwise the element which would be read next.public final T peekBlocking() throws InterruptedException
Ringbuffer
peekBlocking
in interface Ringbuffer<T>
null
if empty, otherwise the element which would be read next.InterruptedException
public final boolean put(T e)
Returns true if successful, otherwise false in case buffer is full.
Method is non blocking and returns immediately;.
Implementation advances the write position and stores the given element at it, if not full.
put
in interface Ringbuffer<T>
public final void putBlocking(T e) throws InterruptedException
Method blocks until a free slot becomes available via get.
Implementation advances the write position and stores the given element at it, if not full.
putBlocking
in interface Ringbuffer<T>
InterruptedException
public final boolean putSame(boolean blocking) throws InterruptedException
Returns true if successful, otherwise false in case buffer is full.
If blocking
is true, method blocks until a free slot becomes available via get.
Implementation advances the write position and keeps the element at it, if not full.
putSame
in interface Ringbuffer<T>
blocking
- if true, wait until a free slot becomes available via get.InterruptedException
public final void waitForFreeSlots(int count) throws InterruptedException
Ringbuffer
count
free slots become available.waitForFreeSlots
in interface Ringbuffer<T>
InterruptedException
public final void growEmptyBuffer(T[] newElements) throws IllegalStateException, IllegalArgumentException
Ringbuffer
Growing an empty ring buffer increases it's size about the amount, i.e. renders it not empty.
The new elements are inserted at the read position, able to be read out via Ringbuffer.get()
etc.
growEmptyBuffer
in interface Ringbuffer<T>
newElements
- array of new full elements the empty buffer shall grow about.IllegalStateException
- if buffer is not emptyIllegalArgumentException
- if newElements is nullpublic final void growFullBuffer(int growAmount) throws IllegalStateException, IllegalArgumentException
Ringbuffer
Growing a full ring buffer leaves the size intact, i.e. renders it not full.
New null
elements are inserted at the write position, able to be written to via Ringbuffer.put(Object)
etc.
growFullBuffer
in interface Ringbuffer<T>
growAmount
- the amount of elements the buffer shall grow aboutIllegalStateException
- if buffer is not fullIllegalArgumentException
- if amount is < 0