Pool

Struct Pool 

Source
pub struct Pool<T: Default> { /* private fields */ }
Expand description

A concurrent object pool.

§Examples

use concurrent_pool::{Pool, Builder};
use std::sync::{Arc, mpsc};

let mut builder = Builder::new();

let pool: Arc<Pool<String>> = Arc::new(builder.capacity(10).clear_func(String::clear).build());


let (tx, rx) = mpsc::channel();
let clone_pool = pool.clone();
let tx1 = tx.clone();
let sender1 = std::thread::spawn(move || {
    let item = clone_pool.pull_owned_with(|x| x.push_str("1")).unwrap();
    tx1.send((1, item)).unwrap();
});

let clone_pool = pool.clone();
let sender2 = std::thread::spawn(move || {
    let item = clone_pool.pull_owned_with(|x| x.push_str("2")).unwrap();
    tx.send((2, item)).unwrap();
});

let receiver = std::thread::spawn(move || {
    for _ in 0..2 {
        let (id, item) = rx.recv().unwrap();
        if id == 1 {
            assert_eq!(*item, "1");
        } else {
            assert_eq!(*item, "2");
        }
    }
});

sender1.join().unwrap();
sender2.join().unwrap();
receiver.join().unwrap();

Implementations§

Source§

impl<T: Default> Pool<T>

Source

pub fn new(prealloc: usize, capacity: usize) -> Self

Create a new pool with the given preallocation and capacity.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::new(2, 5);
assert_eq!(pool.available(), 5);
assert_eq!(pool.available_noalloc(), 2);
let item = pool.pull().unwrap();
assert_eq!(pool.available_noalloc(), 1);
Source

pub fn with_capacity(capacity: usize) -> Self

Create a new pool with the given capacity.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(10);
assert_eq!(pool.available(), 10);
assert_eq!(pool.available_noalloc(), 10);
let item = pool.pull().unwrap();
assert_eq!(pool.available(), 9);
Source

pub fn with_capacity_half_prealloc(capacity: usize) -> Self

Create a new pool with half of the capacity preallocated.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity_half_prealloc(10);
assert_eq!(pool.available(), 10);
assert_eq!(pool.available_noalloc(), 5);
let item = pool.pull().unwrap();
assert_eq!(pool.available_noalloc(), 4);
assert_eq!(pool.in_use(), 1);
Source

pub fn with_config(config: Config<T>) -> Self

Create a new pool with the given configuration.

§Example
use concurrent_pool::{Pool, Config};

fn clear_func(x: &mut String) {
    x.clear();
}

let mut config = Config::default();
config.capacity = 1;
config.clear_func = Some(clear_func);
let pool: Pool<String> = Pool::with_config(config);
let item = pool.pull_with(|s| s.push_str("Hello, World!")).unwrap();
assert_eq!(&*item, "Hello, World!");
drop(item);
let item2 = pool.pull().unwrap();
assert_eq!(&*item2, "");
Source

pub fn in_use(&self) -> usize

Get in used items count.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(10);
assert_eq!(pool.in_use(), 0);
let item = pool.pull().unwrap();
assert_eq!(pool.in_use(), 1);
let item2 = pool.pull().unwrap();
assert_eq!(pool.in_use(), 2);
Source

pub fn allocated(&self) -> usize

Get allocated items count.

§Example
use concurrent_pool::Pool;

let pool = Pool::<usize>::new(2, 5);
assert_eq!(pool.allocated(), 2);
Source

pub fn available(&self) -> usize

Get available items count.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(10);
assert_eq!(pool.available(), 10);
let item = pool.pull().unwrap();
assert_eq!(pool.available(), 9);
Source

pub fn available_noalloc(&self) -> usize

Get available items count without allocation.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::new(2, 5);
assert_eq!(pool.available_noalloc(), 2);
let item = pool.pull().unwrap();
assert_eq!(pool.available_noalloc(), 1);
let item2 = pool.pull().unwrap();
assert_eq!(pool.available_noalloc(), 0);
let item3 = pool.pull().unwrap();
assert_eq!(pool.available_noalloc(), 0);
drop(item);
assert_eq!(pool.available_noalloc(), 1);
Source

pub fn is_empty(&self) -> bool

Check if the pool is empty.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(2);
assert!(!pool.is_empty());
let item1 = pool.pull().unwrap();
assert!(!pool.is_empty());
let item2 = pool.pull().unwrap();
assert!(pool.is_empty());
drop(item1);
assert!(!pool.is_empty());
Source

pub fn capacity(&self) -> usize

Get the capacity of the pool.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(10);
assert_eq!(pool.capacity(), 10);
Source

pub fn pull(&self) -> Option<Entry<'_, T>>

Pull an item from the pool. Return None if the pool is empty.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(2);
let item1 = pool.pull().unwrap();
assert_eq!(*item1, 0);
Source

pub fn pull_with<F>(&self, func: F) -> Option<Entry<'_, T>>
where F: FnOnce(&mut T),

Pull an item from the pool and apply a function to it. Return None if the pool is empty.

§Example
use concurrent_pool::Pool;

let pool: Pool<u32> = Pool::with_capacity(2);
let item1 = pool.pull_with(|x| *x = 42).unwrap();
assert_eq!(*item1, 42);
Source

pub fn pull_owned(self: &Arc<Self>) -> Option<OwnedEntry<T>>

Pull an owned item from the pool. Return None if the pool is empty.

§Example
use concurrent_pool::Pool;
use std::sync::Arc;

let pool: Arc<Pool<u32>> = Arc::new(Pool::with_capacity(2));
let item1 = pool.pull_owned().unwrap();
assert_eq!(*item1, 0);
Source

pub fn pull_owned_with<F>(self: &Arc<Self>, func: F) -> Option<OwnedEntry<T>>
where F: FnOnce(&mut T),

Pull an owned item from the pool and apply a function to it. Return None if the pool is empty.

§Example
use concurrent_pool::Pool;
use std::sync::Arc;

let pool: Arc<Pool<u32>> = Arc::new(Pool::with_capacity(2));
let item1 = pool.pull_owned_with(|x| *x = 42).unwrap();
assert_eq!(*item1, 42);

Trait Implementations§

Source§

impl<T: Debug + Default> Debug for Pool<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default> Drop for Pool<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for Pool<T>

§

impl<T> RefUnwindSafe for Pool<T>

§

impl<T> Send for Pool<T>
where T: Send + Sync,

§

impl<T> Sync for Pool<T>
where T: Send + Sync,

§

impl<T> Unpin for Pool<T>

§

impl<T> UnwindSafe for Pool<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.