use crate::locators;
use super::basic_tree::*;
use super::*;
use rand;
type T = u64;
pub struct Treap<D: Data> {
tree: BasicTree<D, T>,
}
impl<D: Data> SomeTree<D> for Treap<D> {
fn segment_summary_imm<L>(&self, locator: L) -> D::Summary
where
L: locators::Locator<D>,
D::Value: Clone,
{
segment_algorithms::segment_summary_imm(&self.tree, locator)
}
fn segment_summary<L>(&mut self, locator: L) -> D::Summary
where
L: crate::Locator<D>,
{
segment_algorithms::segment_summary(self, locator)
}
fn act_segment<L>(&mut self, action: D::Action, locator: L)
where
L: crate::Locator<D>,
{
if !action.to_reverse() {
segment_algorithms::act_segment(self, action, locator)
} else {
let mut mid: Treap<D> = self
.slice(locators::LeftEdgeOf(locator.clone()))
.split_right()
.unwrap();
let mut walker2 = TreapWalker {
walker: BasicWalker::new_with_context(
&mut mid.tree,
self.subtree_summary(),
Default::default(),
),
};
walker2.search_subtree(locators::RightEdgeOf(locator));
let right = walker2.split_right().unwrap();
drop(walker2);
mid.act_subtree(action);
mid.concatenate_right(right);
self.concatenate_right(mid);
}
}
type TreeData = T;
fn iter_locator<'a, L: locators::Locator<D>>(
&'a mut self,
locator: L,
) -> basic_tree::iterators::IterLocator<'a, D, L, T> {
iterators::IterLocator::new(&mut self.tree, locator)
}
fn assert_correctness(&self)
where
D::Summary: Eq,
{
self.tree.assert_correctness_with(|node| {
Self::assert_priorities_locally_internal(node);
node.assert_correctness_locally();
});
}
}
impl<D: Data> Default for Treap<D> {
fn default() -> Self {
Treap::new()
}
}
impl<'a, D: Data> SomeTreeRef<D> for &'a mut Treap<D> {
type Walker = TreapWalker<'a, D>;
fn walker(self) -> Self::Walker {
TreapWalker {
walker: self.tree.walker(),
}
}
}
impl<'a, D: Data> ModifiableTreeRef<D> for &'a mut Treap<D> {
type ModifiableWalker = TreapWalker<'a, D>;
}
derive_SomeEntry! {tree, T,
impl<D: Data> SomeEntry<D> for Treap<D> {
fn assert_correctness_locally(&self)
where
D::Summary: Eq,
{
if let Some(node) = self.tree.node() {
Self::assert_priorities_locally_internal(node);
node.assert_correctness_locally();
}
}
}
}
impl<D: Data> BasicTree<D, T> {
pub fn priority(&self) -> Option<T> {
Some(self.node()?.alg_data)
}
}
impl<D: Data> Treap<D> {
pub fn new() -> Treap<D> {
Treap {
tree: BasicTree::Empty,
}
}
pub fn priority(&self) -> Option<T> {
self.tree.priority()
}
pub fn union(&mut self, tree2: Treap<D>)
where
D::Value: Ord,
{
union_internal(&mut self.tree, tree2);
}
pub fn assert_priorities_locally(&self) {
if let Some(node) = self.tree.node() {
Self::assert_priorities_locally_internal(node);
}
}
fn assert_priorities_locally_internal(node: &BasicNode<D, T>) {
if let Some(left) = node.left.node() {
assert!(node.alg_data() > left.alg_data());
}
if let Some(right) = node.right.node() {
assert!(node.alg_data() > right.alg_data());
}
}
pub fn assert_priorities(&self) {
self.tree
.assert_correctness_with(Self::assert_priorities_locally_internal);
}
}
impl<D: Data> std::iter::FromIterator<D::Value> for Treap<D> {
fn from_iter<T: IntoIterator<Item = D::Value>>(iter: T) -> Self {
let mut tree = Treap {
tree: BasicTree::Empty,
};
let mut walker = tree.walker();
for val in iter {
walker.insert(val).unwrap();
while let Ok(()) = walker.go_right() {}
}
drop(walker);
tree
}
}
impl<D: Data> IntoIterator for Treap<D> {
type Item = D::Value;
type IntoIter = iterators::IntoIter<D, std::ops::RangeFull, T>;
fn into_iter(self) -> Self::IntoIter {
iterators::IntoIter::new(self.tree, ..)
}
}
pub struct TreapWalker<'a, D: Data> {
walker: BasicWalker<'a, D, T>,
}
derive_SomeWalker! {walker,
impl<'a, D: Data> SomeWalker<D> for TreapWalker<'a, D> {
fn go_up(&mut self) -> Result<Side, ()> {
self.walker.go_up()
}
}
}
derive_SomeEntry! {walker, T,
impl<'a, D: Data> SomeEntry<D> for TreapWalker<'a, D> {
fn assert_correctness_locally(&self)
where
D::Summary: Eq,
{
self.walker.assert_correctness_locally();
if let Some(node) = self.walker.node() {
Treap::assert_priorities_locally_internal(node);
}
}
}
}
impl<'a, D: Data> TreapWalker<'a, D> {
pub fn priority(&self) -> Option<T> {
self.walker.inner().priority()
}
pub(super) fn inner_mut(&mut self) -> &mut BasicTree<D, T> {
self.walker.inner_mut()
}
}
impl<'a, D: Data> ModifiableWalker<D> for TreapWalker<'a, D> {
fn insert(&mut self, val: D::Value) -> Option<()> {
if !self.is_empty() {
return None;
}
let priority: T = rand::random();
let mut temp = BasicTree::Empty;
let mut prev_side = self.walker.is_left_son().unwrap_or(Side::Right);
while let Ok(side) = self.go_up() {
if self.priority().unwrap() > priority {
match side {
Side::Left => self.walker.go_left().unwrap(),
Side::Right => self.walker.go_right().unwrap(),
}
break;
}
if self.priority().unwrap() == priority {
eprintln!("found equal priorities")
}
if prev_side != side {
let node = self.walker.node_mut().unwrap();
let son = match side {
Side::Left => &mut node.left,
Side::Right => &mut node.right,
};
std::mem::swap(&mut temp, son);
self.walker.rebuild();
}
prev_side = side;
}
let mut new: BasicNode<D, _> = BasicNode::new_alg(val, priority);
match prev_side {
Side::Left => {
new.left = temp;
new.right = std::mem::replace(self.walker.inner_mut(), BasicTree::Empty);
}
Side::Right => {
new.right = temp;
new.left = std::mem::replace(self.walker.inner_mut(), BasicTree::Empty);
}
}
new.rebuild();
*self.walker.inner_mut() = BasicTree::from_node(new);
Some(())
}
fn delete(&mut self) -> Option<D::Value> {
let tree = std::mem::replace(self.walker.inner_mut(), BasicTree::Empty);
let node = tree.into_node()?;
let left = Treap { tree: node.left };
let right = Treap { tree: node.right };
*self.walker.inner_mut() = ConcatenableTree::concatenate(left, right).tree;
Some(node.node_value)
}
}
fn union_internal<D: Data>(tree1: &mut BasicTree<D, T>, mut tree2: Treap<D>)
where
D::Value: Ord,
{
if tree2.is_empty() {
return;
}
if tree1.is_empty() {
*tree1 = tree2.tree;
return;
}
if tree1.priority().unwrap() < tree2.priority().unwrap() {
std::mem::swap(tree1, &mut tree2.tree);
}
let node = tree1.node_mut().unwrap();
let key = node.node_value().get_key();
let mut split_walker = tree2.search(
locators::LeftEdgeOf(locators::ByKey((key,)))
);
let right = split_walker.split_right().unwrap();
drop(split_walker);
let left = tree2;
union_internal(&mut node.left, left);
union_internal(&mut node.right, right);
node.rebuild();
}
pub fn union<D: Data>(mut tree1: Treap<D>, tree2: Treap<D>) -> Treap<D>
where
D::Value: Ord,
{
tree1.union(tree2);
tree1
}
impl<D: Data> ConcatenableTree<D> for Treap<D> {
fn concatenate_right(&mut self, tree2: Treap<D>) {
let mut walker = self.walker();
let mut tree_r = tree2.tree;
tree_r.access();
loop {
match (walker.priority(), tree_r.priority()) {
(None, _) => {
*walker.walker.inner_mut() = tree_r;
break;
}
(_, None) => break,
(Some(a), Some(b)) if a > b => {
walker.go_right().unwrap();
}
_ => {
std::mem::swap(walker.walker.inner_mut(), &mut tree_r);
walker.go_left().unwrap();
std::mem::swap(walker.walker.inner_mut(), &mut tree_r);
}
}
}
}
}
impl<'a, D: Data> SplittableTreeRef<D> for &'a mut Treap<D> {
type T = Treap<D>;
type SplittableWalker = TreapWalker<'a, D>;
}
impl<'a, D: Data> SplittableWalker<D> for TreapWalker<'a, D> {
type T = Treap<D>;
fn split_right(&mut self) -> Option<Treap<D>> {
if !self.is_empty() {
return None;
}
let mut temp = BasicTree::Empty;
let mut prev_side = self.walker.is_left_son().unwrap_or(Side::Right);
while let Ok(side) = self.go_up() {
if prev_side != side {
let node = self.walker.node_mut().unwrap();
let son = match side {
Side::Left => &mut node.left,
Side::Right => &mut node.right,
};
std::mem::swap(&mut temp, son);
node.rebuild();
}
prev_side = side;
}
if prev_side == Side::Left {
std::mem::swap(self.walker.inner_mut(), &mut temp);
}
Some(Treap { tree: temp })
}
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)
}
}