Switch branches/tags
Find file History
Pull request Compare This branch is 1 commit ahead of CryZe:sync.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
benches
examples
src
tests
.gitignore
.travis.yml
Cargo.toml
LICENSE
README.md

README.md

lifeguard

Object Pool Manager

API Documentation

Examples

Pool issues owned values wrapped in smartpointers.

extern crate lifeguard;
use lifeguard::*;

fn main() {
    let mut pool : Pool<String> = pool().with(StartingSize(10)).build();
    {
        let string = pool.new_from("Hello, World!"); // Pool size is now 9
    } // Values that have gone out of scope are automatically moved back into the pool.
    // Pool size is 10 again
}

Values taken from the pool can be dereferenced to access/mutate their contents.

extern crate lifeguard;
use lifeguard::*;

fn main() {
    let mut pool : Pool<String> = pool().with(StartingSize(10)).build();
    let mut string = pool.new_from("cat");
    string.push_str("s love eating mice"); //string.as_mut() also works
    assert_eq!("cats love eating mice", *string);
}

Values can be unwrapped, detaching them from the pool.

extern crate lifeguard;
use lifeguard::*;

fn main() {
    let mut pool : Pool<String> = pool().with(StartingSize(10)).build();
    {
        let string : String = pool.new().detach();
    } // The String goes out of scope and is dropped; it is not returned to the pool
    assert_eq!(9, pool.size());
}

Values can be manually entered into / returned to the pool.

extern crate lifeguard;
use lifeguard::*;

fn main() {
    let mut pool : Pool<String> = pool().with(StartingSize(10)).build();
    {
        let string : String = pool.detached(); // An unwrapped String, detached from the Pool
        assert_eq!(9, pool.size());
        let rstring : Recycled<String> = pool.attach(string); // The String is attached to the pool again
        assert_eq!(9, pool.size()); // but it is still checked out from the pool
    } // rstring goes out of scope and is added back to the pool
    assert_eq!(10, pool.size());
}

Pool's builder API can be used to customize the behavior of the pool.

extern crate lifeguard;
use lifeguard::*;

fn main() {
 let mut pool : Pool<String> = pool()
   // The pool will allocate 128 values for immediate use. More will be allocated on demand.
   .with(StartingSize(128))
   // The pool will only grow up to 4096 values. Further values will be dropped.
   .with(MaxSize(4096))
   // The pool will use this closure (or other object implementing Supply<T>) to allocate
   .with(Supplier(|| String::with_capacity(1024)))
   .build();
  // ...
}

Highly Unscientific Benchmarks

Benchmark source can be found here. Tests were run on a VirtualBox VM with 3 CPUs @ 3Ghz and 4GB of RAM.

Uninitialized Allocation

String::with_capacity Pool::new_rc Improvement Pool::new Improvement
1421183 ns/iter (+/- 161572) 841286 ns/iter (+/- 78602) ~40.80% 615875 ns/iter (+/- 53906) ~56.67%

Initialized Allocation

String::to_owned Pool::new_rc_from Improvement Pool::new_from Improvement
2256492 ns/iter (+/- 184229) 1652247 ns/iter (+/- 185096) ~26.78% 1430212 ns/iter (+/- 146108) ~36.62%

Vec<Vec<String>> Allocation

Adapted from this benchmark.

Vec::new + String::to_owned Pool::new_rc + Pool::new_rc_from Improvement Pool::new + Pool::new_from Improvement
1303594 ns/iter (+/- 98974) 723338 ns/iter (+/- 82782) ~44.51% 678324 ns/iter (+/- 88772) ~47.97%

Ideas and PRs welcome!

Inspired by frankmcsherry's recycler.