Struct syncpool::prelude::SyncPool[][src]

pub struct SyncPool<T> { /* fields omitted */ }

Implementations

impl<T: Default> SyncPool<T>[src]

pub fn new() -> Self[src]

Create a pool with default size of 64 pre-allocated elements in it.

pub fn with_size(size: usize) -> Self[src]

Create a SyncPool with pre-defined number of elements. Note that we will round-up the size such that the total number of elements in the pool will mod to 8.

impl<T> SyncPool<T>[src]

pub fn with_builder(builder: fn() -> T) -> Self[src]

Create a pool with default size of 64 pre-allocated elements in it, which will use the builder handler to obtain the initialized instance of the struct, and then place the object into the syncpool for later use.

Note that the handler shall be responsible for creating and initializing the struct object with all fields being valid. After all, they will be the same objects provided to the caller when invoking the get call.

Examples

use syncpool::*;
use std::vec;

struct BigStruct {
    a: u32,
    b: u32,
    c: Vec<u8>,
}

let mut pool = SyncPool::with_builder(|| {
    BigStruct {
        a: 1,
        b: 42,
        c: vec::from_elem(0u8, 0x1_000_000),
    }
});

let big_box: Box<BigStruct> = pool.get();

assert_eq!(big_box.a, 1);
assert_eq!(big_box.b, 42);
assert_eq!(big_box.c.len(), 0x1_000_000);

pool.put(big_box);

pub fn with_builder_and_size(size: usize, builder: fn() -> T) -> Self[src]

Create a SyncPool with pre-defined number of elements and a packer handler. The builder handler shall essentially function the same way as in the with_builder, that it shall take the responsibility to create and initialize the element, and return the instance at the end of the builder closure. Note that we will round-up the size such that the total number of elements in the pool will mod to 8.

pub fn with_packer(packer: fn(_: Box<T>) -> Box<T>) -> Self[src]

Create a pool with default size of 64 pre-allocated elements in it, which will use the packer handler to initialize the element that's being provided by the pool.

Note that the handler shall take a boxed instance of the element that only contains placeholder fields, and it is the caller/handler's job to initialize the fields and pack it with valid and meaningful values. If the struct is valid with all-zero values, the handler can just return the input element.

Examples

use syncpool::*;
use std::vec;

struct BigStruct {
    a: u32,
    b: u32,
    c: Vec<u8>,
}

let mut pool = SyncPool::with_packer(|mut src: Box<BigStruct>| {
    src.a = 1;
    src.b = 42;
    src.c = vec::from_elem(0u8, 0x1_000_000);
    src
});

let big_box: Box<BigStruct> = pool.get();

assert_eq!(big_box.a, 1);
assert_eq!(big_box.b, 42);
assert_eq!(big_box.c.len(), 0x1_000_000);

pool.put(big_box);

pub fn with_packer_and_size(
    size: usize,
    packer: fn(_: Box<T>) -> Box<T>
) -> Self
[src]

Create a SyncPool with pre-defined number of elements and a packer handler. The packer handler shall essentially function the same way as in with_packer, that it shall take the responsibility to initialize all the fields of a placeholder struct on the heap, otherwise the element returned by the pool will be essentially undefined, unless all the struct's fields can be represented by a 0 value. In addition, we will round-up the size such that the total number of elements in the pool will mod to 8.

pub fn get(&mut self) -> Box<T>[src]

Try to obtain a pre-allocated element from the pool. This method will always succeed even if the pool is empty or not available for anyone to access, and in this case, a new boxed-element will be created.

pub fn put(&mut self, val: Box<T>) -> Option<Box<T>>[src]

Try to return an element to the SyncPool. If succeed, we will return None to indicate that the value has been placed in an empty slot; otherwise, we will return Option<Box<T>> such that the caller can decide if the element shall be just discarded, or try put it back again.

Trait Implementations

impl<T> Default for SyncPool<T> where
    T: Default
[src]

impl<T> Drop for SyncPool<T>[src]

impl<T> PoolManager<T> for SyncPool<T>[src]

The pool manager that provide many useful utilities to keep the SyncPool close to the needs of the caller program.

fn reset_handle(&mut self, handle: fn(_: &mut T)) -> &mut Self[src]

Set or update the reset handle. If set, the reset handle will be invoked every time an element has been returned back to the pool (i.e. calling the put method), regardless of if the element is created by the pool or not.

fn allow_expansion(&mut self, allow: bool) -> &mut Self[src]

Set or update the settings that if we will allow the SyncPool to be expanded.

fn expand(&mut self, additional: usize, block: bool) -> bool[src]

Try to expand the SyncPool and add more elements to it. Usually invoke this API only when the caller is certain that the pool is under pressure, and that a short block to the access of the pool won't cause serious issues, since the function will block the current caller's thread until it's finished (i.e. get the opportunity to raise the writer's barrier and wait everyone to leave).

If we're unable to expand the pool, it's due to one of the following reasons: 1) someone has already raised the writer's barrier and is likely modifying the pool, we will leave immediately, and it's up to the caller if they want to try again; 2) we've waited too long but still couldn't obtain an exclusive access to the pool, and similar to reason 1), we will quit now.

fn refill(&mut self, additional: usize) -> usize[src]

Due to contentious access to the pool, sometimes the put action could not finish and return the element to the pool successfully. Overtime, this could cause the number of elements in the pool to dwell. This would only happen slowly if we're running a very contentious multithreading program, but it surely could happen. If the caller detects such situation, they can invoke the refill API and try to refill the pool with elements.

We will try to refill as many elements as requested

impl<T> PoolState for SyncPool<T>[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for SyncPool<T> where
    T: RefUnwindSafe
[src]

impl<T> Send for SyncPool<T> where
    T: Send
[src]

impl<T> !Sync for SyncPool<T>[src]

impl<T> Unpin for SyncPool<T>[src]

impl<T> UnwindSafe for SyncPool<T> where
    T: RefUnwindSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.