Struct voluntary_servitude::VoluntaryServitude
source · pub struct VoluntaryServitude<T>(_);
Expand description
Appendable list with lock-free iterator (also called VS
)
Examples
Single thread
let (a, b, c) = (0usize, 1usize, 2usize);
// VS alias to VoluntaryServitude
// vs! alias to voluntary_servitude! (and operate like vec!)
let list = vs![a, b, c];
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&a, &b, &c]);
// Current VS's length
// Be careful with race conditions since the value, when used, may not be true anymore
assert_eq!(list.len(), 3);
// The 'iter' method makes a one-time lock-free iterator (Iter)
for (index, element) in list.iter().enumerate() {
assert_eq!(index, *element);
}
// You can get the current iteration index
// iter.next() == iter.len() means iteration ended (iter.next() == None)
let mut iter = list.iter();
assert_eq!(iter.index(), 0);
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.index(), 1);
// List can also be cleared (but current iterators are not affected)
list.clear();
assert_eq!(iter.len(), 3);
assert_eq!(list.len(), 0);
assert_eq!(list.iter().len(), 0);
assert_eq!(list.iter().next(), None);
println!("Single thread example ended without errors");
Multi-producer, multi-consumer
#[macro_use]
extern crate voluntary_servitude;
use std::{sync::Arc, thread::spawn};
const CONSUMERS: usize = 8;
const PRODUCERS: usize = 4;
const ELEMENTS: usize = 10_000_000;
fn main() {
let list = Arc::new(vs![]);
let mut handlers = vec![];
// Creates producer threads to insert 10k elements
for _ in 0..PRODUCERS {
let l = Arc::clone(&list);
handlers.push(spawn(move || {
let _ = (0..ELEMENTS).map(|i| l.append(i)).count();
}));
}
// Creates consumer threads to print number of elements
// Until all of them are inserted
for _ in 0..CONSUMERS {
const TOTAL: usize = PRODUCERS * ELEMENTS;
let consumer = Arc::clone(&list);
handlers.push(spawn(move || loop {
let count = consumer.iter().count();
println!("{} elements", count);
if count >= TOTAL { break };
}));
}
// Join threads
for handler in handlers.into_iter() {
handler.join().expect("Failed to join thread");
}
println!("Multi-thread rust example ended without errors");
}
Implementations
sourceimpl<T> VoluntaryServitude<T>
impl<T> VoluntaryServitude<T>
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns current size, be careful with race conditions when using it
let list = vs![3, 2];
assert_eq!(list.len(), 2);
list.append(5);
assert_eq!(list.len(), 3);
list.clear();
assert_eq!(list.len(), 0);
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Checks if VS
is currently empty, be careful with race conditions when using it
let list = vs![];
assert!(list.is_empty());
list.append(());
assert!(!list.is_empty());
sourcepub fn append(&self, value: T)
pub fn append(&self, value: T)
Inserts element after last node
let list = vs![];
let mut iter = list.iter();
list.append(3);
assert!(iter.is_empty());
iter = list.iter();
list.append(8);
assert_eq!(iter.collect::<Vec<_>>(), vec![&3, &8]);
sourcepub fn iter(&self) -> Iter<'_, T> ⓘ
pub fn iter(&self) -> Iter<'_, T> ⓘ
Makes lock-free iterator based on VS
let list = vs![3, 2];
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&3, &2]);
for (index, element) in list.iter().enumerate() {
assert_eq!(*element, [3, 2][index]);
}
sourcepub fn clear(&self)
pub fn clear(&self)
Clears list (iterators referencing old chain will still work)
let list = vs![3, 2];
let iter = list.iter();
list.clear();
assert_eq!(iter.len(), 2);
assert_eq!(list.len(), 0);
assert_eq!(list.iter().len(), 0);
sourcepub fn empty(&self) -> Iter<'_, T> ⓘ
pub fn empty(&self) -> Iter<'_, T> ⓘ
Clears list returning iterator to it
let list = vs![3, 2];
let iter = list.empty();
assert_eq!(iter.len(), 2);
assert_eq!(list.len(), 0);
assert_eq!(list.iter().len(), 0);
sourcepub fn extend<I: IntoIterator<Item = T>>(&self, iter: I)
pub fn extend<I: IntoIterator<Item = T>>(&self, iter: I)
Extends VS
like the Extend
trait, but without needing a mutable reference
let list = vs![1, 2, 3];
list.extend(vec![4, 5, 6]);
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);
let list = vs![1, 2, 3];
list.extend(vs![4, 5, 6].iter().cloned());
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);
let list = vs![1, 2, 3];
list.extend(vec![&4, &5, &6].into_iter().cloned());
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5, &6]);
sourceimpl<T: Send + Sync> VoluntaryServitude<T>
impl<T: Send + Sync> VoluntaryServitude<T>
sourcepub fn par_extend<I: IntoParallelIterator<Item = T>>(&self, par_iter: I)
Available on crate feature rayon-traits
only.
pub fn par_extend<I: IntoParallelIterator<Item = T>>(&self, par_iter: I)
rayon-traits
only.Parallely Extends VS
like the ParallelExtend trait, but without a mutable reference
let list = vs![1u8, 2, 3];
list.par_extend(vec![4, 5, 6]);
assert_eq!(list.iter().sum::<u8>(), 21u8);
Trait Implementations
sourceimpl<T: Debug> Debug for VoluntaryServitude<T>
impl<T: Debug> Debug for VoluntaryServitude<T>
sourceimpl<T> Default for VoluntaryServitude<T>
impl<T> Default for VoluntaryServitude<T>
sourceimpl<'a, T: 'a + Deserialize<'a>> Deserialize<'a> for VoluntaryServitude<T>
Available on crate feature serde-traits
only.
impl<'a, T: 'a + Deserialize<'a>> Deserialize<'a> for VoluntaryServitude<T>
Available on crate feature
serde-traits
only.sourcefn deserialize<D: Deserializer<'a>>(des: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'a>>(des: D) -> Result<Self, D::Error>
Deserialize this value from the given Serde deserializer. Read more
sourceimpl<'a, T: 'a + Copy> Extend<&'a T> for VoluntaryServitude<T>
impl<'a, T: 'a + Copy> Extend<&'a T> for VoluntaryServitude<T>
sourcefn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I)
Extends a collection with the contents of an iterator. Read more
sourcefn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (
extend_one
)Extends a collection with exactly one element.
sourcefn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (
extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
sourceimpl<T> Extend<T> for VoluntaryServitude<T>
impl<T> Extend<T> for VoluntaryServitude<T>
sourcefn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
Extends a collection with the contents of an iterator. Read more
sourcefn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
🔬This is a nightly-only experimental API. (
extend_one
)Extends a collection with exactly one element.
sourcefn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
🔬This is a nightly-only experimental API. (
extend_one
)Reserves capacity in a collection for the given number of additional elements. Read more
sourceimpl<'a, T: 'a + Copy> FromIterator<&'a T> for VoluntaryServitude<T>
impl<'a, T: 'a + Copy> FromIterator<&'a T> for VoluntaryServitude<T>
sourcefn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self
Creates a value from an iterator. Read more
sourceimpl<T> FromIterator<T> for VoluntaryServitude<T>
impl<T> FromIterator<T> for VoluntaryServitude<T>
sourcefn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Creates a value from an iterator. Read more
sourceimpl<T: Send + Sync> FromParallelIterator<T> for VoluntaryServitude<T>
Available on crate feature rayon-traits
only.
impl<T: Send + Sync> FromParallelIterator<T> for VoluntaryServitude<T>
Available on crate feature
rayon-traits
only.sourcefn from_par_iter<I: IntoParallelIterator<Item = T>>(par_iter: I) -> Self
fn from_par_iter<I: IntoParallelIterator<Item = T>>(par_iter: I) -> Self
Creates an instance of the collection from the parallel iterator
par_iter
. Read moresourceimpl<T: Send + Sync> ParallelExtend<T> for VoluntaryServitude<T>
Available on crate feature rayon-traits
only.
impl<T: Send + Sync> ParallelExtend<T> for VoluntaryServitude<T>
Available on crate feature
rayon-traits
only.sourcefn par_extend<I: IntoParallelIterator<Item = T>>(&mut self, par_iter: I)
fn par_extend<I: IntoParallelIterator<Item = T>>(&mut self, par_iter: I)
Extends an instance of the collection with the elements drawn
from the parallel iterator
par_iter
. Read moreAuto Trait Implementations
impl<T> RefUnwindSafe for VoluntaryServitude<T>where
T: RefUnwindSafe,
impl<T> Send for VoluntaryServitude<T>where
T: Send + Sync,
impl<T> Sync for VoluntaryServitude<T>where
T: Send + Sync,
impl<T> Unpin for VoluntaryServitude<T>
impl<T> UnwindSafe for VoluntaryServitude<T>where
T: RefUnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more