[][src]Struct persistent_stack::PersistentStack

pub struct PersistentStack<T>(_);

Concurrent persistent stack

Supportted operations:

  • clone O(1)
  • push O(1)
  • pop O(1)
  • iterate O(n)
use persistent_stack::PersistentStack;

let mut s1 = PersistentStack::new();
s1.push(1);
let mut s2 = s1.clone();
std::thread::spawn(move || {
    s2.push(2);
    assert_eq!(s2.iter().copied().collect::<Vec<_>>(), vec![2, 1]);
    std::thread::sleep(std::time::Duration::from_millis(20));
    s2.push(4);
    assert_eq!(s2.iter().copied().collect::<Vec<_>>(), vec![4, 2, 1]);
});
s1.push(3);
assert_eq!(s1.iter().copied().collect::<Vec<_>>(), vec![3, 1]);
std::thread::sleep(std::time::Duration::from_millis(20));
s1.push(5);
assert_eq!(s1.iter().copied().collect::<Vec<_>>(), vec![5, 3, 1]);

Implementations

impl<T> PersistentStack<T>[src]

pub fn new() -> PersistentStack<T>[src]

Creates new empty persistent stack

use persistent_stack::PersistentStack;

let s = PersistentStack::<i32>::new();
assert!(s.into_iter().next().is_none())

pub fn push(&mut self, data: T)[src]

Pushes data to end of self (affects only current copy of stack)

use persistent_stack::PersistentStack;
use std::sync::Arc;

let mut s1 = PersistentStack::new();
s1.push(1);
let mut s2 = s1.clone();
s2.push(2);
assert_eq!(s1.into_iter().collect::<Vec<_>>(), [&1]);
assert_eq!(s2.into_iter().collect::<Vec<_>>(), [&2, &1]);

pub fn pop(&mut self) -> Result<T, PersistentStackPopError>[src]

Pops value from stack and tries to return it

Returns Ok(data) if only this copy of stack owned data

Returns Err(CantUnwrap) if there are other copies, which own data

Returns Err(RootIsReached) if nothing to pop

use persistent_stack::{PersistentStack, PersistentStackPopError::*};

let mut s1 = PersistentStack::new();
s1.push(1);
s1.push(2);
let mut s2 = s1.clone();
s1.push(3);
s2.push(4);
assert_eq!(s2.pop(), Ok(4)); // only s2 owned 4
assert_eq!(s2.pop(), Err(CantUnwrap)); // s1 also owns 2
let mut s3 = s2.clone();
assert_eq!(s2.pop(), Err(CantUnwrap)); // s1 also owns 1
assert_eq!(s2.pop(), Err(RootIsReached)); // There are no elements in s2
s3.push(5);
assert_eq!(s3.iter().copied().collect::<Vec<_>>(), vec![5, 1]); // s3 is cloned, when s2 was [1]

pub fn iter(&self) -> PersistentStackIter<'_, T>

Notable traits for PersistentStackIter<'a, T>

impl<'a, T> Iterator for PersistentStackIter<'a, T> type Item = &'a T;
[src]

Creates iterator over self by reference

use persistent_stack::PersistentStack;

let mut s = PersistentStack::new();
s.push(1);
s.push(2);
s.push(3);
assert_eq!(s.iter().collect::<Vec<_>>(), [&3, &2, &1]);
s.push(4); // s didn't move out

Trait Implementations

impl<T> Clone for PersistentStack<T>[src]

impl<T> Default for PersistentStack<T>[src]

impl<'a, T> IntoIterator for &'a PersistentStack<T>[src]

type IntoIter = PersistentStackIter<'a, T>

Which kind of iterator are we turning this into?

type Item = &'a T

The type of the elements being iterated over.

Auto Trait Implementations

impl<T> RefUnwindSafe for PersistentStack<T> where
    T: RefUnwindSafe
[src]

impl<T> Send for PersistentStack<T> where
    T: Send + Sync
[src]

impl<T> Sync for PersistentStack<T> where
    T: Send + Sync
[src]

impl<T> Unpin for PersistentStack<T>[src]

impl<T> UnwindSafe for PersistentStack<T> where
    T: RefUnwindSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.