seqmap 0.1.4

A blazing fast seqlock-based concurrent hashmap where every data cell is its own seqlock, suitable for thousands of concurrent readers and writers
Documentation
// use crossbeam_utils::CachePadded;
// use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

// use crate::*;

// /// A concurrent, lock-free analogue to [`Vec<T>`] which can be shared safely between threads,
// /// uses interior mutability, can grow dynamically, and supports concurrent push and pop
// /// operations.
// ///
// /// ```
// /// use seqmap::SeqVec;
// ///
// /// let vec = SeqVec::<u32>::with_capacity(2);
// ///
// /// vec.push(1);
// /// vec.push(2);
// ///
// /// std::thread::scope(|s| {
// ///     s.spawn(|| {
// ///         assert_eq!(vec.get(0), Some(1));
// ///         assert!(vec.len() >= 2);
// ///         assert!(vec.len() < 4);
// ///         vec.push(3);
// ///     });
// ///     s.spawn(|| {
// ///         assert_eq!(vec.get(1), Some(2));
// ///         assert!(vec.len() >= 2);
// ///         assert!(vec.len() < 4);
// ///         vec.push(4);
// ///     });
// /// });
// ///
// /// assert_eq!(vec.get(0), Some(1));
// /// assert_eq!(vec.get(1), Some(2));
// /// assert!(
// ///     (vec.get(2) == Some(3) && vec.get(3) == Some(4)) ||
// ///     (vec.get(2) == Some(4) && vec.get(3) == Some(3))
// /// );
// /// ```
// pub struct SeqVec<T: Copy + Clone + Send + Sync + 'static> {
//     arr: SeqArray<T>,
//     len: CachePadded<AtomicUsize>,
//     pushing: CachePadded<AtomicBool>,
// }

// impl<T: Copy + Clone + Send + Sync + 'static> SeqVec<T> {
//     /// Creates a new [`SeqVec`] with the specified initial capacity.
//     #[inline(always)]
//     pub fn with_capacity(cap: usize) -> Self {
//         SeqVec {
//             arr: SeqArray::with_capacity(cap),
//             len: CachePadded::new(AtomicUsize::new(0)),
//             pushing: CachePadded::new(AtomicBool::new(false)),
//         }
//     }

//     /// Returns the current capacity of the [`SeqVec`].
//     #[inline(always)]
//     pub fn capacity(&self) -> usize {
//         self.arr.capacity()
//     }

//     /// Returns the current length of the [`SeqVec`] using [`Ordering::Acquire`] ordering.
//     #[inline(always)]
//     pub fn len(&self) -> usize {
//         self.len.load(Ordering::Acquire)
//     }

//     /// Attempts to get the value at the specified index, waiting before returning in the event
//     /// of a resize.
//     #[inline(always)]
//     pub fn get(&self, index: usize) -> Option<T> {
//         if index >= self.len() {
//             return None;
//         }
//         self.arr.get(index).ok()
//     }

//     /// Attempts to set the data slot at the specified index to the specified value.
//     ///
//     /// If a resize is in progress, this will block until the resize is complete.
//     pub fn set(&self, index: usize, value: T) -> Result<Option<T>> {
//         self.arr.set(index, value)
//     }

//     pub fn push(&self, value: T) -> usize {
//         loop {
//             while self.pushing.swap(true, Ordering::AcqRel) {
//                 std::thread::yield_now();
//             }
//             let idx = self.len();
//             let cap = self.capacity();
//             if idx < cap {
//                 if !self.arr.set_without_resize(cap, idx, value).is_ok() {
//                     // If set fails, it means the array is full or index is out of bounds
//                     self.pushing.store(false, Ordering::Release);
//                     std::thread::yield_now();
//                     continue;
//                 }
//                 self.len.fetch_add(1, Ordering::AcqRel);
//                 self.pushing.store(false, Ordering::Release);
//                 return idx;
//             } else {
//                 // retry after resize
//                 self.arr.scale_up();
//                 self.pushing.store(false, Ordering::Release);
//             }
//         }
//     }

//     /// Pops the last element from the [`SeqVec`], returning it if it exists.
//     ///
//     /// Only one `push` or `pop` operation can be in progress at a time.
//     pub fn pop(&self) -> Option<T> {
//         loop {
//             while self.pushing.swap(true, Ordering::AcqRel) {
//                 std::thread::yield_now();
//             }
//             let cap = self.capacity();
//             let len = self.len();
//             if len == 0 {
//                 self.pushing.store(false, Ordering::Release);
//                 return None;
//             }
//             let idx = len.saturating_sub(1);
//             if idx < cap {
//                 let old = self.arr.get_without_resize(cap, idx);
//                 if matches!(old, Err(Error::Resized | Error::Resizing)) {
//                     // If resizing, retry
//                     self.pushing.store(false, Ordering::Release);
//                     std::thread::yield_now();
//                     continue;
//                 }
//                 let unset = self.arr.unset_without_resize(cap, idx);
//                 if matches!(unset, Err(Error::Resized | Error::Resizing)) {
//                     // If resizing, retry
//                     self.pushing.store(false, Ordering::Release);
//                     std::thread::yield_now();
//                     continue;
//                 }
//                 if old.is_err() || !unset.is_ok() {
//                     self.pushing.store(false, Ordering::Release);
//                     return None;
//                 }
//                 self.len.fetch_sub(1, Ordering::AcqRel);
//                 self.pushing.store(false, Ordering::Release);
//                 return old.ok();
//             } else {
//                 self.pushing.store(false, Ordering::Release);
//                 return None;
//             }
//         }
//     }

//     /// Reserves capacity for at least `new_cap` elements in the [`SeqVec`].
//     pub fn reserve(&self, new_cap: usize) {
//         self.arr.reserve(new_cap);
//     }
// }

// impl<T: Copy + Clone + Send + Sync + 'static> Clone for SeqVec<T> {
//     fn clone(&self) -> Self {
//         let arr = self.arr.clone();
//         let cap = arr.capacity();
//         let len = self.len.load(Ordering::Acquire);
//         let len = if len > cap { cap } else { len };
//         let mut new_len = 0;
//         for i in 0..len {
//             if let Ok(_) = arr.get(i) {
//                 new_len += 1;
//             } else {
//                 break;
//             }
//         }
//         SeqVec {
//             arr,
//             len: CachePadded::new(AtomicUsize::new(new_len)),
//             pushing: CachePadded::new(AtomicBool::new(false)),
//         }
//     }
// }

// #[test]
// fn push_and_get() {
//     let vec: SeqVec<usize> = SeqVec::with_capacity(8);
//     let n = 1000;
//     for i in 0..n {
//         let idx = vec.push(i);
//         assert_eq!(idx, i);
//     }
//     for i in 0..n {
//         assert_eq!(vec.get(i), Some(i));
//     }
//     assert_eq!(vec.len(), n);
// }

// #[test]
// fn set_and_get_update() {
//     let vec: SeqVec<usize> = SeqVec::with_capacity(16);
//     for _ in 0..16 {
//         vec.push(0);
//     }
//     for i in 0..16 {
//         vec.set(i, i * 2).unwrap();
//     }
//     for i in 0..16 {
//         assert_eq!(vec.get(i), Some(i * 2));
//     }
//     // Out of bounds set
//     vec.set(16, 123).unwrap_err();
//     assert_eq!(vec.get(16), None);
// }

// #[test]
// fn reserve_and_push_grow() {
//     let vec: SeqVec<usize> = SeqVec::with_capacity(2);
//     vec.reserve(100);
//     for i in 0..100 {
//         vec.push(i);
//     }
//     for i in 0..100 {
//         assert_eq!(vec.get(i), Some(i));
//     }
//     assert_eq!(vec.len(), 100);
//     assert!(vec.capacity() >= 100);
// }

// #[test]
// fn concurrent_push_unique() {
//     use rayon::prelude::*;
//     let vec: SeqVec<usize> = SeqVec::with_capacity(8);
//     let n = 1000000;
//     (0..n).into_par_iter().for_each(|i| {
//         vec.push(i);
//     });
//     let mut seen = std::collections::HashSet::new();
//     let mut missing = vec![];
//     for i in 0..vec.len() {
//         match vec.get(i) {
//             Some(v) => {
//                 assert!(seen.insert(v), "Duplicate value {v}");
//             }
//             None => missing.push(i),
//         }
//     }
//     assert!(
//         missing.is_empty(),
//         "Missing values at indices: {:?}",
//         missing
//     );
//     assert_eq!(seen.len(), n);
// }

// #[test]
// fn push_and_pop_lifo() {
//     let vec: SeqVec<i32> = SeqVec::with_capacity(8);
//     let n = 1000;
//     for i in 0..n {
//         vec.push(i);
//     }
//     for i in (0..n).rev() {
//         assert_eq!(vec.pop(), Some(i));
//     }
//     assert_eq!(vec.len(), 0);
//     assert_eq!(vec.pop(), None);
// }

// #[test]
// fn interleaved_push_pop_varied() {
//     let vec: SeqVec<i32> = SeqVec::with_capacity(4);
//     assert_eq!(vec.pop(), None);
//     let a = vec.push(1);
//     let b = vec.push(2);
//     assert_eq!(a, 0);
//     assert_eq!(b, 1);
//     assert_eq!(vec.pop(), Some(2));
//     assert_eq!(vec.pop(), Some(1));
//     assert_eq!(vec.pop(), None);
//     let c = vec.push(42);
//     assert_eq!(c, 0);
//     assert_eq!(vec.pop(), Some(42));
//     assert_eq!(vec.pop(), None);
// }

// #[test]
// fn concurrent_push_and_pop_unique() {
//     use rayon::prelude::*;
//     let vec: SeqVec<i32> = SeqVec::with_capacity(8);
//     let n = 10000;
//     // Push in parallel
//     (0..n).into_par_iter().for_each(|i| {
//         vec.push(i);
//     });
//     // Pop in parallel
//     let pops: Vec<_> = (0..n).into_par_iter().map(|_| vec.pop()).collect();
//     // All pops should be Some and unique, and after n pops, len should be 0
//     let mut seen = std::collections::HashSet::new();
//     let mut missing = vec![];
//     for v in pops {
//         match v {
//             Some(x) => {
//                 assert!(seen.insert(x), "Duplicate value {x}");
//             }
//             None => missing.push(()),
//         }
//     }
//     assert!(missing.len() == 0, "Some pops returned None before empty");
//     assert_eq!(vec.len(), 0);
//     // Further pops should be None
//     assert_eq!(vec.pop(), None);
// }

// #[test]
// fn concurrent_interleaved_push_pop_varied() {
//     use rayon::prelude::*;
//     let vec: SeqVec<usize> = SeqVec::with_capacity(8);
//     let n = 10000;
//     // Interleave push and pop in parallel
//     let results: Vec<_> = (0..n)
//         .into_par_iter()
//         .map(|i| {
//             if i % 2 == 0 {
//                 Some(vec.push(i))
//             } else {
//                 vec.pop();
//                 None // marker for pop
//             }
//         })
//         .collect();
//     // Count how many pushes succeeded
//     let _push_count = results.iter().filter(|x| x.is_some()).count();
//     // After all, len should be >= 0 and <= n/2 (since half are pops)
//     assert!(vec.len() <= n / 2);
//     // All remaining values in the vector should be unique
//     let mut seen = std::collections::HashSet::new();
//     for i in 0..vec.len() {
//         let v = vec.get(i).unwrap();
//         assert!(seen.insert(v), "Duplicate value {v}");
//     }
// }

// #[test]
// fn clone_basic() {
//     let vec: SeqVec<usize> = SeqVec::with_capacity(16);
//     for i in 0..10 {
//         vec.push(i);
//     }
//     let clone = vec.clone();
//     assert_eq!(clone.len(), 10);
//     for i in 0..10 {
//         assert_eq!(clone.get(i), Some(i));
//     }
//     // Mutate original, clone should not change
//     vec.set(0, 42).unwrap();
//     assert_eq!(clone.get(0), Some(0));
// }

// #[test]
// fn clone_after_grow() {
//     let vec: SeqVec<usize> = SeqVec::with_capacity(2);
//     for i in 0..100 {
//         vec.push(i);
//     }
//     let clone = vec.clone();
//     assert_eq!(clone.len(), 100);
//     for i in 0..100 {
//         assert_eq!(clone.get(i), Some(i));
//     }
// }

// #[test]
// fn clone_during_concurrent_growth() {
//     use std::thread;
//     let vec: SeqVec<i32> = SeqVec::with_capacity(4);
//     let n = 10_000;
//     thread::scope(|s| {
//         // Writer: grows and fills the vector
//         let writer = s.spawn(|| {
//             for i in 0..n {
//                 vec.push(i);
//             }
//         });
//         // Cloner: repeatedly clones the vector while it is growing
//         let cloner = s.spawn(|| {
//             let mut last_len = 0;
//             for _ in 0..100 {
//                 let clone = vec.clone();
//                 assert!(clone.len() >= last_len, "Clone length should not decrease");
//                 for i in 0..clone.len() {
//                     let v = clone.get(i).unwrap();
//                     assert!(v < n, "Cloned value out of range");
//                 }
//                 last_len = clone.len();
//             }
//         });
//         writer.join().unwrap();
//         cloner.join().unwrap();
//     });
// }