[−][src]Struct obj_pool::ObjPool
An object pool.
ObjPool<T>
holds an array of slots for storing objects.
Every slot is always in one of two states: occupied or vacant.
Essentially, this is equivalent to Vec<Option<T>>
.
Insert and remove
When inserting a new object into object pool, a vacant slot is found and then the object is placed
into the slot. If there are no vacant slots, the array is reallocated with bigger capacity.
The cost of insertion is amortized O(1)
.
When removing an object, the slot containing it is marked as vacant and the object is returned.
The cost of removal is O(1)
.
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let a = obj_pool.insert(10); let b = obj_pool.insert(20); assert_ne!(a, b); // ids are not the same assert_eq!(obj_pool.remove(a), Some(10)); assert_eq!(obj_pool.get(a), None); // there is no object with this `ObjId` anymore assert_eq!(obj_pool.insert(30), a); // slot is reused, got the same `ObjId`
Indexing
You can also access objects in an object pool by ObjId
.
However, accessing an object with invalid ObjId
will result in panic.
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let a = obj_pool.insert(10); let b = obj_pool.insert(20); assert_eq!(obj_pool[a], 10); assert_eq!(obj_pool[b], 20); obj_pool[a] += obj_pool[b]; assert_eq!(obj_pool[a], 30);
To access slots without fear of panicking, use get
and get_mut
, which return Option
s.
Methods
impl<T> ObjPool<T>
[src]
pub fn new() -> Self
[src]
Constructs a new, empty object pool.
The object pool will not allocate until objects are inserted into it.
Examples
use obj_pool::ObjPool; let mut obj_pool: ObjPool<i32> = ObjPool::new();
pub fn offset(&self) -> u32
[src]
Returns an offset for this ObjPool
, in release mode it's 0
, in debug mode it's
between 0
and u32::max_value() / 2
.
pub fn with_offset(offset: u32) -> Self
[src]
For debug purposes only.
pub fn obj_id_to_index(&self, obj_id: ObjId) -> u32
[src]
Get an index in the ObjPool
for the given ObjId
.
pub fn index_to_obj_id(&self, index: u32) -> ObjId
[src]
Make an ObjId
from an index in this ObjPool
.
pub fn with_capacity(cap: usize) -> Self
[src]
Constructs a new, empty object pool with the specified capacity (number of slots).
The object pool will be able to hold exactly capacity
objects without reallocating.
If capacity
is 0, the object pool will not allocate.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::with_capacity(10); assert_eq!(obj_pool.len(), 0); assert_eq!(obj_pool.capacity(), 10); // These inserts are done without reallocating... for i in 0..10 { obj_pool.insert(i); } assert_eq!(obj_pool.capacity(), 10); // ... but this one will reallocate. obj_pool.insert(11); assert!(obj_pool.capacity() > 10);
pub fn capacity(&self) -> usize
[src]
Returns the number of slots in the object pool.
Examples
use obj_pool::ObjPool; let obj_pool: ObjPool<i32> = ObjPool::with_capacity(10); assert_eq!(obj_pool.capacity(), 10);
pub fn len(&self) -> u32
[src]
Returns the number of occupied slots in the object pool.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); assert_eq!(obj_pool.len(), 0); for i in 0..10 { obj_pool.insert(()); assert_eq!(obj_pool.len(), i + 1); }
pub fn is_empty(&self) -> bool
[src]
Returns true
if all slots are vacant.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); assert!(obj_pool.is_empty()); obj_pool.insert(1); assert!(!obj_pool.is_empty());
pub fn next_vacant(&mut self) -> ObjId
[src]
Returns the ObjId
of the next inserted object if no other
mutating calls take place in between.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let a = obj_pool.next_vacant(); let b = obj_pool.insert(1); assert_eq!(a, b); let c = obj_pool.next_vacant(); let d = obj_pool.insert(2); assert_eq!(c, d);
pub fn insert(&mut self, object: T) -> ObjId
[src]
Inserts an object into the object pool and returns the ObjId
of this object.
The object pool will reallocate if it's full.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let a = obj_pool.insert(1); let b = obj_pool.insert(2); assert!(a != b);
pub fn remove(&mut self, obj_id: ObjId) -> Option<T>
[src]
Removes the object stored by ObjId
from the object pool and returns it.
None
is returned in case the there is no object with such an ObjId
.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let a = obj_pool.insert("hello"); assert_eq!(obj_pool.len(), 1); assert_eq!(obj_pool.remove(a), Some("hello")); assert_eq!(obj_pool.len(), 0); assert_eq!(obj_pool.remove(a), None);
pub fn clear(&mut self)
[src]
Clears the object pool, removing and dropping all objects it holds. Keeps the allocated memory for reuse.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); for i in 0..10 { obj_pool.insert(i); } assert_eq!(obj_pool.len(), 10); obj_pool.clear(); assert_eq!(obj_pool.len(), 0);
pub fn get(&self, obj_id: ObjId) -> Option<&T>
[src]
Returns a reference to the object by its ObjId
.
If object is not found with given obj_id
, None
is returned.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let obj_id = obj_pool.insert("hello"); assert_eq!(obj_pool.get(obj_id), Some(&"hello")); obj_pool.remove(obj_id); assert_eq!(obj_pool.get(obj_id), None);
pub fn get_mut(&mut self, obj_id: ObjId) -> Option<&mut T>
[src]
Returns a mutable reference to the object by its ObjId
.
If object can't be found, None
is returned.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let obj_id = obj_pool.insert(7); assert_eq!(obj_pool.get_mut(obj_id), Some(&mut 7)); *obj_pool.get_mut(obj_id).unwrap() *= 10; assert_eq!(obj_pool.get_mut(obj_id), Some(&mut 70));
pub unsafe fn get_unchecked(&self, obj_id: ObjId) -> &T
[src]
Returns a reference to the object by its ObjId
.
Safety
Behavior is undefined if object can't be found.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let obj_id = obj_pool.insert("hello"); unsafe { assert_eq!(&*obj_pool.get_unchecked(obj_id), &"hello") }
pub unsafe fn get_unchecked_mut(&mut self, obj_id: ObjId) -> &mut T
[src]
Returns a mutable reference to the object by its ObjId
.
Safety
Behavior is undefined if object can't be found.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let obj_id = obj_pool.insert("hello"); unsafe { assert_eq!(&*obj_pool.get_unchecked_mut(obj_id), &"hello") }
pub fn swap(&mut self, a: ObjId, b: ObjId)
[src]
Swaps two objects in the object pool.
The two ObjId
s are a
and b
.
Panics
Panics if any of the ObjId
s is invalid.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); let a = obj_pool.insert(7); let b = obj_pool.insert(8); obj_pool.swap(a, b); assert_eq!(obj_pool.get(a), Some(&8)); assert_eq!(obj_pool.get(b), Some(&7));
pub fn reserve(&mut self, additional: u32)
[src]
Reserves capacity for at least additional
more objects to be inserted. The object pool may
reserve more space to avoid frequent reallocations.
Panics
Panics if the new capacity overflows u32
.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); obj_pool.insert("hello"); obj_pool.reserve(10); assert!(obj_pool.capacity() >= 11);
pub fn reserve_exact(&mut self, additional: u32)
[src]
Reserves the minimum capacity for exactly additional
more objects to be inserted.
Note that the allocator may give the object pool more space than it requests.
Panics
Panics if the new capacity overflows u32
.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); obj_pool.insert("hello"); obj_pool.reserve_exact(10); assert!(obj_pool.capacity() >= 11);
ⓘImportant traits for Iter<'a, T>pub fn iter(&self) -> Iter<T>
[src]
Returns an iterator over occupied slots.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); obj_pool.insert(1); obj_pool.insert(2); obj_pool.insert(4); let mut iterator = obj_pool.iter(); assert_eq!(iterator.next(), Some((obj_pool.index_to_obj_id(0), &1))); assert_eq!(iterator.next(), Some((obj_pool.index_to_obj_id(1), &2))); assert_eq!(iterator.next(), Some((obj_pool.index_to_obj_id(2), &4)));
ⓘImportant traits for IterMut<'a, T>pub fn iter_mut(&mut self) -> IterMut<T>
[src]
Returns an iterator that returns mutable references to objects.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::new(); obj_pool.insert("zero".to_string()); obj_pool.insert("one".to_string()); obj_pool.insert("two".to_string()); let offset = obj_pool.offset(); for (obj_id, object) in obj_pool.iter_mut() { *object = obj_id.into_index(offset).to_string() + " " + object; } let mut iterator = obj_pool.iter(); assert_eq!(iterator.next(), Some((obj_pool.index_to_obj_id(0), &"0 zero".to_string()))); assert_eq!(iterator.next(), Some((obj_pool.index_to_obj_id(1), &"1 one".to_string()))); assert_eq!(iterator.next(), Some((obj_pool.index_to_obj_id(2), &"2 two".to_string())));
pub fn shrink_to_fit(&mut self)
[src]
Shrinks the capacity of the object pool as much as possible.
It will drop down as close as possible to the length but the allocator may still inform the object pool that there is space for a few more elements.
Examples
use obj_pool::ObjPool; let mut obj_pool = ObjPool::with_capacity(10); obj_pool.insert("first".to_string()); obj_pool.insert("second".to_string()); obj_pool.insert("third".to_string()); assert_eq!(obj_pool.capacity(), 10); obj_pool.shrink_to_fit(); assert!(obj_pool.capacity() >= 3);
Trait Implementations
impl<T> AsMut<ObjPool<T>> for ObjPool<T>
[src]
impl<T> Default for ObjPool<T>
[src]
impl<T: Clone> Clone for ObjPool<T>
[src]
fn clone(&self) -> Self
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<T> AsRef<ObjPool<T>> for ObjPool<T>
[src]
impl<T> IntoIterator for ObjPool<T>
[src]
type Item = (ObjId, T)
The type of the elements being iterated over.
type IntoIter = IntoIter<T>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<'a, T> IntoIterator for &'a ObjPool<T>
[src]
type Item = (ObjId, &'a T)
The type of the elements being iterated over.
type IntoIter = Iter<'a, T>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<'a, T> IntoIterator for &'a mut ObjPool<T>
[src]
type Item = (ObjId, &'a mut T)
The type of the elements being iterated over.
type IntoIter = IterMut<'a, T>
Which kind of iterator are we turning this into?
fn into_iter(self) -> Self::IntoIter
[src]
impl<T> Index<ObjId> for ObjPool<T>
[src]
impl<T> IndexMut<ObjId> for ObjPool<T>
[src]
impl<T> Debug for ObjPool<T>
[src]
impl<T> FromIterator<T> for ObjPool<T>
[src]
fn from_iter<U: IntoIterator<Item = T>>(iter: U) -> ObjPool<T>
[src]
Auto Trait Implementations
impl<T> Send for ObjPool<T> where
T: Send,
T: Send,
impl<T> Unpin for ObjPool<T> where
T: Unpin,
T: Unpin,
impl<T> Sync for ObjPool<T> where
T: Sync,
T: Sync,
impl<T> UnwindSafe for ObjPool<T> where
T: UnwindSafe,
T: UnwindSafe,
impl<T> RefUnwindSafe for ObjPool<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
Blanket Implementations
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<I> IntoIterator for I where
I: Iterator,
[src]
I: Iterator,
type Item = <I as Iterator>::Item
The type of the elements being iterated over.
type IntoIter = I
Which kind of iterator are we turning this into?
fn into_iter(self) -> I
[src]
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,