#![doc(html_root_url = "https://docs.rs/arctree")]
#![forbid(unsafe_code)]
#![warn(missing_docs)]
use std::fmt;
use std::sync::{Arc, Weak};
use parking_lot::{
MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
};
type Link<T> = Arc<RwLock<NodeData<T>>>;
type WeakLink<T> = Weak<RwLock<NodeData<T>>>;
pub struct Node<T>(Link<T>);
pub struct WeakNode<T>(WeakLink<T>);
struct NodeData<T> {
parent: Option<WeakLink<T>>,
first_child: Option<Link<T>>,
last_child: Option<WeakLink<T>>,
previous_sibling: Option<WeakLink<T>>,
next_sibling: Option<Link<T>>,
data: T,
}
impl<T> Clone for Node<T> {
fn clone(&self) -> Self {
Node(Arc::clone(&self.0))
}
}
impl<T> PartialEq for Node<T> {
fn eq(&self, other: &Node<T>) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}
impl<T: fmt::Debug> fmt::Debug for Node<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&*self.read(), f)
}
}
impl<T: fmt::Display> fmt::Display for Node<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&*self.read(), f)
}
}
impl<T> Node<T> {
pub fn new(data: T) -> Node<T> {
Node(Arc::new(RwLock::new(NodeData {
parent: None,
first_child: None,
last_child: None,
previous_sibling: None,
next_sibling: None,
data,
})))
}
pub fn downgrade(&self) -> WeakNode<T> {
WeakNode(Arc::downgrade(&self.0))
}
pub fn parent(&self) -> Option<Node<T>> {
Some(Node(self.0.read().parent.as_ref()?.upgrade()?))
}
pub fn first_child(&self) -> Option<Node<T>> {
Some(Node(self.0.read().first_child.as_ref()?.clone()))
}
pub fn last_child(&self) -> Option<Node<T>> {
Some(Node(self.0.read().last_child.as_ref()?.upgrade()?))
}
pub fn previous_sibling(&self) -> Option<Node<T>> {
Some(Node(self.0.read().previous_sibling.as_ref()?.upgrade()?))
}
pub fn next_sibling(&self) -> Option<Node<T>> {
Some(Node(self.0.read().next_sibling.as_ref()?.clone()))
}
pub fn read(&self) -> MappedRwLockReadGuard<'_, T> {
RwLockReadGuard::<'_, NodeData<T>>::map(self.0.read(), |v| &v.data)
}
pub fn write(&self) -> MappedRwLockWriteGuard<'_, T> {
RwLockWriteGuard::<'_, NodeData<T>>::map(self.0.write(), |v| &mut v.data)
}
pub fn ancestors(&self) -> Ancestors<T> {
Ancestors(Some(self.clone()))
}
pub fn preceding_siblings(&self) -> PrecedingSiblings<T> {
PrecedingSiblings(Some(self.clone()))
}
pub fn following_siblings(&self) -> FollowingSiblings<T> {
FollowingSiblings(Some(self.clone()))
}
pub fn children(&self) -> Children<T> {
Children {
next: self.first_child(),
next_back: self.last_child(),
}
}
pub fn has_children(&self) -> bool {
self.first_child().is_some()
}
pub fn descendants(&self) -> Descendants<T> {
Descendants(self.traverse())
}
pub fn traverse(&self) -> Traverse<T> {
Traverse {
root: self.clone(),
next: Some(NodeEdge::Start(self.clone())),
next_back: Some(NodeEdge::End(self.clone())),
}
}
pub fn detach(&self) {
self.0.write().detach();
}
pub fn append(&self, new_child: Node<T>) {
assert!(*self != new_child, "a node cannot be appended to itself");
let mut self_write = self.0.write();
let mut last_child_opt = None;
{
let mut new_child_write = new_child.0.write();
new_child_write.detach();
new_child_write.parent = Some(Arc::downgrade(&self.0));
if let Some(last_child_weak) = self_write.last_child.take() {
if let Some(last_child_strong) = last_child_weak.upgrade() {
new_child_write.previous_sibling = Some(last_child_weak);
last_child_opt = Some(last_child_strong);
}
}
self_write.last_child = Some(Arc::downgrade(&new_child.0));
}
if let Some(last_child_strong) = last_child_opt {
let mut last_child_write = last_child_strong.write();
debug_assert!(last_child_write.next_sibling.is_none());
last_child_write.next_sibling = Some(new_child.0);
} else {
debug_assert!(self_write.first_child.is_none());
self_write.first_child = Some(new_child.0);
}
}
pub fn prepend(&self, new_child: Node<T>) {
assert!(*self != new_child, "a node cannot be prepended to itself");
let mut self_write = self.0.write();
{
let mut new_child_write = new_child.0.write();
new_child_write.detach();
new_child_write.parent = Some(Arc::downgrade(&self.0));
match self_write.first_child.take() {
Some(first_child_strong) => {
{
let mut first_child_write = first_child_strong.write();
debug_assert!(first_child_write.previous_sibling.is_none());
first_child_write.previous_sibling = Some(Arc::downgrade(&new_child.0));
}
new_child_write.next_sibling = Some(first_child_strong);
}
None => {
debug_assert!(self_write.first_child.is_none());
self_write.last_child = Some(Arc::downgrade(&new_child.0));
}
}
}
self_write.first_child = Some(new_child.0);
}
pub fn insert_after(&self, new_sibling: Node<T>) {
assert!(
*self != new_sibling,
"a node cannot be inserted after itself"
);
let mut self_write = self.0.write();
{
let mut new_sibling_write = new_sibling.0.write();
new_sibling_write.detach();
new_sibling_write.parent = self_write.parent.clone();
new_sibling_write.previous_sibling = Some(Arc::downgrade(&self.0));
match self_write.next_sibling.take() {
Some(next_sibling_strong) => {
{
let mut next_sibling_write = next_sibling_strong.write();
debug_assert!({
let weak = next_sibling_write.previous_sibling.as_ref().unwrap();
Arc::ptr_eq(&weak.upgrade().unwrap(), &self.0)
});
next_sibling_write.previous_sibling = Some(Arc::downgrade(&new_sibling.0));
}
new_sibling_write.next_sibling = Some(next_sibling_strong);
}
None => {
if let Some(parent_ref) = self_write.parent.as_ref() {
if let Some(parent_strong) = parent_ref.upgrade() {
let mut parent_write = parent_strong.write();
parent_write.last_child = Some(Arc::downgrade(&new_sibling.0));
}
}
}
}
}
self_write.next_sibling = Some(new_sibling.0);
}
pub fn insert_before(&self, new_sibling: Node<T>) {
assert!(
*self != new_sibling,
"a node cannot be inserted before itself"
);
let mut self_write = self.0.write();
let mut previous_sibling_opt = None;
{
let mut new_sibling_write = new_sibling.0.write();
new_sibling_write.detach();
new_sibling_write.parent = self_write.parent.clone();
new_sibling_write.next_sibling = Some(self.0.clone());
if let Some(previous_sibling_weak) = self_write.previous_sibling.take() {
if let Some(previous_sibling_strong) = previous_sibling_weak.upgrade() {
new_sibling_write.previous_sibling = Some(previous_sibling_weak);
previous_sibling_opt = Some(previous_sibling_strong);
}
}
self_write.previous_sibling = Some(Arc::downgrade(&new_sibling.0));
}
if let Some(previous_sibling_strong) = previous_sibling_opt {
let mut previous_sibling_write = previous_sibling_strong.write();
debug_assert!({
let rc = previous_sibling_write.next_sibling.as_ref().unwrap();
Arc::ptr_eq(rc, &self.0)
});
previous_sibling_write.next_sibling = Some(new_sibling.0);
} else {
if let Some(parent_ref) = self_write.parent.as_ref() {
if let Some(parent_strong) = parent_ref.upgrade() {
let mut parent_write = parent_strong.write();
parent_write.first_child = Some(new_sibling.0);
}
}
}
}
pub fn make_copy(&self) -> Node<T>
where
T: Clone,
{
Node::new(self.read().clone())
}
pub fn make_deep_copy(&self) -> Node<T>
where
T: Clone,
{
let mut root = self.make_copy();
Node::_make_deep_copy(&mut root, self);
root
}
fn _make_deep_copy(parent: &mut Node<T>, node: &Node<T>)
where
T: Clone,
{
for child in node.children() {
let mut new_node = child.make_copy();
parent.append(new_node.clone());
if child.has_children() {
Node::_make_deep_copy(&mut new_node, &child);
}
}
}
}
impl<T> Clone for WeakNode<T> {
fn clone(&self) -> Self {
WeakNode(Weak::clone(&self.0))
}
}
impl<T: fmt::Debug> fmt::Debug for WeakNode<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("(WeakNode)")
}
}
impl<T> WeakNode<T> {
pub fn upgrade(&self) -> Option<Node<T>> {
self.0.upgrade().map(Node)
}
}
impl<T> NodeData<T> {
fn detach(&mut self) {
let parent_weak = self.parent.take();
let previous_sibling_weak = self.previous_sibling.take();
let next_sibling_strong = self.next_sibling.take();
let previous_sibling_opt = previous_sibling_weak
.as_ref()
.and_then(|weak| weak.upgrade());
if let Some(next_sibling_ref) = next_sibling_strong.as_ref() {
let mut next_sibling_write = next_sibling_ref.write();
next_sibling_write.previous_sibling = previous_sibling_weak;
} else if let Some(parent_ref) = parent_weak.as_ref() {
if let Some(parent_strong) = parent_ref.upgrade() {
let mut parent_write = parent_strong.write();
parent_write.last_child = previous_sibling_weak;
}
}
if let Some(previous_sibling_strong) = previous_sibling_opt {
let mut previous_sibling_write = previous_sibling_strong.write();
previous_sibling_write.next_sibling = next_sibling_strong;
} else if let Some(parent_ref) = parent_weak.as_ref() {
if let Some(parent_strong) = parent_ref.upgrade() {
let mut parent_write = parent_strong.write();
parent_write.first_child = next_sibling_strong;
}
}
}
}
impl<T> Drop for NodeData<T> {
fn drop(&mut self) {
if let Some(child) = self.first_child.take() {
let mut open_set = vec![child];
while let Some(node) = open_set.pop() {
let mut node_data = node.write();
if let Some(next_sibling) = node_data.next_sibling.as_ref() {
open_set.push(next_sibling.clone());
}
if Arc::strong_count(&node) == 1 {
if let Some(first_child) = node_data.first_child.as_ref() {
open_set.push(first_child.clone());
}
}
node_data.detach();
}
}
}
}
pub struct Ancestors<T>(Option<Node<T>>);
impl<T> Iterator for Ancestors<T> {
type Item = Node<T>;
fn next(&mut self) -> Option<Self::Item> {
let node = self.0.take()?;
self.0 = node.parent();
Some(node)
}
}
pub struct PrecedingSiblings<T>(Option<Node<T>>);
impl<T> Iterator for PrecedingSiblings<T> {
type Item = Node<T>;
fn next(&mut self) -> Option<Self::Item> {
let node = self.0.take()?;
self.0 = node.previous_sibling();
Some(node)
}
}
pub struct FollowingSiblings<T>(Option<Node<T>>);
impl<T> Iterator for FollowingSiblings<T> {
type Item = Node<T>;
fn next(&mut self) -> Option<Self::Item> {
let node = self.0.take()?;
self.0 = node.next_sibling();
Some(node)
}
}
pub struct Children<T> {
next: Option<Node<T>>,
next_back: Option<Node<T>>,
}
impl<T> Children<T> {
fn finished(&self) -> bool {
match self.next_back {
Some(ref next_back) => next_back.next_sibling() == self.next,
_ => true,
}
}
}
impl<T> Iterator for Children<T> {
type Item = Node<T>;
fn next(&mut self) -> Option<Self::Item> {
if self.finished() {
return None;
}
let node = self.next.take()?;
self.next = node.next_sibling();
Some(node)
}
}
impl<T> DoubleEndedIterator for Children<T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.finished() {
return None;
}
let node = self.next_back.take()?;
self.next_back = node.previous_sibling();
Some(node)
}
}
pub struct Descendants<T>(Traverse<T>);
impl<T> Iterator for Descendants<T> {
type Item = Node<T>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.0.next() {
Some(NodeEdge::Start(node)) => return Some(node),
Some(NodeEdge::End(_)) => {}
None => return None,
}
}
}
}
#[derive(Clone, Debug)]
pub enum NodeEdge<T> {
Start(Node<T>),
End(Node<T>),
}
impl<T> PartialEq for NodeEdge<T> {
fn eq(&self, other: &NodeEdge<T>) -> bool {
match (self, other) {
(&NodeEdge::Start(ref n1), &NodeEdge::Start(ref n2)) => *n1 == *n2,
(&NodeEdge::End(ref n1), &NodeEdge::End(ref n2)) => *n1 == *n2,
_ => false,
}
}
}
impl<T> NodeEdge<T> {
fn next_edge(&self, root: &Node<T>) -> Option<NodeEdge<T>> {
match *self {
NodeEdge::Start(ref node) => match node.first_child() {
Some(first_child) => Some(NodeEdge::Start(first_child)),
None => Some(NodeEdge::End(node.clone())),
},
NodeEdge::End(ref node) => {
if *node == *root {
None
} else {
match node.next_sibling() {
Some(next_sibling) => Some(NodeEdge::Start(next_sibling)),
None => node.parent().map(NodeEdge::End),
}
}
}
}
}
fn previous_edge(&self, root: &Node<T>) -> Option<NodeEdge<T>> {
match *self {
NodeEdge::End(ref node) => match node.last_child() {
Some(last_child) => Some(NodeEdge::End(last_child)),
None => Some(NodeEdge::Start(node.clone())),
},
NodeEdge::Start(ref node) => {
if *node == *root {
None
} else {
match node.previous_sibling() {
Some(previous_sibling) => Some(NodeEdge::End(previous_sibling)),
None => node.parent().map(NodeEdge::Start),
}
}
}
}
}
}
pub struct Traverse<T> {
root: Node<T>,
next: Option<NodeEdge<T>>,
next_back: Option<NodeEdge<T>>,
}
impl<T> Traverse<T> {
fn finished(&self) -> bool {
match self.next_back {
Some(ref next_back) => next_back.next_edge(&self.root) == self.next,
_ => true,
}
}
}
impl<T> Iterator for Traverse<T> {
type Item = NodeEdge<T>;
fn next(&mut self) -> Option<Self::Item> {
if self.finished() {
return None;
}
let node = self.next.take()?;
self.next = node.next_edge(&self.root);
Some(node)
}
}
impl<T> DoubleEndedIterator for Traverse<T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.finished() {
return None;
}
let node = self.next_back.take()?;
self.next_back = node.previous_edge(&self.root);
Some(node)
}
}