pub struct Stack<T> { /* private fields */ }
Expand description
Stack
is a lock-free concurrent last-in-first-out container.
Implementations§
Source§impl<T: 'static> Stack<T>
impl<T: 'static> Stack<T>
Sourcepub fn push_if<F: FnMut(Option<&Entry<T>>) -> bool>(
&self,
val: T,
cond: F,
) -> Result<Shared<Entry<T>>, T>
pub fn push_if<F: FnMut(Option<&Entry<T>>) -> bool>( &self, val: T, cond: F, ) -> Result<Shared<Entry<T>>, T>
Pushes an instance of T
if the newest entry satisfies the given condition.
§Errors
Returns an error along with the supplied instance if the condition is not met.
§Examples
use scc::Stack;
let stack: Stack<usize> = Stack::default();
stack.push(11);
assert!(stack.push_if(17, |e| e.map_or(false, |x| **x == 11)).is_ok());
assert!(stack.push_if(29, |e| e.map_or(false, |x| **x == 11)).is_err());
Sourcepub fn peek<'g>(&self, guard: &'g Guard) -> Option<&'g Entry<T>>
pub fn peek<'g>(&self, guard: &'g Guard) -> Option<&'g Entry<T>>
Returns a guarded reference to the newest entry.
Returns None
if the Stack
is empty. The returned reference can survive as long as the
associated Guard
is alive.
§Examples
use scc::ebr::Guard;
use scc::Stack;
let stack: Stack<usize> = Stack::default();
assert!(stack.peek(&Guard::new()).is_none());
stack.push(37);
stack.push(3);
assert_eq!(**stack.peek(&Guard::new()).unwrap(), 3);
Source§impl<T> Stack<T>
impl<T> Stack<T>
Sourcepub unsafe fn push_unchecked(&self, val: T) -> Shared<Entry<T>>
pub unsafe fn push_unchecked(&self, val: T) -> Shared<Entry<T>>
Pushes an instance of T
without checking the lifetime of T
.
Returns a Shared
holding a strong reference to the newly pushed entry.
§Safety
T::drop
can be run after the Stack
is dropped, therefore it is safe only if T::drop
does not access short-lived data or std::mem::needs_drop
is false
for T
,
§Examples
use scc::Stack;
let hello = String::from("hello");
let stack: Stack<&str> = Stack::default();
assert_eq!(unsafe { **stack.push_unchecked(hello.as_str()) }, "hello");
Sourcepub unsafe fn push_if_unchecked<F: FnMut(Option<&Entry<T>>) -> bool>(
&self,
val: T,
cond: F,
) -> Result<Shared<Entry<T>>, T>
pub unsafe fn push_if_unchecked<F: FnMut(Option<&Entry<T>>) -> bool>( &self, val: T, cond: F, ) -> Result<Shared<Entry<T>>, T>
Pushes an instance of T
if the newest entry satisfies the given condition without
checking the lifetime of T
.
§Errors
Returns an error along with the supplied instance if the condition is not met.
§Safety
T::drop
can be run after the Stack
is dropped, therefore it is safe only if T::drop
does not access short-lived data or std::mem::needs_drop
is false
for T
,
§Examples
use scc::Stack;
let hello = String::from("hello");
let stack: Stack<&str> = Stack::default();
assert!(unsafe { stack.push_if_unchecked(hello.as_str(), |e| e.is_none()).is_ok() });
Sourcepub fn pop(&self) -> Option<Shared<Entry<T>>>
pub fn pop(&self) -> Option<Shared<Entry<T>>>
Pops the newest entry.
Returns None
if the Stack
is empty.
§Examples
use scc::Stack;
let stack: Stack<usize> = Stack::default();
stack.push(37);
stack.push(3);
stack.push(1);
assert_eq!(stack.pop().map(|e| **e), Some(1));
assert_eq!(stack.pop().map(|e| **e), Some(3));
assert_eq!(stack.pop().map(|e| **e), Some(37));
assert!(stack.pop().is_none());
Sourcepub fn pop_all(&self) -> Self
pub fn pop_all(&self) -> Self
Pops all the entries at once, and passes each one of the popped entries to the supplied closure.
§Examples
use scc::Stack;
let stack: Stack<usize> = Stack::default();
stack.push(37);
stack.push(3);
let popped = stack.pop_all();
stack.push(1);
assert_eq!(stack.pop().map(|e| **e), Some(1));
assert!(stack.pop().is_none());
assert!(stack.is_empty());
assert_eq!(popped.pop().map(|e| **e), Some(3));
assert_eq!(popped.pop().map(|e| **e), Some(37));
assert!(popped.pop().is_none());
Sourcepub fn pop_if<F: FnMut(&Entry<T>) -> bool>(
&self,
cond: F,
) -> Result<Option<Shared<Entry<T>>>, Shared<Entry<T>>>
pub fn pop_if<F: FnMut(&Entry<T>) -> bool>( &self, cond: F, ) -> Result<Option<Shared<Entry<T>>>, Shared<Entry<T>>>
Pops the newest entry if the entry satisfies the given condition.
Returns None
if the Stack
is empty.
§Errors
Returns an error along with the newest entry if the given condition is not met.
§Examples
use scc::Stack;
let stack: Stack<usize> = Stack::default();
stack.push(3);
stack.push(1);
assert!(stack.pop_if(|v| **v == 3).is_err());
assert_eq!(stack.pop().map(|e| **e), Some(1));
assert_eq!(stack.pop_if(|v| **v == 3).ok().and_then(|e| e).map(|e| **e), Some(3));
assert!(stack.is_empty());
Sourcepub fn peek_with<R, F: FnOnce(Option<&Entry<T>>) -> R>(&self, reader: F) -> R
pub fn peek_with<R, F: FnOnce(Option<&Entry<T>>) -> R>(&self, reader: F) -> R
Peeks the newest entry.
§Examples
use scc::Stack;
let stack: Stack<usize> = Stack::default();
assert!(stack.peek_with(|v| v.is_none()));
stack.push(37);
stack.push(3);
assert_eq!(stack.peek_with(|v| **v.unwrap()), 3);
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of entries in the Stack
.
This method iterates over all the entries in the Stack
to count them, therefore its
time complexity is O(N)
.
§Examples
use scc::Stack;
let stack: Stack<usize> = Stack::default();
assert_eq!(stack.len(), 0);
stack.push(7);
stack.push(11);
assert_eq!(stack.len(), 2);
stack.pop();
stack.pop();
assert_eq!(stack.len(), 0);
Sourcepub fn iter<'g>(&self, guard: &'g Guard) -> Iter<'g, T> ⓘ
pub fn iter<'g>(&self, guard: &'g Guard) -> Iter<'g, T> ⓘ
Returns an Iter
.
§Examples
use scc::ebr::Guard;
use scc::Stack;
let stack: Stack<usize> = Stack::default();
assert_eq!(stack.iter(&Guard::new()).count(), 0);
stack.push(7);
stack.push(11);
stack.push(17);
let guard = Guard::new();
let mut iter = stack.iter(&guard);
assert_eq!(*iter.next().unwrap(), 17);
assert_eq!(*iter.next().unwrap(), 11);
assert_eq!(*iter.next().unwrap(), 7);
assert!(iter.next().is_none());