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 operates 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 lock-free iterator (Iter)
for (index, element) in list.iter().enumerate() {
assert_eq!(index, *element);
}
// You can get the current iteration index
// iter.index() == iter.len() means iteration ended (iter.next() == None)
let mut iter = &mut 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!((&mut list.iter()).next(), None);
println!("Single thread example ended without errors");
Multi-producer, multi-consumer
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 example ended without errors");
}
Implementations
sourceimpl<T: Send + Sync> VoluntaryServitude<T>
impl<T: Send + Sync> VoluntaryServitude<T>
sourcepub fn par_extend<I>(&self, par_iter: I)where
I: IntoParallelIterator<Item = T>,
Available on crate feature rayon-traits
only.
pub fn par_extend<I>(&self, par_iter: I)where
I: IntoParallelIterator<Item = T>,
rayon-traits
only.Parallely Extends VS
like the ParallelExtend
trait, but without a mutable reference
let list = vs![1, 2, 3];
list.par_extend(vec![4, 5, 6]);
assert_eq!(list.iter().sum::<i32>(), 21);
sourceimpl<T> VoluntaryServitude<T>
impl<T> VoluntaryServitude<T>
sourcepub fn new() -> Self
pub fn new() -> Self
Creates new empty VS
(like Default
trait)
let list: VS<()> = VS::new();
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);
// Iter doesn't grow if it's empty (originally empty or was consumed)
assert!(iter.is_empty());
iter = list.iter();
list.append(8);
// Iter grows if it has not been consumed
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 (element, expected) in list.iter().zip(&[3, 2][..]) {
assert_eq!(element, expected);
}
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns current size, be careful with race conditions when using it since other threads can change it right after the read
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 since other threads can change it right after the read
let list = vs![];
assert!(list.is_empty());
list.append(());
assert!(!list.is_empty());
sourcepub fn clear(&self)
pub fn clear(&self)
Clears list (iterators referencing the 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 (other iterators referencing the old chain will still work)
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 swap(&self, other: &Self)
pub fn swap(&self, other: &Self)
Swaps two VS
let list = vs![3, 2];
let list2 = vs![5, 4];
list.swap(&list2);
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&5, &4]);
assert_eq!(list2.iter().collect::<Vec<_>>(), vec![&3, &2]);
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 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]);
// You can extend from another `VS` if you clone (or copy) each element
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]);
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: Deserialize<'a>> Deserialize<'a> for VoluntaryServitude<T>
Available on crate feature serde-traits
only.
impl<'a, T: 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<'a, T, Tab> Insertable<Tab> for &'a VoluntaryServitude<T>where
T: Insertable<Tab> + UndecoratedInsertRecord<Tab>,
Available on crate features diesel-traits
or diesel-sqlite
only.
impl<'a, T, Tab> Insertable<Tab> for &'a VoluntaryServitude<T>where
T: Insertable<Tab> + UndecoratedInsertRecord<Tab>,
Available on crate features
diesel-traits
or diesel-sqlite
only.sourcefn insert_into(
self,
table: T
) -> InsertStatement<T, Self::Values, Insert, NoReturningClause>where
Self: Sized,
fn insert_into(
self,
table: T
) -> InsertStatement<T, Self::Values, Insert, NoReturningClause>where
Self: Sized,
Insert
self
into a given table. 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>
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
sourceimpl<T> IntoSql for T
impl<T> IntoSql for T
sourcefn into_sql<T>(self) -> Self::Expressionwhere
Self: AsExpression<T> + Sized,
fn into_sql<T>(self) -> Self::Expressionwhere
Self: AsExpression<T> + Sized,
Convert
self
to an expression for Diesel’s query builder. Read moresourcefn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expressionwhere
&'a Self: AsExpression<T>,
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expressionwhere
&'a Self: AsExpression<T>,
Convert
&self
to an expression for Diesel’s query builder. Read more