Skip to content

Instantly share code, notes, and snippets.

@bristermitten
Last active December 1, 2019 15:29
Show Gist options
  • Save bristermitten/783fbe3e33d4405a0ecbc9b7504ade9f to your computer and use it in GitHub Desktop.
Save bristermitten/783fbe3e33d4405a0ecbc9b7504ade9f to your computer and use it in GitHub Desktop.
A simple Object Buffer implementation in Kotlin that uses BlockingQueue. Objects cannot be reused so new values are always created, unless any are cached.
package me.bristermitten.teamed.util
import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue
/**
* A buffer of objects with a fixed size.
* These objects cannot be reused so the given [compute] function is continuously run asynchronously
* to ensure that the buffer is always populated.
* If the objects are polled faster than [compute] can create new objects,
* [poll] will block until a new object is added
*
* @author Alex Wood (github.com/knightzmc)
* @param size the maximum size of the buffer
* @param compute the function to get or create objects to fill the buffer
* @param V the type of object stored in the buffer
*/
class ObjectBuffer<V>(private val size: Int, private val compute: () -> V) {
/**
* The underlying list holding the objects in the buffer
* This will never contain null values, and may be empty
*/
private val list: BlockingQueue<V> = LinkedBlockingQueue<V>(size)
/**
* Function to constantly add new computed elements to the buffer.
* A [BlockingQueue] is used so the thread will be blocked until space is free
*/
private val addFunction = {
while (true) {
list.put(compute())
}
}
/**
* The thread that runs in the background. It repeats adding a computed value whenever possible,
* blocking until space is free
*/
private val computeThread = Thread(addFunction, "ObjectPool")
init {
computeThread.start()
}
/**
* Returns the size of the buffer
*/
fun size() = list.size
/**
* Returns the maximum size of the buffer
*/
fun maxSize() = size
/**
* Return is the buffer is full or not
*/
fun isFull() = list.size == size
/**
* Return if the buffer is empty
*/
fun isEmpty() = list.isEmpty()
/**
* Get the next element in the buffer. If the buffer is empty, this will block
* the calling thread until a new value is computed
*/
fun poll(): V {
return list.take()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment