use std::ops::{Deref, DerefMut};
use std::borrow::Cow;
use std::convert::Infallible;
use std::sync::{Arc, Weak};
use std::fmt::{self, Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use either::Either;
use parking_lot::{RwLock, RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard};
use super::cons::CacheAcceptor;
#[derive(Debug)]
pub struct Node<T: ?Sized> {
data: Arc<RwLock<T>>
}
impl<T: ?Sized> Node<T> {
pub fn data(&self) -> View<RwLockReadGuard<T>> { View::new(self.data.read()) }
pub fn try_data(&self) -> Option<View<RwLockReadGuard<T>>> {
self.data.try_read().map(View::new)
}
pub fn data_mut(&self) -> View<RwLockWriteGuard<T>> { View::new(self.data.write()) }
pub fn try_data_mut(&self) -> Option<View<RwLockWriteGuard<T>>> {
self.data.try_write().map(View::new)
}
pub fn downgrade(&self) -> WeakNode<T> { WeakNode { data: Arc::downgrade(&self.data) } }
}
impl<T: ?Sized> Clone for Node<T> {
#[inline(always)] fn clone(&self) -> Node<T> { Node { data: self.data.clone() } }
}
impl<T: ?Sized> PartialEq for Node<T> {
#[inline] fn eq(&self, other: &Node<T>) -> bool { Arc::ptr_eq(&self.data, &other.data) }
}
impl<T: ?Sized> Eq for Node<T> {}
impl<T: ?Sized> Hash for Node<T> {
#[inline] fn hash<H: Hasher>(&self, hasher: &mut H) {
(self.data.deref() as *const RwLock<_>).hash(hasher)
}
}
#[derive(Debug, Clone)]
pub struct NotBacklinked<T>(Node<T>);
impl<T: NodeData> NotBacklinked<T> {
pub fn backlink(self) -> Result<Node<T>, T::Error> {
{
let mut data = self.0.data.write();
data.backlink(Backlink(&self.0))?;
}
Ok(self.0)
}
}
#[derive(Debug, Clone)]
pub struct Backlink<'a, T>(&'a Node<T>);
impl<T> Deref for Backlink<'_, T> {
type Target = Node<T>;
#[inline(always)] fn deref(&self) -> &Node<T> { self.0 }
}
pub trait NodeData: Sized {
type Error;
type CacheAcceptor: CacheAcceptor<Self>;
fn backlink(&mut self, _backlink: Backlink<Self>) -> Result<(), Self::Error> { Ok(()) }
fn dedup(&mut self) -> Either<Node<Self>, Self::CacheAcceptor>;
}
#[derive(Debug, PartialEq)]
pub struct View<R>(pub(crate) R);
impl<R> Deref for View<R> where R: Deref {
type Target = R::Target;
fn deref(&self) -> &R::Target { self.0.deref() }
}
impl<R> View<R> where R: Deref {
pub fn new(r: R) -> View<R> { View(r) }
}
impl<'a, T> View<RwLockWriteGuard<'a, T>> {
pub fn downgrade(self) -> View<RwLockReadGuard<'a, T>> {
View::new(RwLockWriteGuard::downgrade(self.0))
}
pub fn downgrade_to_upgradeable(self) -> View<RwLockUpgradableReadGuard<'a, T>> {
View::new(RwLockWriteGuard::downgrade_to_upgradable(self.0))
}
}
impl<'a, T> View<RwLockUpgradableReadGuard<'a, T>> {
pub fn upgrade(self) -> View<RwLockWriteGuard<'a, T>> {
View::new(RwLockUpgradableReadGuard::upgrade(self.0))
}
pub fn try_upgrade(self) -> Result<View<RwLockWriteGuard<'a, T>>, Self> {
match RwLockUpgradableReadGuard::try_upgrade(self.0) {
Ok(up) => Ok(View::new(up)),
Err(s) => Err(View::new(s))
}
}
}
impl<T: NodeData> Node<T> {
fn not_backlinked(data: T) -> NotBacklinked<T> {
NotBacklinked(Node { data : Arc::new(RwLock::new(data)) })
}
pub fn try_new(mut data: T) -> Result<Node<T>, T::Error> {
match data.dedup() {
Either::Left(node) => Ok(node),
Either::Right(acceptor) => {
let node = Node::not_backlinked(data).backlink()?;
acceptor.accept(node.downgrade());
Ok(node)
}
}
}
}
impl<T: NodeData<Error=Infallible>> Node<T> {
pub fn new(data: T) -> Node<T> {
Node::try_new(data).unwrap_or_else(|err| match err {})
}
}
impl<T: Display> Display for Node<T> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
write!(fmt, "{}", self.data().deref())
}
}
#[derive(Debug)]
pub struct WeakNode<T: ?Sized> {
data: Weak<RwLock<T>>
}
impl<T: ?Sized> Clone for WeakNode<T> {
#[inline(always)] fn clone(&self) -> WeakNode<T> { WeakNode { data: self.data.clone() } }
}
impl<T> Default for WeakNode<T> {
#[inline(always)] fn default() -> WeakNode<T> { WeakNode { data: Weak::default() } }
}
impl<T: ?Sized> WeakNode<T> {
pub fn upgrade(&self) -> Option<Node<T>> { self.data.upgrade().map(|data| Node { data }) }
}
impl<T: ?Sized> PartialEq for WeakNode<T> {
fn eq(&self, other: &WeakNode<T>) -> bool { self.data.ptr_eq(&other.data) }
}
impl<T: ?Sized> Eq for WeakNode<T> {}
impl<T> Hash for WeakNode<T> {
#[inline] fn hash<H: Hasher>(&self, hasher: &mut H) {
self.data.as_ptr().hash(hasher)
}
}
impl<T> WeakNode<T> {
pub fn is_null(&self) -> bool { self == &WeakNode::default() }
}
impl<T> WeakNode<T> {
pub fn new() -> WeakNode<T> { WeakNode { data: Weak::default() } }
pub fn alloc_eq(&self, other: &WeakNode<T>) -> bool {
!self.data.ptr_eq(&Weak::new()) && self == other
}
}
pub trait HasThis<T=Self> {
fn this(&self) -> Cow<WeakNode<T>>;
}
impl<T> HasThis<T> for WeakNode<T> {
fn this(&self) -> Cow<WeakNode<T>> { Cow::Borrowed(&self) }
}
pub trait HasAddr<T=Self> {
fn addr(&self) -> Cow<Node<T>>;
}
impl<T> HasAddr<T> for Node<T> {
#[inline(always)] fn addr(&self) -> Cow<Node<T>> { Cow::Borrowed(&self) }
}
impl<T> HasThis<T> for Node<T> {
#[inline(always)] fn this(&self) -> Cow<WeakNode<T>> { Cow::Owned(self.downgrade()) }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ToWeak<I>(pub I);
impl<'a, T: 'a, I> Iterator for ToWeak<I> where I: Iterator<Item=&'a Node<T>> {
type Item = WeakNode<T>;
fn next(&mut self) -> Option<WeakNode<T>> { self.0.next().map(Node::downgrade) }
fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
fn count(self) -> usize { self.0.count() }
fn last(self) -> Option<WeakNode<T>> { self.0.last().map(Node::downgrade) }
fn nth(&mut self, n: usize) -> Option<WeakNode<T>> { self.0.nth(n).map(Node::downgrade) }
}
impl<'a, T: 'a, I> ExactSizeIterator for ToWeak<I> where I: ExactSizeIterator<Item=&'a Node<T>> {
fn len(&self) -> usize { self.0.len() }
}
impl<'a, T: 'a, I> DoubleEndedIterator for ToWeak<I> where I: DoubleEndedIterator<Item=&'a Node<T>>
{
fn next_back(&mut self) -> Option<WeakNode<T>> { self.0.next_back().map(Node::downgrade) }
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default)]
pub struct Data<T>(pub T);
impl<T> Deref for Data<T> {
type Target = T;
fn deref(&self) -> &T { &self.0 }
}
impl<T> DerefMut for Data<T> {
fn deref_mut(&mut self) -> &mut T { &mut self.0 }
}
impl<T> NodeData for Data<T> {
type Error = Infallible;
type CacheAcceptor = ();
fn dedup(&mut self) -> Either<Node<Data<T>>, ()> { Either::Right(()) }
}
impl<R, T> DerefMut for View<R> where R: DerefMut<Target=Data<T>> {
fn deref_mut(&mut self) -> &mut Data<T> { self.0.deref_mut() }
}