use crate::{node::Node, prelude::*};
use parking_lot::RwLock;
use std::fmt::{self, Debug, Formatter};
use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use std::{iter::Extend, iter::FromIterator, mem::swap, ptr::null_mut, ptr::NonNull, sync::Arc};
#[derive(Debug)]
pub struct Inner<T> {
size: AtomicUsize,
first_node: FillOnceAtomicOption<Node<T>>,
last_node: AtomicPtr<Node<T>>,
}
impl<T> Default for Inner<T> {
#[inline]
fn default() -> Self {
trace!("default()");
Self {
size: AtomicUsize::new(0),
first_node: FillOnceAtomicOption::default(),
last_node: AtomicPtr::new(null_mut()),
}
}
}
impl<T> Inner<T> {
#[inline]
pub fn first_node(&self) -> Option<NonNull<Node<T>>> {
let nn = NonNull::new(self.first_node.get_raw(Ordering::Relaxed));
trace!("first_node() = {:?}", nn);
nn
}
#[inline]
pub fn last_node(&self) -> Option<NonNull<Node<T>>> {
let nn = NonNull::new(self.last_node.load(Ordering::Relaxed));
trace!("last_node() = {:?}", nn);
nn
}
#[inline]
pub fn len(&self) -> usize {
let len = self.size.load(Ordering::Relaxed);
trace!("len() = {}", len);
len
}
#[inline]
pub fn is_empty(&self) -> bool {
trace!("is_empty()");
self.len() == 0
}
#[inline]
fn set_first(&self, node: Box<Node<T>>) -> Result<(), NotEmpty> {
trace!("set_first({:p})", node);
let ret = self.first_node.try_store(node, Ordering::Relaxed);
debug_assert!(ret.is_ok());
ret
}
#[inline]
fn swap_last(&self, ptr: *mut Node<T>) -> Option<NonNull<Node<T>>> {
trace!("swap_last({:p})", ptr);
NonNull::new(self.last_node.swap(ptr, Ordering::Relaxed))
}
#[inline]
pub unsafe fn append_chain(&self, first: *mut Node<T>, last: *mut Node<T>, length: usize) {
debug!("append_chain({:p}, {:p}, {})", first, last, length);
if let Some(nn) = self.swap_last(last) {
#[allow(unused)]
let old = nn.as_ref().try_store_next(Box::from_raw(first));
debug_assert!(old.is_ok());
} else {
let _ = self.set_first(Box::from_raw(first));
}
info!("Increased size by {}", length);
let _ = self.size.fetch_add(length, Ordering::Relaxed);
}
#[inline]
pub fn append(&self, value: T) {
let ptr = Node::new(value).into_ptr();
unsafe { self.append_chain(ptr, ptr, 1) };
}
#[inline]
pub fn into_inner(self) -> (usize, *mut Node<T>, *mut Node<T>) {
trace!("into_inner()");
let size = self.size.into_inner();
let first = self.first_node.into_inner().into_ptr();
let last = self.last_node.into_inner();
(size, first, last)
}
}
impl<T> FromIterator<T> for Inner<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
trace!("FromIterator<T>");
let inner = Self::default();
for element in iter {
inner.append(element);
}
inner
}
}
pub struct VoluntaryServitude<T>(RwLock<Arc<Inner<T>>>);
pub type VS<T> = VoluntaryServitude<T>;
impl<T> VoluntaryServitude<T> {
#[inline]
pub fn new() -> Self {
trace!("new()");
Self::default()
}
#[inline]
pub fn append(&self, value: T) {
self.0.read().append(value);
}
#[inline]
pub fn iter(&self) -> Iter<T> {
debug!("iter()");
Iter::from(self.0.read().clone())
}
#[inline]
pub fn len(&self) -> usize {
self.0.read().len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.read().is_empty()
}
#[inline]
pub fn clear(&self) {
debug!("clear()");
*self.0.write() = Arc::new(Inner::default());
}
#[inline]
pub fn empty(&self) -> Iter<T> {
debug!("empty()");
let old = Self::default();
self.swap(&old);
old.iter()
}
#[inline]
pub fn swap(&self, other: &Self) {
debug!("swap({:p})", other);
swap(&mut *self.0.write(), &mut *other.0.write());
}
#[inline]
pub fn extend<I: IntoIterator<Item = T>>(&self, iter: I) {
trace!("extend()");
let (size, first, last) = Inner::from_iter(iter).into_inner();
unsafe { self.0.read().append_chain(first, last, size) };
}
}
impl<T> Default for VoluntaryServitude<T> {
#[inline]
fn default() -> Self {
trace!("default()");
Self::from(Inner::default())
}
}
impl<T: Debug> Debug for VoluntaryServitude<T> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_tuple("VoluntaryServitude")
.field(&self.iter().collect::<Vec<_>>())
.finish()
}
}
impl<T> Extend<T> for VoluntaryServitude<T> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
Self::extend(self, iter)
}
}
impl<'a, T: 'a + Copy> Extend<&'a T> for VoluntaryServitude<T> {
#[inline]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
Self::extend(self, iter.into_iter().cloned())
}
}
impl<T> FromIterator<T> for VoluntaryServitude<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self::from(Inner::from_iter(iter))
}
}
impl<'a, T: 'a + Copy> FromIterator<&'a T> for VoluntaryServitude<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = &'a T>>(iter: I) -> Self {
Self::from_iter(iter.into_iter().cloned())
}
}
impl<T> From<Inner<T>> for VoluntaryServitude<T> {
#[inline]
fn from(inner: Inner<T>) -> Self {
trace!("From<Inner<T>>");
VoluntaryServitude(RwLock::new(Arc::new(inner)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::setup_logger;
use std::mem::drop;
#[test]
fn iter_outlives() {
setup_logger();
let vs = vs![1, 2, 3, 4];
let iter = vs.iter();
drop(vs);
drop(iter);
}
#[test]
fn voluntary_servitude_len_append_clear() {
setup_logger();
let list = vs![1, 2, 3];
assert_eq!(list.len(), 3);
list.append(4);
assert_eq!(list.len(), 4);
list.clear();
assert!(list.is_empty());
list.append(4);
assert_eq!(list.len(), 1);
}
#[test]
fn extend_partial_eq() {
setup_logger();
let vs: VS<u8> = vs![1, 2, 3, 4, 5];
let iter = &mut vs.iter();
vs.extend(iter.cloned());
assert_eq!(
vs.iter().collect::<Vec<_>>(),
vec![&1u8, &2, &3, &4, &5, &1, &2, &3, &4, &5]
);
}
#[test]
fn swap_empty() {
let vs: VS<u8> = vs![1, 2, 3, 4, 5];
let mut old: VS<u8> = vs![5, 4, 3, 2, 1];
vs.swap(&mut old);
assert_eq!(vs.empty().collect::<Vec<_>>(), vec![&5, &4, &3, &2, &1]);
assert_eq!(old.empty().collect::<Vec<_>>(), vec![&1, &2, &3, &4, &5]);
assert!(vs.is_empty());
}
#[test]
fn test_send() {
fn assert_send<T: Send>() {}
assert_send::<VoluntaryServitude<()>>();
assert_send::<Inner<()>>();
}
#[test]
fn test_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<VoluntaryServitude<()>>();
assert_sync::<Inner<()>>();
}
}