[][src]Struct sharded_slab::Pool

pub struct Pool<T, C = DefaultConfig> where
    T: Clear + Default,
    C: Config
{ /* fields omitted */ }

A lock-free concurrent object pool.

Slabs provide pre-allocated storage for many instances of a single type. But, when working with heap allocated objects, the advantages of a slab are lost, as the memory allocated for the object is freed when the object is removed from the slab. With a pool, we can instead reuse this memory for objects being added to the pool in the future, therefore reducing memory fragmentation and avoiding additional allocations.

This type implements a lock-free concurrent pool, indexed by usizes. The items stored in this type need to implement Clear and Default.

The Pool type shares similar semantics to Slab when it comes to sharing across threads and storing mutable shared data. The biggest difference is there are no Slab::insert and Slab::take analouges for the Pool type. Instead new items are added to the pool by using the Pool::create method, and marked for clearing by the Pool::clear method.

Examples

Add an entry to the pool, returning an index:

let pool: Pool<String> = Pool::new();

let key = pool.create(|item| item.push_str("hello world")).unwrap();
assert_eq!(pool.get(key).unwrap(), String::from("hello world"));

Pool entries can be cleared either by manually calling Pool::clear. This marks the entry to be cleared when the guards referencing to it are dropped.

let pool: Pool<String> = Pool::new();

let key = pool.create(|item| item.push_str("hello world")).unwrap();

// Mark this entry to be cleared.
pool.clear(key);

// The cleared entry is no longer available in the pool
assert!(pool.get(key).is_none());

Configuration

Both Pool and Slab share the same configuration mechanism. See crate level documentation for more details.

Methods

impl<T> Pool<T> where
    T: Clear + Default
[src]

pub fn new() -> Self[src]

pub fn new_with_config<C: Config>() -> Pool<T, C>[src]

Returns a new Pool with the provided configuration parameters.

impl<T, C> Pool<T, C> where
    T: Clear + Default,
    C: Config
[src]

pub const USED_BITS: usize[src]

The number of bits in each index which are used by the pool.

If other data is packed into the usize indices returned by Pool::create, user code is free to use any bits higher than the USED_BITS-th bit freely.

This is determined by the Config type that configures the pool's parameters. By default, all bits are used; this can be changed by overriding the Config::RESERVED_BITS constant.

pub fn create(&self, initializer: impl FnOnce(&mut T)) -> Option<usize>[src]

Creates a new object in the pool, returning a key that can be used to access it.

If this function returns None, then the shard for the current thread is full and no items can be added until some are removed, or the maximum number of shards has been reached.

Examples

let pool: Pool<String> = Pool::new();
let key = pool.create(|item| item.push_str("Hello")).unwrap();
assert_eq!(pool.get(key).unwrap(), String::from("Hello"));

pub fn get(&self, key: usize) -> Option<PoolGuard<T, C>>[src]

Return a reference to the value associated with the given key.

If the pool does not contain a value for the given key, None is returned instead.

Examples

let pool: Pool<String> = sharded_slab::Pool::new();
let key = pool.create(|item| item.push_str("hello world")).unwrap();

assert_eq!(pool.get(key).unwrap(), String::from("hello world"));
assert!(pool.get(12345).is_none());

pub fn clear(&self, key: usize) -> bool[src]

Remove the value using the storage associated with the given key from the pool, returning true if the value was removed.

This method does not block the current thread until the value can be cleared. Instead, if another thread is currently accessing that value, this marks it to be cleared by that thread when it is done accessing that value.

Examples

let pool: Pool<String> = Pool::new();
let key = pool.create(|item| item.push_str("hello world")).unwrap();

assert_eq!(pool.get(key).unwrap(), String::from("hello world"));

pool.clear(key);
assert!(pool.get(key).is_none());
let pool: Pool<String> = Pool::new();

let key = pool.create(|item| item.push_str("Hello world!")).unwrap();

// Clearing a key that doesn't exist in the `Pool` will return `false`
assert_eq!(pool.clear(key + 69420), false);

// Clearing a key that does exist returns `true`
assert!(pool.clear(key));

// Clearing a key that has previously been cleared will return `false`
assert_eq!(pool.clear(key), false);

Trait Implementations

impl<T, C> Debug for Pool<T, C> where
    T: Debug + Clear + Default,
    C: Config
[src]

impl<T> Default for Pool<T> where
    T: Clear + Default
[src]

impl<T, C> Send for Pool<T, C> where
    T: Send + Clear + Default,
    C: Config
[src]

impl<T, C> Sync for Pool<T, C> where
    T: Sync + Clear + Default,
    C: Config
[src]

Auto Trait Implementations

impl<T, C = DefaultConfig> !RefUnwindSafe for Pool<T, C>

impl<T, C> Unpin for Pool<T, C> where
    C: Unpin

impl<T, C> UnwindSafe for Pool<T, C> where
    C: UnwindSafe,
    T: UnwindSafe

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.