Skip to content

Commit

Permalink
1. [refactoring] split linked::singly::Node into Link and Node
Browse files Browse the repository at this point in the history
  • Loading branch information
oooutlk committed Aug 27, 2018
1 parent 68e2e68 commit 35a9dba
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 80 deletions.
1 change: 0 additions & 1 deletion src/linked/fully/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ impl<T> Node<T> {
forest.set_parent( self as *mut Node<T> );
if self.is_leaf() {
self.set_child( forest.tail() );
forest.clear();
} else { unsafe {
let forest_head = forest.head();
forest.set_sib( self.tail(), self.head() );
Expand Down
44 changes: 20 additions & 24 deletions src/linked/singly/forest.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//! `Forest` composed of disjoint `Tree`s.

use super::{Node,Tree,Iter,IterMut,OntoIter};
use super::{Node,Link,Tree,Iter,IterMut,OntoIter};
use rust::*;

/// A nullable forest
pub struct Forest<T> {
child : *mut Node<T>,
mark : super::heap::Phantom<T>,
link : Link,
mark : super::heap::Phantom<T>,
}

impl<T> Forest<T> {
Expand All @@ -26,27 +26,21 @@ impl<T> Forest<T> {
/// forest.push_back( tr(1) );
/// assert!( !forest.is_empty() );
/// ```
#[inline] pub fn is_empty( &self ) -> bool { self.child.is_null() }
#[inline] pub fn is_empty( &self ) -> bool { self.link.has_no_child() }

#[inline] pub(crate) fn set_child( &mut self, node: *mut Node<T> ) { self.child = node; }
#[inline] pub(crate) fn from( node: *mut Node<T> ) -> Self { Forest{ child: node, mark: PhantomData } }
#[inline] pub(crate) fn clear( &mut self ) { self.child = null_mut(); }
#[inline] pub(crate) fn set_child( &mut self, node: *mut Node<T> ) { self.link.set_child( node as *mut Link ); }
#[inline] pub(crate) fn from( node: *mut Node<T> ) -> Self { Forest{ link: Link{ next: null_mut(), child: node as *mut Link }, mark: PhantomData }}
#[inline] pub(crate) fn clear( &mut self ) { self.link.reset_child(); }

#[inline] pub(crate) unsafe fn set_sib( &mut self, sib: *mut Node<T> ) {
(*self.tail()).next = sib;
}
#[inline] pub(crate) unsafe fn set_sib( &mut self, sib: *mut Node<T> ) { (*self.tail()).set_sib( sib ); }

#[inline] pub(crate) unsafe fn head ( &self ) -> *mut Node<T> { (*self.child).next }
#[inline] pub(crate) fn tail ( &self ) -> *mut Node<T> { self.child }
#[inline] pub(crate) unsafe fn new_head( &self ) -> *mut Node<T> { (*self.head()).next }
#[inline] pub(crate) unsafe fn head ( &self ) -> *mut Node<T> { self.link.head() as *mut Node<T> }
#[inline] pub(crate) fn tail ( &self ) -> *mut Node<T> { self.link.tail() as *mut Node<T> }
#[inline] pub(crate) unsafe fn new_head( &self ) -> *mut Node<T> { self.link.new_head() as *mut Node<T> }

#[inline] pub(crate) unsafe fn has_only_one_child( &self ) -> bool { self.head() == self.tail() }
#[inline] pub(crate) unsafe fn has_only_one_child( &self ) -> bool { self.link.has_only_one_child() }

#[inline] pub(crate) fn adopt( &mut self, child: *mut Node<T> ) {
unsafe {
(*self.tail()).next = child;
}
}
#[inline] pub(crate) fn adopt( &mut self, child: *mut Node<T> ) { unsafe { self.link.adopt( child as *mut Link )}}

/// Returns the first child of the forest,
/// or None if it is empty.
Expand Down Expand Up @@ -147,7 +141,7 @@ impl<T> Forest<T> {
if self.has_only_one_child() {
self.clear();
} else {
(*self.tail()).next = self.new_head();
(*self.tail()).set_sib( self.new_head() );
}
(*front).reset_sib();
Some( Tree::from( front ))
Expand Down Expand Up @@ -246,16 +240,18 @@ impl<T> Forest<T> {
if self.is_empty() {
OntoIter {
next: null_mut(), curr: null_mut(), prev: null_mut(), child: null_mut(),
ptail: &mut self.child as *mut *mut Node<T>,
//ptail: &mut self.child as *mut *mut Node<T>,
parent: &mut self.link as *mut Link,
mark: PhantomData,
}
} else {
OntoIter {
next : self.head(),
curr : null_mut(),
prev : self.child,
child : self.child,
ptail : &mut self.child as *mut *mut Node<T>,
prev : self.tail(),
child : self.tail(),
//ptail : &mut self.child as *mut *mut Node<T>,
parent: &mut self.link as *mut Link,
mark : PhantomData,
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/linked/singly/heap.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
//! Dynamic allocation/deallocation on heap.

use super::Node;
use super::{Node,Link};

use rust::*;

pub type Phantom<T> = PhantomData<Box<Node<T>>>;

pub(crate) fn make_node<T>( data: T ) -> *mut Node<T> {
let mut node = Box::new( Node {
next : null_mut(),
child : null_mut(),
data : data,
});
let mut node = Box::new(
Node {
link: Link {
next : null_mut(),
child : null_mut(),
},
data,
}
);
node.reset_sib();
Box::into_raw( node )
}
Expand Down
4 changes: 2 additions & 2 deletions src/linked/singly/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl<'a, T:'a> Iterator for Iter<'a, T> {
self.head = if self.head == self.tail {
null()
} else {
(*node).next
(*node).link.next as *mut Node<T>
};
Some( &*node )
}}
Expand Down Expand Up @@ -68,7 +68,7 @@ impl<'a, T:'a> Iterator for IterMut<'a, T> {
self.head = if self.head == self.tail {
null_mut()
} else {
(*node).next
(*node).link.next as *mut Node<T>
};
Some( &mut *node )
}}
Expand Down
1 change: 1 addition & 0 deletions src/linked/singly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use self::forest::Forest;

pub mod node;
pub use self::node::Node;
pub(crate) use self::node::Link;

pub mod notation;
pub use self::notation::{tr,fr};
Expand Down
59 changes: 42 additions & 17 deletions src/linked/singly/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@
use super::{Tree,Forest,Iter,IterMut,OntoIter};
use rust::*;

pub(crate) struct Link {
pub(crate) next : *mut Link, // next sibling
pub(crate) child : *mut Link, // last child
}

#[repr(C)]
pub struct Node<T> {
pub(crate) next : *mut Node<T>, // next sibling
pub(crate) child : *mut Node<T>, // last child
pub data : T,
pub(crate) link : Link,
pub data : T,
}

impl<T> Node<T> {
#[inline] pub(crate) fn set_child( &mut self, child: *mut Node<T> ) { self.child = child; }
impl Link {
#[inline] pub(crate) fn set_child( &mut self, child: *mut Self ) { self.child = child; }
#[inline] pub(crate) fn reset_child( &mut self ) { self.set_child( null_mut() ); }
#[inline] pub fn is_leaf( &self ) -> bool { self.child.is_null() }
#[inline] pub(crate) fn has_no_child( &self ) -> bool { self.child.is_null() }
#[inline] pub(crate) unsafe fn has_only_one_child( &self ) -> bool { self.head() == self.tail() }

#[inline] pub(crate) fn set_sib( &mut self, sib: *mut Self ) { self.next = sib; }
Expand All @@ -21,9 +26,28 @@ impl<T> Node<T> {

#[inline] pub(crate) unsafe fn head( &self ) -> *mut Self { (*self.child).next }
#[inline] pub(crate) fn tail( &self ) -> *mut Self { self.child }
#[inline] pub(crate) unsafe fn new_head( &self ) -> *mut Node<T> { (*self.head()).next }
#[inline] pub(crate) unsafe fn new_head( &self ) -> *mut Self { (*self.head()).next }

#[inline] pub(crate) unsafe fn adopt( &mut self, child: *mut Self ) { (*self.tail()).next = child; }
}

impl<T> Node<T> {
#[inline] pub(crate) fn set_child( &mut self, child: *mut Self ) { self.link.set_child( child as *mut Link ); }
#[inline] pub(crate) fn reset_child( &mut self ) { self.link.reset_child(); }
#[inline] pub fn is_leaf( &self ) -> bool { self.link.has_no_child() }
#[inline] pub(crate) unsafe fn has_only_one_child( &self ) -> bool { self.head() == self.tail() }

#[inline] pub(crate) fn set_sib( &mut self, sib: *mut Self ) { self.link.set_sib( sib as *mut Link ); }
#[inline] pub(crate) fn reset_sib( &mut self ) { self.link.reset_sib(); }
#[inline] pub(crate) fn has_no_sib( &self ) -> bool { self.link.has_no_sib() }

#[inline] pub(crate) unsafe fn head( &self ) -> *mut Self { self.link.head() as *mut Self }
#[inline] pub(crate) fn tail( &self ) -> *mut Self { self.link.tail() as *mut Self }
#[inline] pub(crate) unsafe fn new_head( &self ) -> *mut Self { self.link.new_head() as *mut Self }

#[inline] pub(crate) unsafe fn adopt( &mut self, child: *mut Self ) { (*self.tail()).set_sib( child ); }

#[inline] pub(crate) unsafe fn adopt( &mut self, child: *mut Node<T> ) { (*self.tail()).next = child; }
#[inline] pub(crate) fn next( &self ) -> *mut Self { self.link.next as *mut Self }

/// Returns the first child of the forest,
/// or None if it is empty.
Expand Down Expand Up @@ -126,7 +150,7 @@ impl<T> Node<T> {
if self.has_only_one_child() {
self.reset_child();
} else {
(*self.tail()).next = self.new_head();
(*self.tail()).set_sib( self.new_head() );
}
(*front).reset_sib();
Some( Tree::from( front ))
Expand Down Expand Up @@ -171,7 +195,6 @@ impl<T> Node<T> {
if !forest.is_empty() {
if self.is_leaf() {
self.set_child( forest.tail() );
forest.clear();
} else { unsafe {
let forest_head = forest.head();
forest.set_sib( self.head() );
Expand Down Expand Up @@ -227,17 +250,19 @@ impl<T> Node<T> {
if self.is_leaf() {
OntoIter {
next: null_mut(), curr: null_mut(), prev: null_mut(), child: null_mut(),
ptail: &mut self.child as *mut *mut Node<T>,
//ptail: &mut self.child as *mut *mut Node<T>,
parent: &mut self.link,
mark: PhantomData,
}
} else {
OntoIter {
next : self.head(),
curr : null_mut(),
prev : self.child,
child : self.child,
ptail : &mut self.child as *mut *mut Node<T>,
mark : PhantomData,
next : self.head(),
curr : null_mut(),
prev : self.tail(),
child : self.tail(),
//ptail : &mut self.child as *mut *mut Node<T>,
parent : &mut self.link,
mark : PhantomData,
}
}
}
Expand Down
50 changes: 24 additions & 26 deletions src/linked/singly/onto_iter.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
//! A full functional mutable iterator implementation with the extra ability of inserting/removing `Node` at any position than `IterMut`.

use super::{Node,Tree};
use super::{Node,Link,Tree};
use rust::*;

/// Wrapper of `Node` for allowing modification of parent or sib links.
/// Any `Node` that is the root of some `Tree` is impossible to be `Subnode`.
pub struct Subnode<'a, T:'a>{
node : &'a mut Node<T>,
prev : *mut Node<T>,
ptail : *mut *mut Node<T>,
node : &'a mut Node<T>,
prev : *mut Node<T>,
parent : *mut Link,
//ptail : *mut *mut Node<T>,
}

impl<'a, T:'a> Subnode<'a,T> {
Expand All @@ -25,8 +26,8 @@ impl<'a, T:'a> Subnode<'a,T> {
/// ```
#[inline] pub fn insert_before( &mut self, mut sib: Tree<T> ) {
unsafe {
sib.root_mut().next = self.node as *mut Node<T>;
(*self.prev).next = sib.root_mut();
sib.root_mut().set_sib( self.node );
(*self.prev).set_sib( sib.root_mut() );
}
sib.clear();
}
Expand All @@ -44,10 +45,10 @@ impl<'a, T:'a> Subnode<'a,T> {
/// ```
#[inline] pub fn insert_after( &mut self, mut sib: Tree<T> ) {
unsafe {
(*sib.root_mut()).next = self.node.next;
self.node.next = sib.root_mut();
if (*self.ptail) == self.node as *mut Node<T> {
*self.ptail = sib.root_mut();
(*sib.root_mut()).set_sib( self.node.next() );
self.node.set_sib( sib.root_mut() );
if (*self.parent).tail() == self.node as *mut Node<T> as *mut Link {
(*self.parent).set_child( &mut sib.root_mut().link );
}
}
sib.clear();
Expand All @@ -66,14 +67,10 @@ impl<'a, T:'a> Subnode<'a,T> {
/// ```
#[inline] pub fn depart( self ) -> Tree<T> {
unsafe {
if (*self.ptail) == self.node as *mut Node<T> {
*self.ptail = if self.node.has_no_sib() {
null_mut()
} else {
self.prev
}
if (*self.parent).tail() == self.node as *mut Node<T> as *mut Link {
(*self.parent).set_child( ( if self.node.has_no_sib() { null_mut() } else { self.prev } ) as *mut Link );
}
(*self.prev).next = self.node.next;
(*self.prev).set_sib( self.node.next() );
self.node.reset_sib();
Tree::from( self.node as *mut Node<T> )
}
Expand All @@ -89,12 +86,13 @@ impl<'a, T:'a> DerefMut for Subnode<'a,T> { fn deref_mut( &mut self ) -> &mut No

/// Mutable iterator allowing modification of parent or sib links.
pub struct OntoIter<'a, T:'a>{
pub(crate) next : *mut Node<T>,
pub(crate) curr : *mut Node<T>,
pub(crate) prev : *mut Node<T>,
pub(crate) child : *mut Node<T>,
pub(crate) ptail : *mut *mut Node<T>,
pub(crate) mark : PhantomData<&'a mut Node<T>>,
pub(crate) next : *mut Node<T>,
pub(crate) curr : *mut Node<T>,
pub(crate) prev : *mut Node<T>,
pub(crate) child : *mut Node<T>,
//pub(crate) ptail : *mut *mut Node<T>,
pub(crate) parent : *mut Link,
pub(crate) mark : PhantomData<&'a mut Node<T>>,
}

impl<'a, T:'a> Iterator for OntoIter<'a,T> {
Expand All @@ -107,7 +105,7 @@ impl<'a, T:'a> Iterator for OntoIter<'a,T> {
return None;
}
unsafe {
if (*self.prev).next != self.next {
if (*self.prev).next() != self.next {
self.prev = self.curr; // curr did not depart()-ed
}
}
Expand All @@ -116,8 +114,8 @@ impl<'a, T:'a> Iterator for OntoIter<'a,T> {
if !self.next.is_null() {
let curr = self.next;
unsafe {
self.next = (*curr).next;
return Some( Subnode{ node: &mut *curr, prev: self.prev, ptail: self.ptail });
self.next = (*curr).next();
return Some( Subnode{ node: &mut *curr, prev: self.prev, parent: self.parent });
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/linked/singly/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<T> Tree<T> {
/// assert_eq!( tree, tr(0) );
/// ```
#[inline] pub fn abandon( &mut self ) -> Forest<T> {
let forest = Forest::<T>::from( self.child );
let forest = Forest::<T>::from( self.root().tail() );
self.reset_child();
forest
}
Expand Down
6 changes: 3 additions & 3 deletions src/linked/singly/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct Nodes<T> {

impl<T> Nodes<T> {
/// Only the given node will be visited.
#[inline] fn this( node: *const Node<T> ) -> Self { Nodes{ node, sentinel: unsafe{ (*node).next }}}
#[inline] fn this( node: *const Node<T> ) -> Self { Nodes{ node, sentinel: unsafe{ (*node).next() }}}

/// The given node and all its siblings will be visited.
#[inline] fn sibs( node: *const Node<T> ) -> Self { Nodes{ node, sentinel: node }}
Expand Down Expand Up @@ -151,7 +151,7 @@ impl<T> Walk<T> {
}
Direction::Right => {
if let Some( nodes ) = self.path.last_mut() {
nodes.node = unsafe{ (*nodes.node).next };
nodes.node = unsafe{ (*nodes.node).next() };
if nodes.node == nodes.sentinel {
self.direction = Direction::Up;
continue;
Expand Down Expand Up @@ -207,7 +207,7 @@ impl<T> Walk<T> {
#[inline] fn to_sib( &mut self, n: usize ) -> Option<Visit<T>> {
if let Some( nodes ) = self.path.last_mut() {
for _ in 0..n {
nodes.node = unsafe{ (*nodes.node).next };
nodes.node = unsafe{ (*nodes.node).next() };
if nodes.node == nodes.sentinel {
self.direction = Direction::Up;
return None;
Expand Down

0 comments on commit 35a9dba

Please sign in to comment.