use std::mem;
use arrayvec::ArrayVec;
use crate::constants::*;
use crate::subtree::{self, Subtree};
use std::iter;
use std::slice;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct InnerSkewList<T> {
pub values: ArrayVec<ChildNodes<T>>,
pub tree_size: usize,
pub size: usize,
pub tail: Option<Ref<InnerSkewList<T>>>,
}
impl<T> InnerSkewList<T> {
pub fn empty() -> Self {
InnerSkewList {
values: ArrayVec::new(),
tree_size: NODE_SIZE,
size: 0,
tail: None,
}
}
pub fn new(node: FullChunk<T>) -> Self {
let mut self_ = InnerSkewList::empty();
self_.push(Subtree::new_leaf(node));
self_
}
pub fn full(nodes: ChildNodes<T>, tree_size: usize) -> Self {
InnerSkewList {
values: ArrayVec::from(nodes),
tree_size,
size: tree_size * FANOUT,
tail: None,
}
}
fn push(&mut self, node: Subtree<T>) {
self.values.push(node);
self.size += self.tree_size;
}
fn pop(&mut self) -> Option<Subtree<T>> {
let popped = self.values.pop()?;
self.size -= self.tree_size;
Some(popped)
}
fn lookup_local(&self, i: usize) -> Result<&T, usize> {
if i >= self.size {
Err(i - self.size)
} else {
let (idx, new_i) = get_idx(i, self.tree_size);
Ok(self.values[self.values.len() - 1 - idx].get(new_i, self.tree_size))
}
}
fn lookup_static(mut skew_list: &Self, mut i: usize) -> Option<&T> {
loop {
match skew_list.lookup_local(i) {
Ok(value) => {
break Some(value);
}
Err(new_i) => {
i = new_i;
skew_list = match skew_list.tail {
Some(ref x) => &**x,
None => {
break None;
}
};
}
}
}
}
pub fn get(&self, i: usize) -> Option<&T> {
Self::lookup_static(self, i)
}
pub fn add_one(self_: &mut Ref<Self>, tree: FullChunk<T>) {
if self_.values.len() == FANOUT {
Self::upgrade(self_, tree);
} else if self_.tree_size == NODE_SIZE {
let mut_self = Ref::make_mut(self_);
mut_self.push(Subtree::new_leaf(tree));
} else {
let new_head = Self::new(tree);
let old_self = mem::replace(self_, Ref::new(new_head));
let mut_head = Ref::make_mut(self_);
mut_head.tail = Some(old_self);
}
}
pub fn subtract_one(self_: &mut Ref<Self>) -> Option<FullChunk<T>> {
let mut_self = Ref::make_mut(self_);
let child = mut_self.pop()?;
let (children_opt, values) = child.downgrade();
if let Some(children_rc) = children_opt {
Self::downgrade(self_, children_rc);
} else if self_.values.is_empty() {
if let Some(tail) = Ref::make_mut(self_).tail.take() {
mem::replace(self_, tail);
}
}
Some(values)
}
pub fn upgrade(self_: &mut Ref<Self>, new_root: FullChunk<T>) {
let new_tree_size = increment_tree_size(self_.tree_size);
let mut_self = Ref::make_mut(self_);
if mut_self
.tail
.as_ref()
.map(|tail| tail.tree_size == new_tree_size)
.unwrap_or(false)
{
let tail_rc = mut_self.tail.take().unwrap();
let old_self_rc = mem::replace(self_, tail_rc);
let tail = self_;
let old_self = Ref::try_unwrap(old_self_rc).ok().unwrap();
let values = old_self.values.into_inner().ok().unwrap();
let new_subtree = Subtree::upgrade(values, new_root);
let mut_tail = Ref::make_mut(tail);
mut_tail.push(new_subtree);
} else {
let old_array = mem::replace(&mut mut_self.values, ArrayVec::new());
let values = old_array.into_inner().ok().unwrap();
let new_subtree = Subtree::upgrade(values, new_root);
mut_self.values.push(new_subtree);
mut_self.tree_size = new_tree_size;
mut_self.size = new_tree_size;
}
}
pub fn downgrade(self_: &mut Ref<Self>, values: Ref<ChildNodes<T>>) {
let values = Ref::try_unwrap(values).unwrap_or_else(|rc| (&*rc).clone());
let new_tree_size = decrement_tree_size(self_.tree_size);
if self_.values.is_empty() {
let mut_self = Ref::make_mut(self_);
mut_self.values = ArrayVec::from(values);
mut_self.tree_size = decrement_tree_size(mut_self.tree_size);
mut_self.size = mut_self.tree_size * FANOUT;
} else {
let mut new_head = InnerSkewList::full(values, new_tree_size);
new_head.tail = Some(self_.clone());
mem::replace(self_, Ref::new(new_head));
}
}
pub fn iter(&self) -> Iter<'_, T> {
Iter::new(self)
}
fn len_static(mut skew_list: &Self) -> usize {
let mut len = 0;
loop {
len += skew_list.size;
skew_list = match skew_list.tail {
Some(ref tail) => &**tail,
None => {
break len;
}
};
}
}
pub fn get_len(&self) -> usize {
Self::len_static(self)
}
}
impl<T> InnerSkewList<T>
where
T: Clone,
{
fn lookup_local_mut(
values: &mut ArrayVec<ChildNodes<T>>,
i: usize,
tree_size: usize,
size: usize,
) -> Result<&mut T, usize> {
if i >= size {
Err(i - size)
} else {
let (idx, new_i) = get_idx(i, tree_size);
let real_idx = values.len() - 1 - idx;
Ok(values[real_idx].get_mut(new_i, tree_size))
}
}
fn get_mut_static(mut skew_list: &mut Self, mut i: usize) -> Option<&mut T> {
loop {
match Self::lookup_local_mut(
&mut skew_list.values,
i,
skew_list.tree_size,
skew_list.size,
) {
Ok(value) => {
return Some(value);
}
Err(new_i) => {
i = new_i;
skew_list = match skew_list.tail.as_mut() {
Some(x) => Ref::make_mut(x),
None => {
return None;
}
};
}
};
}
}
pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
Self::get_mut_static(self, i)
}
}
impl<T> Default for InnerSkewList<T> {
fn default() -> Self {
Self::empty()
}
}
impl<T> Clone for InnerSkewList<T> {
fn clone(&self) -> Self {
InnerSkewList {
values: self.values.clone(),
tree_size: self.tree_size,
tail: self.tail.clone(),
size: self.size,
}
}
}
pub struct Iter<'a, T> {
tree_iter: subtree::Iter<'a, T>,
trees: iter::Rev<slice::Iter<'a, Subtree<T>>>,
tail: Option<&'a InnerSkewList<T>>,
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
loop {
if let Some(item) = self.tree_iter.next() {
return Some(item);
}
loop {
if let Some(next_tree) = self.trees.next() {
self.tree_iter = next_tree.iter();
break;
}
if let Some(tail) = self.tail {
self.trees = tail.values.iter().rev();
self.tail = tail.tail.as_ref().map(|x| &**x);
} else {
return None;
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
if let Some(ref tail) = self.tail {
let tail_len = tail.get_len();
(
tail_len,
tail_len.checked_add(decrement_tree_size(tail.tree_size)),
)
} else {
(0, None)
}
}
}
impl<'a, T> Iter<'a, T> {
fn new(list: &'a InnerSkewList<T>) -> Self {
Iter {
tree_iter: subtree::Iter::default(),
trees: list.values.iter().rev(),
tail: list.tail.as_ref().map(|x| &**x),
}
}
}
impl<'a, T> Default for Iter<'a, T> {
fn default() -> Self {
Iter {
tree_iter: subtree::Iter::default(),
trees: [].iter().rev(),
tail: None,
}
}
}