Added support for having an initial empty object pool

master
Robinson 2023-09-06 22:02:12 +02:00
parent 7f45a524f2
commit 141d91cb60
No known key found for this signature in database
GPG Key ID: 8E7DB78588BD6F5C
5 changed files with 43 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 dorkbox, llc
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -47,14 +47,15 @@ object ObjectPool {
* Creates a suspending pool of a specific size, where the entire pool is initially filled, and when the pool is empty, a
* [Pool.take] will wait for a corresponding [Pool.put].
*
* @param poolObject controls the lifecycle of the pooled objects.
* @param poolObject controls the lifecycle of the pooled objects
* @param size the size of the pool to create
* @param initiallyFillPool true (default) to initially fill the pool with objects
* @param <T> the type of object used in the pool
*
* @return a suspending pool using the kotlin Channel implementation of a specific size
*/
fun <T: Any> suspending(poolObject: SuspendingPoolObject<T>, size: Int): dorkbox.objectPool.SuspendingPool<T> {
return suspending(poolObject, size, ChannelQueue(size))
fun <T: Any> suspending(poolObject: SuspendingPoolObject<T>, size: Int, initiallyFillPool: Boolean = true): dorkbox.objectPool.SuspendingPool<T> {
return suspending(poolObject, size, ChannelQueue(size), initiallyFillPool)
}
@ -62,44 +63,46 @@ object ObjectPool {
* Creates a suspending pool of a specific size, where the entire pool is initially filled, and when the pool is empty, a
* [Pool.take] will wait for a corresponding [Pool.put].
*
* @param poolObject controls the lifecycle of the pooled objects.
* @param poolObject controls the lifecycle of the pooled objects
* @param size the size of the pool to create
* @param initiallyFillPool true (default) to initially fill the pool with objects
* @param <T> the type of object used in the pool
*
* @return a suspending pool using the kotlin Channel implementation of a specific size
*/
fun <T> suspending(poolObject: SuspendingPoolObject<T>, size: Int, queue: SuspendingQueue<T>): dorkbox.objectPool.SuspendingPool<T> {
return SuspendingPool(poolObject, size, queue)
fun <T: Any> suspending(poolObject: SuspendingPoolObject<T>, size: Int, queue: SuspendingQueue<T>): dorkbox.objectPool.SuspendingPool<T> {
fun <T: Any> suspending(poolObject: SuspendingPoolObject<T>, size: Int, queue: SuspendingQueue<T>, initiallyFillPool: Boolean = true): dorkbox.objectPool.SuspendingPool<T> {
return SuspendingPool(poolObject, size, queue, initiallyFillPool)
}
/**
* Creates a high-performance blocking pool of a specific size, where the entire pool is initially filled, and when the pool is empty, a
* [Pool.take] will wait for a corresponding [Pool.put].
*
* @param poolObject controls the lifecycle of the pooled objects.
* @param poolObject controls the lifecycle of the pooled objects
* @param size the size of the pool to create
* @param initiallyFillPool true (default) to initially fill the pool with objects
* @param <T> the type of object used in the pool
*
* @return a blocking pool using the DisruptorBlockingQueue implementation of a specific size
*/
fun <T: Any> blocking(poolObject: PoolObject<T>, size: Int): Pool<T> {
return blocking(poolObject, DisruptorBlockingQueue(size), size)
fun <T: Any> blocking(poolObject: PoolObject<T>, size: Int, initiallyFillPool: Boolean = true): Pool<T> {
return blocking(poolObject, DisruptorBlockingQueue(size), size, initiallyFillPool)
}
/**
* Creates a blocking pool of a specific size, where the entire pool is initially filled, and when the pool is empty, a
* [Pool.take] will wait for a corresponding [Pool.put].
*
* @param poolObject controls the lifecycle of the pooled objects.
* @param poolObject controls the lifecycle of the pooled objects
* @param queue the blocking queue implementation to use
* @param size the size of the pool to create
* @param initiallyFillPool true (default) to initially fill the pool with objects
* @param <T> the type of object used in the pool
*
* @return a blocking pool using the specified [BlockingQueue] implementation of a specific size
*/
fun <T> blocking(poolObject: PoolObject<T>, queue: BlockingQueue<T>, size: Int): Pool<T> {
return BlockingPool(poolObject, queue, size)
fun <T: Any> blocking(poolObject: PoolObject<T>, queue: BlockingQueue<T>, size: Int): Pool<T> {
fun <T: Any> blocking(poolObject: PoolObject<T>, queue: BlockingQueue<T>, size: Int, initiallyFillPool: Boolean = true): Pool<T> {
return BlockingPool(poolObject, queue, size, initiallyFillPool)
}
/**

View File

@ -39,6 +39,11 @@ interface SuspendingPool<T: Any> {
*/
suspend fun put(`object`: T)
/**
* Return object to the pool, blocking if necessary. If the pool is a [SuspendingPool], this will wake the threads that have blocked during take/takeInterruptibly()
*/
fun putBlocking(`object`: T)
/**
* @return a new object instance created by the pool.
*/

View File

@ -20,7 +20,7 @@ import dorkbox.objectPool.PoolObject
import java.util.concurrent.BlockingQueue
/**
* A blocking pool of a specific size, where the entire pool is initially filled, and when the pool is empty,
* A blocking pool of a specific size, where the entire pool is (optionally) initially filled, and when the pool is empty,
* a [Pool.take] will wait for a corresponding [Pool.put].
*
* @author dorkbox, llc
@ -28,13 +28,16 @@ import java.util.concurrent.BlockingQueue
internal class BlockingPool<T: Any>(
private val poolObject: PoolObject<T>,
private val queue: BlockingQueue<T>,
size: Int) : Pool<T> {
size: Int,
fillPool: Boolean) : Pool<T> {
init {
for (x in 0 until size) {
val e = newInstance()
poolObject.onReturn(e)
queue.offer(e)
if (fillPool) {
for (x in 0 until size) {
val e = newInstance()
poolObject.onReturn(e)
queue.offer(e)
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 dorkbox, llc
* Copyright 2023 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -21,7 +21,7 @@ import dorkbox.objectPool.SuspendingPoolObject
import kotlinx.coroutines.runBlocking
/**
* A suspending pool of a specific size, where the entire pool is initially filled, and when the pool is empty,
* A suspending pool of a specific size, where the entire pool is (optionally) initially filled, and when the pool is empty,
* a [Pool.take] will wait for a corresponding [Pool.put].
*
* @author dorkbox, llc
@ -29,14 +29,17 @@ import kotlinx.coroutines.runBlocking
internal class SuspendingPool<T: Any>(
private val poolObject: SuspendingPoolObject<T>,
size: Int,
private val queue: SuspendingQueue<T>) : SuspendingPool<T> {
private val queue: SuspendingQueue<T>,
fillPool: Boolean) : SuspendingPool<T> {
init {
runBlocking {
for (x in 0 until size) {
val e = newInstance()
poolObject.onReturn(e)
queue.offer(e)
if (fillPool) {
runBlocking {
for (x in 0 until size) {
val e = newInstance()
poolObject.onReturn(e)
queue.offer(e)
}
}
}
}