use serde::{Deserializer, Serialize, Serializer};
use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::cell::UnsafeCell;
use std::fmt::{Debug, Formatter};
use std::iter::FusedIterator;
use std::ops::{Index, IndexMut};
use std::slice::Iter as SliceIter;
use std::sync::Arc;
use std::vec::IntoIter;
pub use crate::guard_common::{MutRefGuard, ReadGuard, RefGuard, WriteGuard};
pub struct SyncVec<V> {
dirty: UnsafeCell<Vec<RwLock<V>>>,
lock: RwLock<()>,
}
unsafe impl<V> Send for SyncVec<V> {}
unsafe impl<V> Sync for SyncVec<V> {}
impl<V> Default for SyncVec<V> {
fn default() -> Self {
Self::new()
}
}
impl<V> From<Vec<V>> for SyncVec<V> {
fn from(v: Vec<V>) -> Self {
Self::with_vec(v)
}
}
impl<V> FromIterator<V> for SyncVec<V> {
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
let mut v = Vec::new();
for item in iter {
v.push(RwLock::new(item));
}
Self {
dirty: UnsafeCell::new(v),
lock: RwLock::new(()),
}
}
}
impl<V> Extend<V> for SyncVec<V> {
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
let v = self.dirty.get_mut();
for item in iter {
v.push(RwLock::new(item));
}
}
}
impl<V> SyncVec<V> {
pub fn new_arc() -> Arc<Self> {
Arc::new(Self::new())
}
pub const fn new() -> Self {
Self {
dirty: UnsafeCell::new(Vec::new()),
lock: RwLock::new(()),
}
}
pub fn with_vec(vec: Vec<V>) -> Self {
let mut v = Vec::with_capacity(vec.len());
for item in vec {
v.push(RwLock::new(item));
}
Self {
dirty: UnsafeCell::new(v),
lock: RwLock::new(()),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
dirty: UnsafeCell::new(Vec::with_capacity(capacity)),
lock: RwLock::new(()),
}
}
#[inline(always)]
fn as_arr(&self) -> &Vec<RwLock<V>> {
unsafe { &*self.dirty.get() }
}
#[inline(always)]
fn as_arr_mut(&self) -> &mut Vec<RwLock<V>> {
unsafe { &mut *self.dirty.get() }
}
#[inline(always)]
pub fn insert(&self, index: usize, v: V) {
let _lock = self.lock.write();
self.as_arr_mut().insert(index, RwLock::new(v));
}
#[inline(always)]
pub fn push(&self, v: V) {
let _lock = self.lock.write();
self.as_arr_mut().push(RwLock::new(v));
}
#[inline(always)]
pub fn push_return(&self, v: V) -> usize {
let _lock = self.lock.write();
let u = self.as_arr_mut();
let index = u.len();
u.push(RwLock::new(v));
index
}
#[inline(always)]
pub fn push_vec(&self, input_arr: Vec<V>) {
let mut _lock = self.lock.write();
let u = self.as_arr_mut();
for ele in input_arr.into_iter() {
u.push(RwLock::new(ele));
}
}
pub fn pop(&self) -> Option<V> {
let _lock = self.lock.write();
let u = self.as_arr_mut();
u.pop().map(|v| v.into_inner())
}
pub fn remove(&self, index: usize) -> Option<V> {
let _lock = self.lock.write();
let u = self.as_arr_mut();
if u.len() > index {
let v = u.remove(index);
Some(v.into_inner())
} else {
None
}
}
pub fn len(&self) -> usize {
let _lock = self.lock.read();
let u = self.as_arr();
u.len()
}
pub fn is_empty(&self) -> bool {
let _lock = self.lock.read();
let u = self.as_arr();
u.is_empty()
}
pub fn clear(&self) {
let _lock = self.lock.write();
let u = self.as_arr_mut();
u.clear();
}
pub fn shrink_to_fit(&self) {
let _lock = self.lock.write();
let u = self.as_arr_mut();
u.shrink_to_fit();
}
#[inline]
pub fn get(&self, index: usize) -> Option<RefGuard<'_, V>> {
let _lock = self.lock.read();
let u = self.as_arr();
if let Some(v_lock) = u.get(index) {
let value_ptr = unsafe {
let lock_ptr = v_lock as *const RwLock<V> as *mut RwLock<V>;
&*(*lock_ptr).get_mut()
};
Some(RefGuard {
_lock,
_value: value_ptr,
})
} else {
None
}
}
#[inline]
pub fn get_uncheck(&self, index: usize) -> RefGuard<'_, V> {
let _lock = self.lock.read();
let u = self.as_arr();
let v_lock = &u[index];
let value_ptr = unsafe {
let lock_ptr = v_lock as *const RwLock<V> as *mut RwLock<V>;
&*(*lock_ptr).get_mut()
};
RefGuard {
_lock,
_value: value_ptr,
}
}
#[inline]
pub fn get_rlock(&self, index: usize) -> Option<ReadGuard<'_, V>> {
let _lock = self.lock.read();
let u = self.as_arr();
if let Some(v_lock) = u.get(index) {
let _value_lock = v_lock.read();
Some(ReadGuard { _lock, _value_lock })
} else {
None
}
}
#[inline]
pub fn get_mut_lock(&self, index: usize) -> Option<WriteGuard<'_, V>> {
let _lock = self.lock.read();
let u = self.as_arr();
if let Some(v_lock) = u.get(index) {
let _value_lock = v_lock.write();
Some(WriteGuard { _lock, _value_lock })
} else {
None
}
}
#[inline]
pub fn get_mut(&self, index: usize) -> Option<MutRefGuard<'_, V>> {
let _lock = self.lock.read();
let u = self.as_arr();
if let Some(v_lock) = u.get(index) {
let value_ptr = unsafe {
let lock_ptr = v_lock as *const RwLock<V> as *mut RwLock<V>;
&mut *(*lock_ptr).get_mut()
};
Some(MutRefGuard {
_lock,
_value: value_ptr,
})
} else {
None
}
}
#[inline]
pub fn contains(&self, x: &V) -> bool
where
V: PartialEq,
{
let _lock = self.lock.read();
let u = self.as_arr();
for item in u {
let value_ptr = unsafe {
let lock_ptr = item as *const RwLock<V> as *mut RwLock<V>;
&*(*lock_ptr).get_mut()
};
if value_ptr == x {
return true;
}
}
false
}
#[inline]
pub fn contains_lock(&self, x: &V) -> bool
where
V: PartialEq,
{
let _lock = self.lock.read();
let u = self.as_arr();
for item in u {
if *item.read() == *x {
return true;
}
}
false
}
pub fn iter_rlock(&self) -> IterRLock<'_, V> {
let _lock = self.lock.read();
let u = self.as_arr();
IterRLock {
_lock,
inner: u.iter(),
}
}
pub fn iter(&self) -> Iter<'_, V> {
let _lock = self.lock.read();
let u = self.as_arr();
Iter {
_lock,
inner: u.iter(),
}
}
pub fn iter_mut_lock(&self) -> IterLock<'_, V> {
let _lock = self.lock.read();
let u = self.as_arr();
IterLock {
_lock,
inner: u.iter(),
}
}
pub fn iter_mut(&self) -> IterMut<'_, V> {
let _lock = self.lock.read();
let u = self.as_arr();
IterMut {
_lock,
inner: u.iter(),
}
}
pub fn into_iter(self) -> IntoIter<V> {
let _lock = self.lock.write();
let m = self.dirty.into_inner();
let mut v = Vec::with_capacity(m.len());
for item in m {
v.push(item.into_inner());
}
v.into_iter()
}
pub fn dirty_ref(&self) -> RefGuard<'_, Vec<RwLock<V>>> {
RefGuard {
_lock: self.lock.read(),
_value: self.as_arr(),
}
}
pub fn into_inner(self) -> Vec<V> {
let m = self.dirty.into_inner();
let mut v = Vec::with_capacity(m.len());
for item in m {
v.push(item.into_inner());
}
v
}
pub fn to_vec(&self) -> Vec<V>
where
V: Clone,
{
let _lock = self.lock.read();
let u = self.as_arr();
let mut v = Vec::with_capacity(u.len());
for item in u {
v.push(item.read().clone());
}
v
}
}
pub struct IterRLock<'a, V> {
pub(crate) _lock: RwLockReadGuard<'a, ()>,
pub(crate) inner: SliceIter<'a, RwLock<V>>,
}
impl<'a, V> Iterator for IterRLock<'a, V> {
type Item = RwLockReadGuard<'a, V>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|v| v.read())
}
}
impl<'a, V> ExactSizeIterator for IterRLock<'a, V> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, V> DoubleEndedIterator for IterRLock<'a, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|v| v.read())
}
}
impl<'a, V> FusedIterator for IterRLock<'a, V> {}
pub struct IterLock<'a, V> {
pub(crate) _lock: RwLockReadGuard<'a, ()>,
pub(crate) inner: SliceIter<'a, RwLock<V>>,
}
impl<'a, V> Iterator for IterLock<'a, V> {
type Item = RwLockWriteGuard<'a, V>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|v| v.write())
}
}
impl<'a, V> ExactSizeIterator for IterLock<'a, V> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, V> DoubleEndedIterator for IterLock<'a, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|v| v.write())
}
}
impl<'a, V> FusedIterator for IterLock<'a, V> {}
pub struct Iter<'a, V> {
pub(crate) _lock: RwLockReadGuard<'a, ()>,
pub(crate) inner: SliceIter<'a, RwLock<V>>,
}
impl<'a, V> Iterator for Iter<'a, V> {
type Item = &'a V;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|v| {
unsafe {
let lock_ptr = v as *const RwLock<V> as *mut RwLock<V>;
&*(*lock_ptr).get_mut()
}
})
}
}
impl<'a, V> ExactSizeIterator for Iter<'a, V> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, V> DoubleEndedIterator for Iter<'a, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|v| {
unsafe {
let lock_ptr = v as *const RwLock<V> as *mut RwLock<V>;
&*(*lock_ptr).get_mut()
}
})
}
}
impl<'a, V> FusedIterator for Iter<'a, V> {}
pub struct IterMut<'a, V> {
pub(crate) _lock: RwLockReadGuard<'a, ()>,
pub(crate) inner: SliceIter<'a, RwLock<V>>,
}
impl<'a, V> Iterator for IterMut<'a, V> {
type Item = &'a mut V;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|v| {
unsafe {
let lock_ptr = v as *const RwLock<V> as *mut RwLock<V>;
&mut *(*lock_ptr).get_mut()
}
})
}
}
impl<'a, V> ExactSizeIterator for IterMut<'a, V> {
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, V> DoubleEndedIterator for IterMut<'a, V> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner.next_back().map(|v| {
unsafe {
let lock_ptr = v as *const RwLock<V> as *mut RwLock<V>;
&mut *(*lock_ptr).get_mut()
}
})
}
}
impl<'a, V> FusedIterator for IterMut<'a, V> {}
impl<'a, V> IntoIterator for &'a SyncVec<V> {
type Item = &'a V;
type IntoIter = Iter<'a, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, V> IntoIterator for &'a mut SyncVec<V> {
type Item = &'a mut V;
type IntoIter = IterMut<'a, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<V> IntoIterator for SyncVec<V> {
type Item = V;
type IntoIter = IntoIter<V>;
fn into_iter(self) -> Self::IntoIter {
self.into_iter()
}
}
impl<V> Serialize for SyncVec<V>
where
V: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use serde::ser::SerializeSeq;
let _lock = self.lock.read();
let v = unsafe { &*self.dirty.get() };
let mut seq = serializer.serialize_seq(Some(v.len()))?;
for element in v {
seq.serialize_element(&*element.read())?;
}
seq.end()
}
}
impl<'de, V> serde::Deserialize<'de> for SyncVec<V>
where
V: serde::Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let m = Vec::deserialize(deserializer)?;
Ok(Self::from(m))
}
}
impl<V> Debug for SyncVec<V>
where
V: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.dirty_ref())
}
}
impl<V: std::fmt::Display> std::fmt::Display for SyncVec<V> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let _lock = self.lock.read();
let v = unsafe { &*self.dirty.get() };
write!(f, "[")?;
for (i, item) in v.iter().enumerate() {
if i > 0 {
write!(f, ", ")?;
}
write!(f, "{}", item.read())?;
}
write!(f, "]")
}
}
impl<V: PartialEq> PartialEq for SyncVec<V> {
fn eq(&self, other: &Self) -> bool {
let _lock1 = self.lock.read();
let _lock2 = other.lock.read();
let v1 = unsafe { &*self.dirty.get() };
let v2 = unsafe { &*other.dirty.get() };
if v1.len() != v2.len() {
return false;
}
for (i1, i2) in v1.iter().zip(v2.iter()) {
if *i1.read() != *i2.read() {
return false;
}
}
true
}
}
impl<V: Clone> Clone for SyncVec<V> {
fn clone(&self) -> Self {
let _lock = self.lock.read();
let v = unsafe { &*self.dirty.get() };
let mut new_vec = Vec::with_capacity(v.len());
for item in v {
new_vec.push(RwLock::new(item.read().clone()));
}
Self {
dirty: UnsafeCell::new(new_vec),
lock: RwLock::new(()),
}
}
}
impl<V> Index<usize> for SyncVec<V> {
type Output = V;
fn index(&self, index: usize) -> &Self::Output {
unsafe {
let v = &*self.dirty.get();
let lock_ptr = &v[index] as *const RwLock<V> as *mut RwLock<V>;
(*lock_ptr).get_mut()
}
}
}
impl<V> IndexMut<usize> for SyncVec<V> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
let v = self.dirty.get_mut();
v[index].get_mut()
}
}
#[macro_export]
macro_rules! sync_vec {
() => (
$crate::SyncVec::new()
);
($elem:expr; $n:expr) => (
$crate::SyncVec::with_vec(vec![$elem;$n])
);
($($x:expr),+ $(,)?) => (
$crate::SyncVec::with_vec(vec![$($x),+,])
);
}
#[test]
fn test_case() {
struct D {}
impl D {
fn is_some(&self) -> bool {
println!("is_some");
true
}
fn take(&mut self) -> Option<bool> {
println!("take");
Some(true)
}
}
let mut d = D {};
if let (true, Some(d)) = (d.is_some(), d.take()) {
println!("d is {d}");
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use std::thread;
#[test]
fn test_new_and_capacity() {
let vec: SyncVec<i32> = SyncVec::new();
assert!(vec.is_empty());
assert_eq!(vec.len(), 0);
let vec: SyncVec<i32> = SyncVec::with_capacity(10);
assert!(vec.is_empty());
assert_eq!(vec.len(), 0);
}
#[test]
fn test_push_and_get() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
assert_eq!(vec.len(), 3);
assert_eq!(*vec.get(0).unwrap(), 1);
assert_eq!(*vec.get(1).unwrap(), 2);
assert_eq!(*vec.get(2).unwrap(), 3);
assert!(vec.get(3).is_none());
}
#[test]
fn test_index_methods() {
let mut vec = SyncVec::new();
vec.push(10);
vec.push(20);
assert_eq!(vec[0], 10);
assert_eq!(vec[1], 20);
{
let val = &mut vec[0];
*val = 100;
}
assert_eq!(vec[0], 100);
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn test_index_panic() {
let vec = SyncVec::new();
vec.push(1);
let _ = vec[1];
}
#[test]
#[should_panic(expected = "index out of bounds")]
fn test_index_mut_panic() {
let mut vec = SyncVec::new();
vec.push(1);
let _ = &mut vec[1];
}
#[test]
fn test_remove_and_pop() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
assert_eq!(vec.pop(), Some(3));
assert_eq!(vec.len(), 2);
assert_eq!(vec.remove(0), Some(1));
assert_eq!(vec.len(), 1);
assert_eq!(*vec.get(0).unwrap(), 2);
}
#[test]
fn test_concurrency() {
let vec = Arc::new(SyncVec::new());
let mut handles = vec![];
for i in 0..10 {
let vec = vec.clone();
handles.push(thread::spawn(move || {
for j in 0..100 {
vec.push(i * 100 + j);
}
}));
}
for handle in handles {
handle.join().unwrap();
}
assert_eq!(vec.len(), 1000);
}
#[test]
fn test_concurrent_modify() {
let vec = Arc::new(SyncVec::new());
for i in 0..100 {
vec.push(i);
}
let vec_clone = vec.clone();
let handle = thread::spawn(move || {
for i in 0..100 {
if let Some(mut guard) = vec_clone.get_mut(i) {
*guard += 1;
}
}
});
for i in 0..100 {
if let Some(val) = vec.get(i) {
let _ = *val; }
}
handle.join().unwrap();
for i in 0..100 {
assert_eq!(*vec.get(i).unwrap(), i + 1);
}
}
#[test]
fn test_iter() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
let mut sum = 0;
for item in vec.iter() {
sum += *item;
}
assert_eq!(sum, 6);
}
#[test]
fn test_iter_mut() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
for mut item in vec.iter_mut() {
*item *= 2;
}
assert_eq!(*vec.get(0).unwrap(), 2);
assert_eq!(*vec.get(1).unwrap(), 4);
assert_eq!(*vec.get(2).unwrap(), 6);
}
#[test]
fn test_clear() {
let vec = SyncVec::new();
vec.push(1);
vec.clear();
assert!(vec.is_empty());
}
#[test]
fn test_contains() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
assert!(vec.contains(&1));
assert!(!vec.contains(&3));
}
#[test]
fn test_iterator_traits() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
let mut iter = vec.iter();
assert_eq!(iter.len(), 3);
assert_eq!(*iter.next().unwrap(), 1);
assert_eq!(iter.len(), 2);
assert_eq!(*iter.next_back().unwrap(), 3);
assert_eq!(iter.len(), 1);
assert_eq!(*iter.next().unwrap(), 2);
assert_eq!(iter.len(), 0);
assert!(iter.next().is_none());
assert!(iter.next_back().is_none());
let mut vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
let mut iter_mut = vec.iter_mut();
assert_eq!(iter_mut.len(), 3);
assert_eq!(*iter_mut.next().unwrap(), 1);
assert_eq!(iter_mut.len(), 2);
assert_eq!(*iter_mut.next_back().unwrap(), 3);
assert_eq!(iter_mut.len(), 1);
assert_eq!(*iter_mut.next().unwrap(), 2);
assert_eq!(iter_mut.len(), 0);
assert!(iter_mut.next().is_none());
assert!(iter_mut.next_back().is_none());
}
#[test]
fn test_from_iter_and_extend() {
let vec: SyncVec<i32> = SyncVec::from_iter(vec![1, 2, 3]);
assert_eq!(vec.len(), 3);
assert_eq!(*vec.get(0).unwrap(), 1);
let mut vec = SyncVec::new();
vec.extend(vec![1, 2, 3]);
assert_eq!(vec.len(), 3);
assert_eq!(*vec.get(0).unwrap(), 1);
}
#[test]
fn test_iter_notlock() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
let mut sum = 0;
for item in vec.iter() {
sum += *item;
}
assert_eq!(sum, 6);
let iter = vec.iter();
assert_eq!(iter.len(), 3);
}
#[test]
fn test_iter_double_ended() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
let mut iter = vec.iter();
assert_eq!(*iter.next().unwrap(), 1);
assert_eq!(*iter.next_back().unwrap(), 3);
assert_eq!(*iter.next().unwrap(), 2);
assert!(iter.next().is_none());
}
#[test]
fn test_iter_empty() {
let vec: SyncVec<i32> = SyncVec::new();
let mut count = 0;
for _ in vec.iter() {
count += 1;
}
assert_eq!(count, 0);
let iter = vec.iter();
assert_eq!(iter.len(), 0);
}
#[test]
fn test_into_iter_ref() {
let vec = SyncVec::new();
vec.push(10);
vec.push(20);
vec.push(30);
let mut sum = 0;
for item in &vec {
sum += *item;
}
assert_eq!(sum, 60);
assert_eq!(vec.len(), 3);
}
#[test]
fn test_into_iter_mut() {
let mut vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
for mut item in &mut vec {
*item *= 2;
}
assert_eq!(*vec.get(0).unwrap(), 2);
assert_eq!(*vec.get(1).unwrap(), 4);
assert_eq!(*vec.get(2).unwrap(), 6);
}
#[test]
fn test_into_iter_owned() {
let vec = SyncVec::new();
vec.push(1);
vec.push(2);
vec.push(3);
let collected: Vec<_> = vec.into_iter().collect();
assert_eq!(collected, vec![1, 2, 3]);
}
}