Tools

Estimated reading time: 1 minute

ObjectPool

ObjectPool is a general purpose lock-free concurrent-safe object pool. It is leak-safe: all object that hasn’t been recycled but collected by GC do not cause any issues with a pool but only allocation penalty. Note that it doens’t mean that leaking object will not cause any issues at all as lost objects could hold some native or external resources. The only guarantee is that ObjectPool is not going to break if there are lost objects.

interface ObjectPool<T : Any> : Closeable {
    val capacity: Int
    fun borrow(): T
    fun recycle(instance: T)
    fun dispose()
    fun close() = dispose()
}

inline fun <T : Any, R> ObjectPool<T>.useBorrowed(block: (T) -> R): R // alias of useInstance
inline fun <T : Any, R> ObjectPool<T>.useInstance(block: (T) -> R): R
val ExampleIntArrayPool = object : DefaultPool<IntArray>(ARRAY_POOL_SIZE) {
    override fun produceInstance(): IntArray = IntArray(ARRAY_SIZE)
}

class ExampleDirectByteBufferPool(val bufferSize: Int, size: Int) : DefaultPool<ByteBuffer>(size) {
    override fun produceInstance(): ByteBuffer = java.nio.ByteBuffer.allocateDirect(bufferSize)

    override fun clearInstance(instance: ByteBuffer): ByteBuffer {
        instance.clear()
        return instance
    }

    override fun validateInstance(instance: ByteBuffer) {
        require(instance.isDirect)
        require(instance.capacity() == bufferSize)
    }
}