pub struct VoluntaryServitude<T>(_);
Appendable list with lock-free iterator (also called VS
)
let (a, b, c) = (0usize, 1usize, 2usize);
let list = vs![a, b, c];
assert_eq!(list.iter().collect::<Vec<_>>(), vec![&a, &b, &c]);
assert_eq!(list.len(), 3);
for (index, element) in list.iter().enumerate() {
assert_eq!(index, *element);
}
let mut iter = &mut list.iter();
assert_eq!(iter.index(), 0);
assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.index(), 1);
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");
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![];
for _ in 0..PRODUCERS {
let l = Arc::clone(&list);
handlers.push(spawn(move || {
let _ = (0..ELEMENTS).map(|i| l.append(i)).count();
}));
}
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 };
}));
}
for handler in handlers.into_iter() {
handler.join().expect("Failed to join thread");
}
println!("Multi-thread example ended without errors");
}
This is supported on feature="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);
Creates new empty VS
(like Default
trait)
let list: VS<()> = VS::new();
assert!(list.is_empty());
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]);
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);
}
Returns current size, be careful with race conditions when using it since other threads can change it right after the read
Relaxed
ordering is used to extract the length, so you shouldn't depend on this being sequentially consistent, only atomic
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);
Checks if VS
is currently empty, be careful with race conditions when using it since other threads can change it right after the read
Relaxed
ordering is used to extract the length, so you shouldn't depend on this being sequentially consistent, only atomic
let list = vs![];
assert!(list.is_empty());
list.append(());
assert!(!list.is_empty());
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);
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);
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]);
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]);
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]);
Returns the "default value" for a type. Read more
Extends a collection with the contents of an iterator. Read more
Extends a collection with the contents of an iterator. Read more
Formats the value using the given formatter. Read more
Creates an instance of the collection from the parallel iterator par_iter
. Read more
Extends an instance of the collection with the elements drawn from the parallel iterator par_iter
. Read more
Serialize this value into the given Serde serializer. Read more
Deserialize this value from the given Serde deserializer. Read more
🔬 This is a nightly-only experimental API. (try_from
)
The type returned in the event of a conversion error.
🔬 This is a nightly-only experimental API. (try_from
)
Immutably borrows from an owned value. Read more
🔬 This is a nightly-only experimental API. (get_type_id
)
this method will likely be replaced by an associated static
🔬 This is a nightly-only experimental API. (try_from
)
The type returned in the event of a conversion error.
🔬 This is a nightly-only experimental API. (try_from
)
Mutably borrows from an owned value. Read more