blind_pool/
lib.rs

1//! This package provides [`BlindPool`], a dynamically growing pool of objects that can store
2//! objects of any type.
3//!
4//! It offers automatic memory management with stable memory addresses
5//! and efficient typed insertion with automatic value dropping.
6//!
7//! [`LocalBlindPool`] is a single-threaded variant with reduced overhead and [`RawBlindPool`]
8//! offers manual lifetime management for the most performance-sensitive scenarios.
9//!
10//! # Features
11//!
12//! - **Type-agnostic memory management**: The pool accepts objects of any sized type.
13//! - **Automatic resource management**: Pooled objects are dropped automatically when no longer
14//!   referenced.
15//! - **Thread-safe and single-threaded variants**: [`BlindPool`] for multi-threaded use,
16//!   [`LocalBlindPool`] for single-threaded performance.
17//! - **Always pinned**: Memory address remains valid for the entire lifetime of a pooled object.
18//! - **Dynamic growth**: Pool capacity grows automatically as needed, shrinks to fit on-demand.
19//! - **Efficient allocation**: Uses high density slabs to minimize allocation overhead.
20//! - **Stable Rust**: No unstable Rust features required.
21//! - **Optional leak detection**: Pool can be configured to panic on drop if values are
22//!   still present (primarily relevant for [`RawBlindPool`]).
23//!
24//! # Example
25//!
26//! ```rust
27//! use blind_pool::BlindPool;
28//!
29//! // Create a thread-safe pool.
30//! let pool = BlindPool::new();
31//!
32//! // Insert values and get handles.
33//! let u64_handle = pool.insert(42_u64);
34//! let string_handle = pool.insert("hello".to_string());
35//!
36//! // Access values through dereferencing.
37//! assert_eq!(*u64_handle, 42);
38//! assert_eq!(*string_handle, "hello");
39//!
40//! // Values are automatically cleaned up when handles are dropped.
41//! ```
42//!
43//! For single-threaded use:
44//!
45//! ```rust
46//! use blind_pool::LocalBlindPool;
47//!
48//! // Create a single-threaded pool (more efficient).
49//! let pool = LocalBlindPool::new();
50//!
51//! let value_handle = pool.insert(vec![1, 2, 3]);
52//! assert_eq!(*value_handle, vec![1, 2, 3]);
53//! ```
54//!
55//! For manual resource management:
56//!
57//! ```rust
58//! use blind_pool::RawBlindPool;
59//!
60//! // Create a pool with manual resource management.
61//! let mut pool = RawBlindPool::new();
62//!
63//! // Insert values of different types into the same pool.
64//! let pooled_u64 = pool.insert(42_u64);
65//! let pooled_i32 = pool.insert(-123_i32);
66//! let pooled_f32 = pool.insert(3.14_f32);
67//!
68//! // Read data back from the pooled items.
69//! let value_u64 = *pooled_u64; // Safe deref access
70//! let value_i32 = *pooled_i32; // Safe deref access
71//!
72//! assert_eq!(value_u64, 42);
73//! assert_eq!(value_i32, -123);
74//!
75//! // Manual cleanup required.
76//! unsafe { pool.remove(&pooled_u64) };
77//! unsafe { pool.remove(&pooled_i32) };
78//! unsafe { pool.remove(&pooled_f32) };
79//! ```
80
81mod cast;
82mod constants;
83mod local_pool;
84mod local_pooled;
85mod local_pooled_mut;
86mod pool;
87mod pooled;
88mod pooled_mut;
89mod raw;
90mod raw_builder;
91mod raw_pooled;
92mod raw_pooled_mut;
93
94pub use local_pool::*;
95pub use local_pooled::*;
96pub use local_pooled_mut::*;
97// Re-export DropPolicy from opaque_pool simply because we do not need a different one.
98pub use opaque_pool::DropPolicy;
99// Re-export so we can use it without the consumer needing a reference.
100#[doc(hidden)]
101pub use pastey::paste as __private_paste;
102pub use pool::*;
103pub use pooled::*;
104pub use pooled_mut::*;
105pub use raw::*;
106pub use raw_builder::*;
107pub use raw_pooled::*;
108pub use raw_pooled_mut::*;