Expand description
AppendOnlyVec
This is a pretty simple type, which is a vector that you can push into, but cannot modify the elements of. The data structure never moves an element once allocated, so you can push to the vec even while holding references to elements that have already been pushed.
§Scaling
-
Accessing an element is O(1), but slightly more expensive than for a standard
Vec. -
Pushing a new element amortizes to O(1), but may require allocation of a new chunk.
§Example
use append_only_vec::AppendOnlyVec;
static V: AppendOnlyVec<String> = AppendOnlyVec::<String>::new();
let mut threads = Vec::new();
for thread_num in 0..10 {
threads.push(std::thread::spawn(move || {
for n in 0..100 {
let s = format!("thread {} says {}", thread_num, n);
let which = V.push(s.clone());
assert_eq!(&V[which], &s);
}
}));
}
for t in threads {
t.join();
}
assert_eq!(V.len(), 1000);§no_std
This crate needs only core and alloc. The std feature, which is on by
default, lets a thread that has waited a long time for another to finish a
push yield to the operating system instead of continuing to spin; without
it (default-features = false) the crate is no_std and always spins.
If you turn off default features on a platform that does have std, turn
std back on to keep that behavior.
Without std, a push that finds another push unfinished spins until it
completes. So never push from an interrupt handler, or from a task that
can preempt another task’s push without letting it run, to a vec that the
interrupted code also pushes to: the handler would spin forever.
On targets without atomic compare-and-swap (such as thumbv6m-none-eabi),
the portable-atomic feature uses the portable-atomic crate’s atomics
instead of core’s. As that crate explains, such targets also need one of
its features that says how to provide them (for instance critical-section).
Structs§
- Append
Only Vec - Into
Iter - An
Iteratorfor the values contained in theAppendOnlyVec