#lock-free #atomic #garbage #non-blocking

object-pool

A thread-safe object pool with automatic return and attach/detach semantics

22 releases

0.6.0 Aug 18, 2024
0.5.4 May 10, 2021
0.5.3 May 25, 2020
0.4.4 Oct 29, 2019
0.1.6 Feb 2, 2019

#26 in Memory management

Download history 9532/week @ 2024-08-21 8715/week @ 2024-08-28 10115/week @ 2024-09-04 6338/week @ 2024-09-11 8019/week @ 2024-09-18 9928/week @ 2024-09-25 10191/week @ 2024-10-02 7648/week @ 2024-10-09 13109/week @ 2024-10-16 11006/week @ 2024-10-23 10701/week @ 2024-10-30 8711/week @ 2024-11-06 7710/week @ 2024-11-13 10661/week @ 2024-11-20 12759/week @ 2024-11-27 13971/week @ 2024-12-04

46,446 downloads per month
Used in 26 crates (12 directly)

MIT/Apache

2.5MB
378 lines

Object Pool

License Cargo Documentation

A thread-safe object pool with automatic return and attach/detach semantics

The goal of an object pool is to reuse expensive to allocate objects or frequently allocated objects

Usage

[dependencies]
object-pool = "0.5"
extern crate object_pool;

Examples

Creating a Pool

The general pool creation looks like this

 let pool: Pool<T> = Pool::new(capacity, || T::new());

Example pool with 32 Vec<u8> with capacity of 4096

 let pool: Pool<Vec<u8>> = Pool::new(32, || Vec::with_capacity(4096));

Using a Pool

Basic usage for ing from the pool

let pool: Pool<Vec<u8>> = Pool::new(32, || Vec::with_capacity(4096));
let mut reusable_buff = pool.try_pull().unwrap(); // returns None when the pool is saturated
reusable_buff.clear(); // clear the buff before using
some_file.read_to_end(reusable_buff);
// reusable_buff is automatically returned to the pool when it goes out of scope

Pull from pool and detach()

let pool: Pool<Vec<u8>> = Pool::new(32, || Vec::with_capacity(4096));
let mut reusable_buff = pool.try_pull().unwrap(); // returns None when the pool is saturated
reusable_buff.clear(); // clear the buff before using
let (pool, reusable_buff) = reusable_buff.detach();
let mut s = String::from(reusable_buff);
s.push_str("hello, world!");
pool.attach(s.into_bytes()); // reattach the buffer before reusable goes out of scope
// reusable_buff is automatically returned to the pool when it goes out of scope

Using Across Threads

You simply wrap the pool in a std::sync::Arc

let pool: Arc<Pool<T>> = Arc::new(Pool::new(cap, || T::new()));

Warning

Objects in the pool are not automatically reset, they are returned but NOT reset You may want to call object.reset() or object.clear() or any other equivalent for the object that you are using, after pulling from the pool

Check out the docs for more examples

Performance

The benchmarks compare alloc() vs pool.try_pull() vs pool.detach().

Check out the results

For those who don't like graphs, here's the raw output

Dependencies