BlindPool

Struct BlindPool 

Source
pub struct BlindPool { /* private fields */ }
Expand description

A thread-safe wrapper around RawBlindPool that provides automatic resource management and reference counting.

This is the main pool type that provides automatic resource management through reference counting. For manual resource management, use RawBlindPool instead.

This type acts as a cloneable handle to a shared pool instance. Multiple handles can exist simultaneously, and the underlying pool remains alive as long as at least one handle exists.

Items inserted into the pool are automatically removed when all references to them are dropped, eliminating the need for manual resource management.

§Thread Safety

This type is thread-safe and can be safely shared across multiple threads.

§Example

use std::thread;

use blind_pool::BlindPool;

let pool = BlindPool::new();

// Clone the pool handle to share across threads.
let pool_clone = pool.clone();

let handle = thread::spawn(move || {
    let item_handle = pool_clone.insert("Test".to_string());
    item_handle.clone()
});

let value = handle.join().unwrap();
assert_eq!(*value, "Test".to_string());

Implementations§

Source§

impl BlindPool

Source

pub fn new() -> Self

Creates a new BlindPool with default configuration.

This is the equivalent of creating a raw pool and wrapping it in management.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

let string1_handle = pool.insert("Test".to_string());
let string2_handle = pool.insert("hello".to_string());

// Access values through dereferencing.
assert_eq!(*string1_handle, "Test".to_string());
assert_eq!(*string2_handle, "hello");
Source

pub fn insert<T: 'static>(&self, value: T) -> Pooled<T>

Inserts a value into the pool and returns a handle to access it.

The returned handle automatically manages the lifetime of the inserted value. When all handles to the value are dropped, the value is automatically removed from the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

let string1_handle = pool.insert("Test".to_string());
let string2_handle = pool.insert("hello".to_string());

// Access values through dereferencing.
assert_eq!(*string1_handle, "Test".to_string());
assert_eq!(*string2_handle, "hello");
Source

pub unsafe fn insert_with<T: 'static>( &self, f: impl FnOnce(&mut MaybeUninit<T>), ) -> Pooled<T>

Inserts a value into the pool using in-place initialization and returns a handle to it.

This method is designed for partial object initialization, where you want to construct an object directly in its final memory location. This can provide significant performance benefits compared to insert() by avoiding temporary allocations and unnecessary moves, especially for large or complex types.

The returned handle automatically manages the lifetime of the inserted value. When all handles to the value are dropped, the value is automatically removed from the pool.

§Example
use std::mem::MaybeUninit;

use blind_pool::BlindPool;

let pool = BlindPool::new();

// Partial initialization - build complex object directly in pool memory.
// SAFETY: We properly initialize the value in the closure.
let handle = unsafe {
    pool.insert_with(|uninit: &mut MaybeUninit<Vec<u64>>| {
        let mut vec = Vec::with_capacity(1000);
        vec.extend(0..100);
        uninit.write(vec);
    })
};

// Access value through dereferencing.
assert_eq!(handle.len(), 100);
§Safety

The closure must properly initialize the MaybeUninit<T> before returning.

Source

pub fn insert_mut<T: 'static>(&self, value: T) -> PooledMut<T>

Inserts a value into the pool and returns a mutable handle to access it.

Unlike insert(), this method returns a PooledMut<T> that provides exclusive mutable access to the value and does not implement Clone. This is suitable for scenarios where you need to modify the value and don’t require shared ownership.

The returned handle automatically manages the lifetime of the inserted value. When the handle is dropped, the value is automatically removed from the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

let mut string_handle = pool.insert_mut("Test".to_string());

// Mutate the value directly.
string_handle.push_str(" - Modified");
assert_eq!(*string_handle, "Test - Modified");
Source

pub unsafe fn insert_with_mut<T: 'static>( &self, f: impl FnOnce(&mut MaybeUninit<T>), ) -> PooledMut<T>

Inserts a value into the pool using in-place initialization and returns a mutable handle to it.

This allows the caller to initialize the item in-place using a closure that receives a &mut MaybeUninit<T>. This can be more efficient than constructing the value separately and then moving it into the pool, especially for large or complex types.

Unlike insert_with(), this method returns a PooledMut<T> that provides exclusive mutable access to the value and does not implement Clone.

The returned handle automatically manages the lifetime of the inserted value. When the handle is dropped, the value is automatically removed from the pool.

§Example
use std::mem::MaybeUninit;

use blind_pool::BlindPool;

let pool = BlindPool::new();

// SAFETY: We properly initialize the value in the closure.
let mut handle = unsafe {
    pool.insert_with_mut(|uninit: &mut MaybeUninit<String>| {
        uninit.write(String::from("Hello, World!"));
    })
};

// Mutate the value directly.
handle.push_str(" - Modified");
assert_eq!(*handle, "Hello, World! - Modified");
§Safety

The closure must properly initialize the MaybeUninit<T> before returning.

Source

pub fn len(&self) -> usize

Returns the total number of items currently stored in the pool.

This operation may block if another thread is currently accessing the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

assert_eq!(pool.len(), 0);

let _item1 = pool.insert("Hello".to_string());
let _item2 = pool.insert("hello".to_string());

assert_eq!(pool.len(), 2);
Source

pub fn is_empty(&self) -> bool

Returns whether the pool has no inserted values.

This operation may block if another thread is currently accessing the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

assert!(pool.is_empty());

let item = pool.insert("Test".to_string());
assert!(!pool.is_empty());

drop(item);
assert!(pool.is_empty());
Source

pub fn capacity_of<T>(&self) -> usize

Returns the capacity for items of type T.

This is the number of items of type T that can be stored without allocating more memory. If no items of type T have been inserted yet, returns 0.

This operation may block if another thread is currently accessing the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

// Initially no capacity is allocated for any type.
assert_eq!(pool.capacity_of::<u32>(), 0);
assert_eq!(pool.capacity_of::<f64>(), 0);

// Inserting a String allocates capacity for String but not f64.
let _item = pool.insert("Test".to_string());
assert!(pool.capacity_of::<String>() > 0);
assert_eq!(pool.capacity_of::<f64>(), 0);
Source

pub fn reserve_for<T>(&self, additional: usize)

Reserves capacity for at least additional more items of type T.

The pool may reserve more space to speculatively avoid frequent reallocations. After calling reserve_for, the capacity for type T will be greater than or equal to the current count of T items plus additional. Does nothing if capacity is already sufficient.

If no items of type T have been inserted yet, this creates an internal pool for type T and reserves the requested capacity.

This operation may block if another thread is currently accessing the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

// Reserve space for 10 u32 values specifically.
pool.reserve_for::<u32>(10);
assert!(pool.capacity_of::<u32>() >= 10);
assert_eq!(pool.capacity_of::<f64>(), 0); // Other types unaffected.

// Insert values - should not need to allocate more capacity.
let _item = pool.insert(42_u32);
assert!(pool.capacity_of::<u32>() >= 10);
Source

pub fn shrink_to_fit(&self)

Shrinks the capacity of the pool to fit its current size.

This can help reduce memory usage after items have been removed from the pool.

This operation may block if another thread is currently accessing the pool.

§Example
use blind_pool::BlindPool;

let pool = BlindPool::new();

// Insert many items to allocate capacity.
let handles: Vec<_> = (0..100).map(|i| pool.insert(i)).collect();

// Remove all items.
drop(handles);

// Shrink to fit the current size.
pool.shrink_to_fit();

Trait Implementations§

Source§

impl Clone for BlindPool

Source§

fn clone(&self) -> BlindPool

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BlindPool

Source§

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

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

impl Default for BlindPool

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.