use std::ptr::NonNull;
use crate::mem::traits::LinksTree;
use crate::mem::{
split::{
generic::internal_recursion_less_base::{
InternalRecursionlessSizeBalancedTreeBase,
InternalRecursionlessSizeBalancedTreeBaseAbstract,
},
DataPart, IndexPart,
},
SplitUpdateMem,
};
use crate::{mem::SplitTree, Link};
use data::{Flow, LinkReference, LinksConstants};
use trees::{IterativeSizeBalancedTree, RecursiveSizeBalancedTree};
pub struct InternalSourcesRecursionlessTree<T: LinkReference> {
base: InternalRecursionlessSizeBalancedTreeBase<T>,
}
impl<T: LinkReference> InternalSourcesRecursionlessTree<T> {
pub fn new(
constants: LinksConstants<T>,
data: NonNull<[DataPart<T>]>,
indexes: NonNull<[IndexPart<T>]>,
) -> Self {
Self {
base: InternalRecursionlessSizeBalancedTreeBase::new(constants, data, indexes),
}
}
}
impl<T: LinkReference> RecursiveSizeBalancedTree<T> for InternalSourcesRecursionlessTree<T> {
unsafe fn get_left_reference(&self, node: T) -> *const T {
std::ptr::addr_of!(self.get_index_part(node).left_as_source)
}
unsafe fn get_right_reference(&self, node: T) -> *const T {
std::ptr::addr_of!(self.get_index_part(node).right_as_source)
}
unsafe fn get_mut_left_reference(&mut self, node: T) -> *mut T {
std::ptr::addr_of_mut!(self.get_mut_index_part(node).left_as_source)
}
unsafe fn get_mut_right_reference(&mut self, node: T) -> *mut T {
std::ptr::addr_of_mut!(self.get_mut_index_part(node).right_as_source)
}
unsafe fn get_left(&self, node: T) -> T {
self.get_index_part(node).left_as_source
}
unsafe fn get_right(&self, node: T) -> T {
self.get_index_part(node).right_as_source
}
unsafe fn get_size(&self, node: T) -> T {
self.get_index_part(node).size_as_source
}
unsafe fn set_left(&mut self, node: T, left: T) {
self.get_mut_index_part(node).left_as_source = left;
}
unsafe fn set_right(&mut self, node: T, right: T) {
self.get_mut_index_part(node).right_as_source = right;
}
unsafe fn set_size(&mut self, node: T, size: T) {
self.get_mut_index_part(node).size_as_source = size;
}
unsafe fn first_is_to_the_left_of_second(&self, first: T, second: T) -> bool {
self.get_key_part(first) < self.get_key_part(second)
}
unsafe fn first_is_to_the_right_of_second(&self, first: T, second: T) -> bool {
self.get_key_part(first) > self.get_key_part(second)
}
unsafe fn clear_node(&mut self, node: T) {
let link = self.get_mut_index_part(node);
link.left_as_source = T::from_byte(0);
link.right_as_source = T::from_byte(0);
link.size_as_source = T::from_byte(0);
}
}
impl<T: LinkReference> IterativeSizeBalancedTree<T> for InternalSourcesRecursionlessTree<T> {}
fn each_usages_core<T: LinkReference, H: FnMut(Link<T>) -> Flow + ?Sized>(
this: &InternalSourcesRecursionlessTree<T>,
base: T,
link: T,
handler: &mut H,
) -> Flow {
if link == T::from_byte(0) {
return Flow::Continue;
}
unsafe {
if each_usages_core(this, base, this.get_left_or_default(link), handler).is_break() {
return Flow::Break;
}
if handler(this.get_link_value(link)).is_break() {
return Flow::Break;
}
if each_usages_core(this, base, this.get_right_or_default(link), handler).is_break() {
return Flow::Break;
}
Flow::Continue
}
}
impl<T: LinkReference> LinksTree<T> for InternalSourcesRecursionlessTree<T> {
fn count_usages(&self, link: T) -> T {
self.count_usages_core(link)
}
fn search(&self, source: T, target: T) -> T {
self.search_core(self.get_tree_root(source), target)
}
fn each_usages<H: FnMut(Link<T>) -> Flow + ?Sized>(&self, root: T, handler: &mut H) -> Flow {
each_usages_core(self, root, self.get_tree_root(root), handler)
}
fn detach(&mut self, root: &mut T, index: T) {
unsafe { IterativeSizeBalancedTree::detach(self, root as *mut _, index) }
}
fn attach(&mut self, root: &mut T, index: T) {
unsafe { IterativeSizeBalancedTree::attach(self, root as *mut _, index) }
}
}
impl<T: LinkReference> SplitUpdateMem<T> for InternalSourcesRecursionlessTree<T> {
fn update_mem(&mut self, data: NonNull<[DataPart<T>]>, index: NonNull<[IndexPart<T>]>) {
self.base.data = data;
self.base.indexes = index;
}
}
impl<T: LinkReference> SplitTree<T> for InternalSourcesRecursionlessTree<T> {}
impl<T: LinkReference> InternalRecursionlessSizeBalancedTreeBaseAbstract<T>
for InternalSourcesRecursionlessTree<T>
{
fn get_index_part(&self, link: T) -> &IndexPart<T> {
unsafe { &self.base.indexes.as_ref()[link.as_()] }
}
fn get_mut_index_part(&mut self, link: T) -> &mut IndexPart<T> {
unsafe { &mut self.base.indexes.as_mut()[link.as_()] }
}
fn get_data_part(&self, link: T) -> &DataPart<T> {
unsafe { &self.base.data.as_ref()[link.as_()] }
}
fn get_mut_data_part(&mut self, link: T) -> &mut DataPart<T> {
unsafe { &mut self.base.data.as_mut()[link.as_()] }
}
fn get_tree_root(&self, link: T) -> T {
self.get_index_part(link).root_as_source
}
fn get_base_part(&self, link: T) -> T {
self.get_data_part(link).source
}
fn get_key_part(&self, link: T) -> T {
self.get_data_part(link).target
}
}