use super::basic_tree::*;
use super::*;
use crate::locators;
#[derive(destructure)]
pub struct SplayTree<D: Data> {
tree: BasicTree<D>,
}
impl<D: Data> SplayTree<D> {
pub fn basic_walker(&mut self) -> BasicWalker<D> {
BasicWalker::new(&mut self.tree)
}
pub fn new() -> SplayTree<D> {
SplayTree {
tree: BasicTree::Empty,
}
}
pub fn assert_correctness(&self)
where
D::Summary: Eq,
{
self.tree.assert_correctness()
}
pub fn isolate_segment<'a, L>(&'a mut self, locator: L) -> SplayWalker<'a, D>
where
L: crate::Locator<D>,
{
if self.is_empty() {
return self.walker();
}
let left_edge = locators::LeftEdgeOf(locator.clone());
let mut walker = self.slice(left_edge).search();
let b1 = walker.previous_filled().is_ok();
walker.splay();
if b1 {
walker.go_right().unwrap();
}
let mut walker2 = SplayWalker {
walker: walker.walker.detached_walker(),
};
let right_edge = locators::RightEdgeOf(locator);
walker2.go_to_root();
walker2.search_subtree(right_edge);
let b2 = walker2.next_filled().is_ok();
walker2.splay();
drop(walker2);
if b2 {
walker.go_left().unwrap();
}
walker
}
pub fn into_inner(self) -> BasicTree<D> {
self.destructure().0
}
}
impl<D: Data> std::default::Default for SplayTree<D> {
fn default() -> Self {
SplayTree::new()
}
}
impl<D: Data> Drop for SplayTree<D> {
fn drop(&mut self) {
basic_tree::deallocate_iteratively(&mut self.tree);
}
}
#[derive(destructure)]
pub struct SplayWalker<'a, D: Data> {
walker: BasicWalker<'a, D>,
}
impl<'a, D: Data> SplayWalker<'a, D> {
pub fn new(walker: BasicWalker<'a, D>) -> Self {
SplayWalker { walker }
}
pub fn inner(&self) -> &BasicTree<D> {
self.walker.inner()
}
fn inner_mut(&mut self) -> &mut BasicTree<D> {
self.walker.inner_mut()
}
pub fn into_inner(self) -> BasicWalker<'a, D> {
let (walker,) = self.destructure();
walker
}
pub fn splay_step(&mut self) {
if self.walker.is_empty() {
let _ = self.walker.go_up();
return;
}
let b1 = match self.walker.go_up() {
Err(()) => return, Ok(b1) => b1,
};
let b2 = match self.walker.is_left_son() {
None => {
self.walker.rot_side(b1.flip()).unwrap();
return;
} Some(b2) => b2,
};
if b1 == b2 {
self.walker.rot_up().unwrap();
self.walker.rot_side(b1.flip()).unwrap();
} else {
self.walker.rot_side(b1.flip()).unwrap();
self.walker.rot_up().unwrap();
}
}
pub fn splay_step_depth(&mut self, depth: usize) {
if self.depth() <= depth {
return;
}
if self.walker.is_empty() {
if let Err(()) = self.walker.go_up() {
panic!(); };
return;
}
let b1 = match self.walker.go_up() {
Ok(b1) => b1,
Err(()) => panic!(), };
if self.depth() <= depth {
self.walker.rot_side(b1.flip()).unwrap();
} else {
let b2 = match self.walker.is_left_son() {
None => panic!(), Some(b2) => b2,
};
if b1 == b2 {
self.walker.rot_up().unwrap();
self.walker.rot_side(b1.flip()).unwrap();
} else {
self.walker.rot_side(b1.flip()).unwrap();
self.walker.rot_up().unwrap();
}
}
}
pub fn splay(&mut self) {
self.splay_to_depth(0);
}
pub fn splay_to_depth(&mut self, depth: usize) {
assert!(self.depth() >= depth);
while self.walker.depth() != depth {
self.splay_step_depth(depth);
}
}
}
impl<'a, D: Data> Drop for SplayWalker<'a, D> {
fn drop(&mut self) {
self.splay();
}
}
impl<D: Data> SomeTree<D> for SplayTree<D> {
fn segment_summary_imm<L>(&self, locator: L) -> D::Summary
where
L: locators::Locator<D>,
D::Value: Clone,
{
if cfg!(debug_assertions) {
panic!(".segment_summary_imm() method is inefficient for splay trees")
} else {
self.tree.segment_summary_imm(locator)
}
}
fn segment_summary<L>(&mut self, locator: L) -> D::Summary
where
L: locators::Locator<D>,
{
let walker = self.isolate_segment(locator);
walker.subtree_summary()
}
fn act_segment<L>(&mut self, action: D::Action, locator: L)
where
L: crate::Locator<D>,
{
let mut walker = self.isolate_segment(locator);
walker.act_subtree(action);
}
type TreeData = ();
fn iter_locator<'a, L: locators::Locator<D>>(
&'a mut self,
locator: L,
) -> basic_tree::iterators::IterLocator<'a, D, L> {
self.isolate_segment(locator.clone());
iterators::IterLocator::new(&mut self.tree, locator)
}
fn assert_correctness(&self)
where
D::Summary: Eq,
{
self.tree.assert_correctness();
}
}
derive_SomeEntry! {tree, (),
impl<D: Data> SomeEntry<D> for SplayTree<D> {
fn assert_correctness_locally(&self)
where
D::Summary: Eq,
{
self.tree.assert_correctness_locally();
}
}
}
impl<'a, D: Data> SomeTreeRef<D> for &'a mut SplayTree<D> {
type Walker = SplayWalker<'a, D>;
fn walker(self: &'a mut SplayTree<D>) -> SplayWalker<'a, D> {
SplayWalker {
walker: self.basic_walker(),
}
}
}
impl<'a, D: Data> ModifiableTreeRef<D> for &'a mut SplayTree<D> {
type ModifiableWalker = Self::Walker;
}
impl<D: Data> std::iter::FromIterator<D::Value> for SplayTree<D> {
fn from_iter<T: IntoIterator<Item = D::Value>>(iter: T) -> Self {
SplayTree {
tree: iter.into_iter().collect(),
}
}
}
impl<D: Data> IntoIterator for SplayTree<D> {
type Item = D::Value;
type IntoIter = <BasicTree<D> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.into_inner().into_iter()
}
}
derive_SomeWalker! {walker,
impl<'a, D: Data> SomeWalker<D> for SplayWalker<'a, D> {
fn go_up(&mut self) -> Result<Side, ()> {
self.walker.go_up()
}
fn previous_filled(&mut self) -> Result<(), ()> {
match self.walker.node() {
None => {}
Some(node) => {
if !node.left.is_empty() {
self.go_left().unwrap();
while self.go_right().is_ok() {}
let r = self.go_up();
assert_eq!(r, Ok(Side::Right));
return Ok(());
}
}
}
let count = match self.walker.steps_until_sided_ancestor(Side::Right) {
None => {
self.splay();
return Err(());
}
Some(count) => count,
};
let depth = self.depth();
self.splay_to_depth(depth - count + 1);
let r = self.go_up();
assert_eq!(r, Ok(Side::Right));
Ok(())
}
fn next_filled(&mut self) -> Result<(), ()> {
match self.walker.node() {
None => {}
Some(node) => {
if !node.right.is_empty() {
self.go_right().unwrap();
while self.go_left().is_ok() {}
let r = self.go_up();
assert_eq!(r, Ok(Side::Left));
return Ok(());
}
}
}
let count = match self.walker.steps_until_sided_ancestor(Side::Left) {
None => {
self.splay();
return Err(());
}
Some(count) => count,
};
let depth = self.depth();
self.splay_to_depth(depth - count + 1);
let r = self.go_up();
assert_eq!(r, Ok(Side::Left));
Ok(())
}
}
}
derive_SomeEntry! {walker, (),
impl<'a, D: Data> SomeEntry<D> for SplayWalker<'a, D> {
fn assert_correctness_locally(&self)
where
D::Summary: Eq,
{
self.walker.assert_correctness_locally();
}
}
}
impl<'a, D: Data> ModifiableWalker<D> for SplayWalker<'a, D> {
fn insert(&mut self, value: D::Value) -> Option<()> {
self.walker.insert(value)
}
fn delete(&mut self) -> Option<D::Value> {
let mut node = self.walker.take_subtree().into_node()?;
if node.right.is_empty() {
self.walker.put_subtree(node.left).unwrap();
} else {
let mut walker = node.right.walker();
while walker.go_left().is_ok() {}
let res = walker.go_up();
assert_eq!(res, Ok(Side::Left));
let mut boxed_replacement_node = walker.take_subtree().into_node_boxed().unwrap();
assert!(boxed_replacement_node.left.is_empty());
walker.put_subtree(boxed_replacement_node.right).unwrap();
drop(SplayWalker { walker });
boxed_replacement_node.left = node.left;
boxed_replacement_node.right = node.right;
boxed_replacement_node.rebuild();
self.walker
.put_subtree(BasicTree::from_boxed_node(boxed_replacement_node))
.unwrap();
}
Some(node.node_value)
}
}
impl<D: Data> ConcatenableTree<D> for SplayTree<D> {
fn concatenate_right(&mut self, other: Self) {
let mut walker = self.walker();
while walker.go_right().is_ok() {}
match walker.go_up() {
Err(()) => {
drop(walker);
*self = other;
return;
}
Ok(Side::Right) => (),
Ok(Side::Left) => unreachable!(),
};
walker.splay();
let node = walker.inner_mut().node_mut().unwrap();
assert!(node.right.is_empty());
node.right = other.into_inner();
node.rebuild();
}
}
impl<'a, D: Data> SplittableTreeRef<D> for &'a mut SplayTree<D> {
type T = SplayTree<D>;
type SplittableWalker = SplayWalker<'a, D>;
}
impl<'a, D: Data> SplittableWalker<D> for SplayWalker<'a, D> {
type T = SplayTree<D>;
fn split_right(&mut self) -> Option<SplayTree<D>> {
if !self.is_empty() {
return None;
}
let side = match self.go_up() {
Err(()) => return Some(SplayTree::new()), Ok(b) => b,
};
self.splay();
let node = match self.inner_mut().node_mut() {
Some(node) => node,
_ => panic!(),
};
match side {
Side::Left => {
let mut tree = std::mem::replace(&mut node.left, BasicTree::Empty);
node.rebuild();
std::mem::swap(self.inner_mut(), &mut tree);
Some(SplayTree { tree })
}
Side::Right => {
let tree = std::mem::replace(&mut node.right, BasicTree::Empty);
node.rebuild();
Some(SplayTree { tree })
}
}
}
fn split_left(&mut self) -> Option<Self::T> {
let mut right = self.split_right()?;
std::mem::swap(self.inner_mut(), &mut right.tree);
Some(right)
}
}