pub struct SeqArray<T: Copy + Clone + Send + Sync + 'static> { /* private fields */ }
Expand description
A thread-safe, concurrent, lock-free, and resizable array that uses interior mutability. Can be used as a basic building block for more complex concurrent data structures.
use seqmap::SeqArray;
let arr = SeqArray::<u32>::with_capacity(4);
arr.set(0, 1);
arr.set(1, 2);
std::thread::scope(|s| {
s.spawn(|| {
assert_eq!(arr.get(0), Ok(1));
assert_eq!(arr.get(1), Ok(2));
arr.set(2, 3);
});
s.spawn(|| {
assert_eq!(arr.get(0), Ok(1));
assert_eq!(arr.get(1), Ok(2));
arr.set(3, 4);
});
});
assert_eq!(arr.get(0), Ok(1));
assert_eq!(arr.get(1), Ok(2));
assert!(
(arr.get(2) == Ok(3) && arr.get(3) == Ok(4)) ||
(arr.get(2) == Ok(4) && arr.get(3) == Ok(3))
);
Implementations§
Source§impl<T: Copy + Clone + Send + Sync + 'static> SeqArray<T>
impl<T: Copy + Clone + Send + Sync + 'static> SeqArray<T>
Sourcepub fn with_capacity(cap: usize) -> Self
pub fn with_capacity(cap: usize) -> Self
Creates a new SeqArray
with the specified initial capacity.
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the approximate current length of the array (eventually consistent).
pub fn resizing(&self) -> bool
pub fn cloning(&self) -> bool
Sourcepub fn get_without_resize(&self, snapshot_cap: usize, index: usize) -> Result<T>
pub fn get_without_resize(&self, snapshot_cap: usize, index: usize) -> Result<T>
Tries to get the value at index
, returning if the array capacity has changed from
snapshot_cap
to something else.
Immediately returns if self.capacity() != snapshot_cap
.
Analogue of Self::get
.
Sourcepub fn get(&self, index: usize) -> Result<T>
pub fn get(&self, index: usize) -> Result<T>
Gets the value at index
, if present and within bounds.
During a resize, this will wait for the resize to complete before checking the value.
For a version that does not wait for resize, see Self::get_without_resize
.
Sourcepub fn unset(&self, index: usize) -> Result<T>
pub fn unset(&self, index: usize) -> Result<T>
Unsets the value at index
, returning the old value if it was set.
Because of the underlying data model, it is possible to have a sparse array without
having to use Option<T>
since the flag byte is used to track initialization safely.
Sourcepub fn unset_without_resize(
&self,
snapshot_cap: usize,
index: usize,
) -> Result<T>
pub fn unset_without_resize( &self, snapshot_cap: usize, index: usize, ) -> Result<T>
Analogue of Self::set
that does not wait for resize and will instead return early
if a resize is detected, based on whether the capacity has changed from snapshot_cap
.
Sourcepub fn set(&self, index: usize, value: T) -> Result<Option<T>>
pub fn set(&self, index: usize, value: T) -> Result<Option<T>>
Sets the value at index
, returning an error if the index is out of bounds.
This will wait for any ongoing resize to complete before setting the value. For a
version that does not wait for resize, see Self::set_without_resize
.
Sourcepub fn set_without_resize(
&self,
snapshot_cap: usize,
index: usize,
value: T,
) -> Result<Option<T>>
pub fn set_without_resize( &self, snapshot_cap: usize, index: usize, value: T, ) -> Result<Option<T>>
Analogue of Self::set
that does not wait for resize and will instead return early
if a resize is detected, based on whether the capacity has changed from snapshot_cap
.
Sourcepub fn cas_set(&self, index: usize, value: T) -> Result<()>
pub fn cas_set(&self, index: usize, value: T) -> Result<()>
Atomically sets the slot at index
to value
only if it is currently unset.
This will wait for any ongoing resize to complete before setting the value. For a
version that does not wait for resize, see Self::cas_set_without_resize
.
Sourcepub fn cas_set_without_resize(
&self,
snapshot_cap: usize,
index: usize,
value: T,
) -> Result<()>
pub fn cas_set_without_resize( &self, snapshot_cap: usize, index: usize, value: T, ) -> Result<()>
Analogue of Self::cas_set
that does not wait for resize and will instead return
early if a resize is detected, based on whether the capacity has changed from snapshot_cap
.