Struct wrc::Wrc [−][src]
Wrc
A thread-safe weight reference counting smart-pointer for Rust.
Weighted Reference Counting
By using weights instead of direct reference counting Wrc
requires
roughly half as many synchronisation operations and writes to the heap.
Every time a Wrc
is cloned its weight is split in two, with half
allocated to the parent and half allocated to the child. When a Wrc
is
dropped its weight is removed from the total. When the total weight
declines to zero then the referenced object is dropped.
The type Wrc<T>
provides shared ownership of type T
, allocated on the
heap. Invoking clone
on Wrc
produces a new pointer to the shared value
in the heap. When the last Wrc
pointer is dropped then the pointed-to
value is also dropped.
See Wikipedia for more information about weighted reference counting.
Thread Safety
Wrc<T>
uses atomic operations for its weight manipulations. This means
that it is thread-safe. The disadvantage is that atomic operations are more
expensive than ordinary memory accesses. The use of the weighted reference
counting algorithm drastically reduces the number of synchronisation
operations required to keep track of references.
Cycles
Currently there is no support in Wrc
for weak pointers or any other
cycle breaking. If your usage causes you to create cycles of references
you may want to investigate an alternative solution or manually force
destruction of those objects.
Cloning references
Creating a new reference from an existing reference counted pointer is done
using the Clone
trait, implemented for Wrc<T>
.
Deref
behaviour
Wrc<T>
automatically dereferences to T
(via the Deref
trait), so you
can call T
’s methods on a value of type WTC<T>
.
Examples
Sharing some immutable data between threads:
use wrc::Wrc; use std::thread; let five = Wrc::new(5); for _ in 0..10 { let five = five.clone(); thread::spawn(move || { println!("{:?}", five); }); }
Sharing a mutable AtomicUsize
:
use wrc::Wrc; use std::sync::atomic::{AtomicUsize, Ordering}; use std::thread; let val = Wrc::new(AtomicUsize::new(5)); for _ in 0..10 { let val = val.clone(); thread::spawn(move || { let v = val.fetch_add(1, Ordering::SeqCst); println!("{:?}", v); }); }
See the rc documentation for more examples of reference counting in general.
Implementations
impl<T> Wrc<T>
[src]
pub fn new(data: T) -> Wrc<T>
[src]
pub fn total_weight(wrc: &Wrc<T>) -> usize
[src]
Return the total weight of all references. Only used for testing. You’re unlikely to need it.
Trait Implementations
impl<T> Clone for Wrc<T>
[src]
fn clone(&self) -> Self
[src]
Makes a clone of the Wrc
pointer.
This creates another pointer with the same ptr value, dividing the weight evenly between the new reference and the old reference.
Examples
use wrc::Wrc; let five = Wrc::new(5); five.clone();
pub fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<T: Debug> Debug for Wrc<T>
[src]
impl<T: Default> Default for Wrc<T>
[src]
impl<T> Deref for Wrc<T>
[src]
type Target = T
The resulting type after dereferencing
fn deref(&self) -> &Self::Target
[src]
The method called to dereference a value
impl<T> DerefMut for Wrc<T>
[src]
impl<T: Display> Display for Wrc<T>
[src]
impl<T: ?Sized> Drop for Wrc<T>
[src]
fn drop(&mut self)
[src]
Drops the Wrc
.
This will decrement the total weight of the referenced object by the weight of this reference.
Examples
use wrc::Wrc; struct Foo; impl Drop for Foo { fn drop(&mut self) { println!("dropped!"); } } let foo = Wrc::new(Foo); let foo2 = foo.clone(); drop(foo); // Doesn't print anything drop(foo2); // Prints "dropped!"
impl<T: Eq> Eq for Wrc<T>
[src]
impl<T: Hash> Hash for Wrc<T>
[src]
fn hash<H: Hasher>(&self, state: &mut H)
[src]
pub fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<T: Ord> Ord for Wrc<T>
[src]
fn cmp(&self, other: &Wrc<T>) -> Ordering
[src]
Comparison for two Wrc
’s
The two are compared by calling cmp()
on their ptr values.
#[must_use]pub fn max(self, other: Self) -> Self
1.21.0[src]
#[must_use]pub fn min(self, other: Self) -> Self
1.21.0[src]
#[must_use]pub fn clamp(self, min: Self, max: Self) -> Self
1.50.0[src]
impl<T: PartialEq> PartialEq<Wrc<T>> for Wrc<T>
[src]
fn eq(&self, other: &Wrc<T>) -> bool
[src]
Equality for Wrc<T>
Two Wrc
’s are equal if their ptr values are equal.
#[must_use]pub fn ne(&self, other: &Rhs) -> bool
1.0.0[src]
impl<T: PartialOrd> PartialOrd<Wrc<T>> for Wrc<T>
[src]
fn partial_cmp(&self, other: &Wrc<T>) -> Option<Ordering>
[src]
Partial comparison for two Wrc
’s
The two are compared by calling partial_cmp()
on their ptr values.
fn lt(&self, other: &Wrc<T>) -> bool
[src]
Less-than comparison for two Wrc
’s
The two are compared by calling <
on their ptr values.
fn le(&self, other: &Wrc<T>) -> bool
[src]
Less-than or equal to comparison for two Wrc
’s
The two are compared by calling <=
on their ptr values.
fn gt(&self, other: &Wrc<T>) -> bool
[src]
Greater-than comparison for two Wrc
’s
The two are compared by calling >
on their ptr values.
fn ge(&self, other: &Wrc<T>) -> bool
[src]
Greater-than or equal comparison for two Wrc
’s
The two are compared by calling >=
on their ptr values.
impl<T: ?Sized + Sync + Send> Send for Wrc<T>
[src]
impl<T: ?Sized + Sync + Send> Sync for Wrc<T>
[src]
Auto Trait Implementations
impl<T> !RefUnwindSafe for Wrc<T>
impl<T: ?Sized> Unpin for Wrc<T>
impl<T: ?Sized> UnwindSafe for Wrc<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
pub fn to_owned(&self) -> T
[src]
pub fn clone_into(&self, target: &mut T)
[src]
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
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.
pub 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>,