Struct cow_arc::CowArc

source ·
pub struct CowArc<T> { /* private fields */ }
Expand description

A special form of an Arc reference that uses two nested Arcs to support a mechanism similar to copy-on-write or clone-on-write.

Effectively, this type reduces to Arc<Arc<Mutex<T>>>.

Unlike regular Arcs, which do not permit mutability if there are multiple strong or weak references to the data inside the Arc, the CowArc type can still allow interior mutability of the data T when there are multiple strong or weak references to it. This works by treating the inner Arc reference as the actual reference count, enabling it to differentiate between two states:

  • Exclusive: only a single strong reference to the internal Arc, meaning that it is okay to mutate the data.
  • Shared: there are multiple strong references to the internal Arc, meaning that it cannot be accessed mutably.

The inner data T is protected by a Mutex, allowing it to be borrowed mutably when the CowArc is in the Exclusive state only. The inner data can be borrowed immutably in either state.

This point of this data type is to encourage deeply copying data that’s in the Shared state in order to modify it, because deeply copying (cloning) Shared data will yield a new instance that starts in the Exclusive state by default.

Finally, the CowArc type can be “cloned” in two ways:

  • using the regular clone function, which actually affects the shared state by duplicating the inner reference, meaning that the CowArc will be in the shared state after invoking clone,
  • using the clone_shallow function, which does not affect the shared state and only duplicates the outer reference.

Implementations§

source§

impl<T> CowArc<T>

source

pub fn new(data: T) -> CowArc<T>

Crates a new CowArc that wraps the given data. The new CowArc will be in the Exclusive state, that is, not shared.

source

pub fn lock_as_ref(&self) -> DerefsTo<MutexGuard<'_, T>, T>

This acquires the lock on the inner Mutex wrapping the data T, and always succeeds because an CowArc always allows immutable access to the data, regardless of whether the data is Shared or Exclusive.

The returned value derefs to and can be used exactly like &T.

source

pub fn try_lock_as_ref(&self) -> Option<DerefsTo<MutexGuard<'_, T>, T>>

This attempts to acquire the lock on the inner Mutex wrapping the data T.

This returns None if the lock is currently held, but will always succeed if the lock is not held because an CowArc always allows immutable access to the data, regardless of whether the data is Shared or Exclusive.

The returned value derefs to and can be used exactly like &T.

source

pub fn lock_as_mut(&self) -> Option<DerefsToMut<MutexGuard<'_, T>, T>>

This acquires the lock on the inner Mutex wrapping the data T if it succeeds, which only occurs if this CowArc is in the Shared state, i.e., only a single strong reference to the inner Arc is held.

The returned value derefs to and can be used exactly like &mut T.

source

pub fn downgrade(this: &CowArc<T>) -> CowWeak<T>

Downgrades this CowArc into a CowWeak weak reference.

source

pub fn is_shared(&self) -> bool

Returns true if this CowArc is in the Shared state, and false if it is in the Exclusive state.

source

pub fn ptr_eq(&self, other: &Self) -> bool

Returns true if the two CowArcs point to the same value (not just values that compare as equal).

source

pub fn clone_shallow(&self) -> CowArc<T>

Creates a shallow clone of this CowArc that does not affect its Shared state. This means that it will not change it to Shared if it was Exclusive, nor will it increase the shared count if it was already Shared`.

Likewise, dropping the returned reference will not decrement the shared count nor potentially change its state from Shared back to Exclusive.

This is useful for passing around a duplicate reference to the same instance (of the outer reference) that will be used somewhere else temporarily, e.g., in the same context, without marking it as a totally separate shared instance.

The fact that this is different from the CowArc::clone function is what differentiates the behavior of CowArc from regular Arc.

Trait Implementations§

source§

impl<T> Clone for CowArc<T>

source§

fn clone(&self) -> CowArc<T>

Creates a shared reference to this CowArc and returns that shared reference as a new CowArc whose internal reference points to the same data.

This increases the shared count of this CowArc, and the returned new CowArc instance will have the same shared count and reference the same data.

1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for CowArc<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for CowArc<T>

§

impl<T> Send for CowArc<T>where T: Send,

§

impl<T> Sync for CowArc<T>where T: Send,

§

impl<T> Unpin for CowArc<T>

§

impl<T> !UnwindSafe for CowArc<T>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.