Passing info about parents replaced with stack-allocated buffer
This commit is contained in:
parent
104e3e4cd9
commit
f349a8751b
230
src/algo/add.rs
230
src/algo/add.rs
@ -4,10 +4,14 @@ use binary_tree_core_0::base_context::{
|
|||||||
BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure,
|
BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure,
|
||||||
BinaryTreeRootGetter,
|
BinaryTreeRootGetter,
|
||||||
};
|
};
|
||||||
use binary_tree_core_0::directed_context::{DirectedBinaryTreeChildrenGetterContext, DynamicDirectedBinaryTreeContextFromContext};
|
use binary_tree_core_0::directed_context::{
|
||||||
|
DirectedBinaryTreeChildrenGetterContext, DynamicDirectedBinaryTreeContextFromContext,
|
||||||
|
};
|
||||||
use binary_tree_core_0::relation_context::{
|
use binary_tree_core_0::relation_context::{
|
||||||
BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext,
|
BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext,
|
||||||
};
|
};
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
pub trait AddRecContext:
|
pub trait AddRecContext:
|
||||||
BinaryTreeRootGetter
|
BinaryTreeRootGetter
|
||||||
@ -19,107 +23,183 @@ pub trait AddRecContext:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Frame<NodeRef> {
|
||||||
|
node: NodeRef,
|
||||||
|
dir: BinaryTreeDirection,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Stack<T> {
|
||||||
|
start: NonNull<T>,
|
||||||
|
ptr: NonNull<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Stack<T> {
|
||||||
|
fn init<const SIZE: usize>(buffer: &mut [MaybeUninit<T>; SIZE]) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let start = NonNull::new_unchecked(
|
||||||
|
((*buffer.as_mut_ptr()).as_mut_ptr())
|
||||||
|
.offset(const { 0isize.strict_add_unsigned(SIZE) }),
|
||||||
|
);
|
||||||
|
return Self { start, ptr: start };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push(&mut self, value: T) {
|
||||||
|
unsafe {
|
||||||
|
let newPtr = self.ptr.offset(-1);
|
||||||
|
newPtr.as_ptr().write(value);
|
||||||
|
self.ptr = newPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _get<const OFFSET: usize>(&self) -> &T {
|
||||||
|
unsafe {
|
||||||
|
let loc = self
|
||||||
|
.ptr
|
||||||
|
.offset(const { 0isize.strict_add_unsigned(OFFSET) });
|
||||||
|
return loc.as_ref();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn getParent(&self) -> &T {
|
||||||
|
return self._get::<0>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getGrandParent(&self) -> &T {
|
||||||
|
return self._get::<1>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn getGrandGrandParent(&self) -> &T {
|
||||||
|
return self._get::<2>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop(&mut self) -> T {
|
||||||
|
unsafe {
|
||||||
|
let newPtr = self.ptr.offset(1);
|
||||||
|
let value = self.ptr.read();
|
||||||
|
self.ptr = newPtr;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn popDiscard(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
self.ptr = self.ptr.offset(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn replaceTop(&mut self, value: T) {
|
||||||
|
unsafe {
|
||||||
|
self.ptr.write(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _has<const OFFSET: usize>(&self) -> bool {
|
||||||
|
unsafe {
|
||||||
|
return self
|
||||||
|
.ptr
|
||||||
|
.offset(const { 0isize.strict_add_unsigned(OFFSET) })
|
||||||
|
< self.start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hasGrandParent(&self) -> bool {
|
||||||
|
return self._has::<1>();
|
||||||
|
}
|
||||||
|
fn hasGrandGrandParent(&self) -> bool {
|
||||||
|
return self._has::<2>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _getChildFrame<Ctx: AddRecContext>(
|
||||||
|
ctx: &mut Ctx,
|
||||||
|
node: Ctx::NodeRef,
|
||||||
|
stack: &mut Stack<Frame<Ctx::NodeRef>>,
|
||||||
|
) -> Option<Ctx::NodeRef> {
|
||||||
|
let dir = ctx
|
||||||
|
.determineDirection(node.clone())
|
||||||
|
.unwrap_or(BinaryTreeDirection::LEFT);
|
||||||
|
let child;
|
||||||
|
match dir {
|
||||||
|
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(node.clone()),
|
||||||
|
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(node.clone()),
|
||||||
|
}
|
||||||
|
stack.push(Frame { node, dir });
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
|
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
|
||||||
ctx.clearLeftChild(newNode.clone());
|
ctx.clearLeftChild(newNode.clone());
|
||||||
ctx.clearRightChild(newNode.clone());
|
ctx.clearRightChild(newNode.clone());
|
||||||
ctx.setColor(newNode.clone(), Color::RED);
|
ctx.setColor(newNode.clone(), Color::RED);
|
||||||
|
|
||||||
let node = ctx.getRoot();
|
let root = ctx.getRoot();
|
||||||
match node {
|
match root {
|
||||||
None => {
|
None => {
|
||||||
ctx.setColor(newNode.clone(), Color::BLACK);
|
ctx.setColor(newNode.clone(), Color::BLACK);
|
||||||
ctx.setRootRelation(newNode);
|
ctx.setRootRelation(newNode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Some(node) => {
|
Some(root) => {
|
||||||
let dir = ctx
|
let mut stack: Stack<Frame<Ctx::NodeRef>> =
|
||||||
.determineDirection(node.clone())
|
Stack::init(&mut [const { MaybeUninit::uninit() }; usize::BITS as usize]);
|
||||||
.unwrap_or(BinaryTreeDirection::LEFT);
|
|
||||||
let child;
|
let child = _getChildFrame(ctx, root.clone(), &mut stack);
|
||||||
match dir {
|
_add_recursive(ctx, &mut stack, child, newNode);
|
||||||
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(node.clone()),
|
ctx.setColor(root, Color::BLACK)
|
||||||
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(node.clone()),
|
|
||||||
}
|
|
||||||
_add_recursive(ctx, None, None, (node.clone(), dir), child, newNode);
|
|
||||||
ctx.setColor(node, Color::BLACK)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _add_recursive<Ctx: AddRecContext>(
|
fn _add_recursive<Ctx: AddRecContext>(
|
||||||
ctx: &mut Ctx,
|
ctx: &mut Ctx,
|
||||||
grandgrandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>,
|
stack: &mut Stack<Frame<Ctx::NodeRef>>,
|
||||||
grandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>,
|
nodeOrPlace: Option<Ctx::NodeRef>,
|
||||||
parent: (Ctx::NodeRef, BinaryTreeDirection),
|
|
||||||
_node: Option<Ctx::NodeRef>,
|
|
||||||
newNode: Ctx::NodeRef,
|
newNode: Ctx::NodeRef,
|
||||||
) {
|
) {
|
||||||
let node;
|
match nodeOrPlace {
|
||||||
match _node {
|
None => match stack.getParent().dir {
|
||||||
None => {
|
BinaryTreeDirection::LEFT => {
|
||||||
match parent.1 {
|
ctx.setLeftRelation(stack.getParent().node.clone(), newNode.clone())
|
||||||
BinaryTreeDirection::LEFT => ctx.setLeftRelation(parent.0.clone(), newNode.clone()),
|
|
||||||
BinaryTreeDirection::RIGHT => {
|
|
||||||
ctx.setRightRelation(parent.0.clone(), newNode.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
node = newNode;
|
BinaryTreeDirection::RIGHT => {
|
||||||
}
|
ctx.setRightRelation(stack.getParent().node.clone(), newNode.clone())
|
||||||
Some(_node) => {
|
|
||||||
node = _node;
|
|
||||||
let childDir = ctx
|
|
||||||
.determineDirection(node.clone())
|
|
||||||
.unwrap_or(BinaryTreeDirection::LEFT);
|
|
||||||
let child;
|
|
||||||
match childDir {
|
|
||||||
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(node.clone()),
|
|
||||||
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(node.clone()),
|
|
||||||
}
|
}
|
||||||
_add_recursive(
|
},
|
||||||
ctx,
|
Some(node) => {
|
||||||
grandparent.clone(),
|
let child = _getChildFrame(ctx, node, stack);
|
||||||
Some(parent.clone()),
|
_add_recursive(ctx, stack, child, newNode);
|
||||||
(node.clone(), childDir),
|
|
||||||
child,
|
|
||||||
newNode,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.getColor(parent.0.clone()) == Color::BLACK {
|
if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK {
|
||||||
return; // todo break
|
return; // todo break
|
||||||
}
|
}
|
||||||
match grandparent {
|
if !stack.hasGrandParent() {
|
||||||
None => {
|
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
|
||||||
ctx.setColor(parent.0, Color::BLACK);
|
return; // todo break
|
||||||
return; // todo break
|
}
|
||||||
|
|
||||||
|
let mut symCtx =
|
||||||
|
DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, stack.getGrandParent().dir);
|
||||||
|
let uncle = symCtx.getOppositeChild(stack.getGrandParent().node.clone());
|
||||||
|
if let Some(uncle) = uncle {
|
||||||
|
if ctx.getColor(uncle.clone()) == Color::RED {
|
||||||
|
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
|
||||||
|
ctx.setColor(uncle, Color::BLACK);
|
||||||
|
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
|
||||||
|
return; // todo current = grandparent
|
||||||
}
|
}
|
||||||
Some(grandparent) => {
|
}
|
||||||
let mut symCtx = DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, grandparent.1);
|
|
||||||
let uncle = symCtx.getOppositeChild(grandparent.0.clone());
|
|
||||||
if let Some(uncle) = uncle {
|
|
||||||
if ctx.getColor(uncle.clone()) == Color::RED {
|
|
||||||
ctx.setColor(parent.0, Color::BLACK);
|
|
||||||
ctx.setColor(uncle, Color::BLACK);
|
|
||||||
ctx.setColor(grandparent.0, Color::RED);
|
|
||||||
return; // todo current = grandparent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match grandparent.1 == parent.1 {
|
|
||||||
true => {
|
|
||||||
todo!("__rotateOpposite_Switch(grandParent)");
|
|
||||||
return; // todo continue
|
|
||||||
},
|
|
||||||
false => {
|
|
||||||
todo!("__rotateForward_Forward(parent, grandParent)");
|
|
||||||
return; // todo current = parent
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
match stack.getGrandParent().dir == stack.getParent().dir {
|
||||||
|
true => {
|
||||||
|
todo!("__rotateOpposite_Switch(grandParent)");
|
||||||
|
stack.replaceTop(stack.pop());
|
||||||
|
return; // todo continue
|
||||||
|
}
|
||||||
|
false => {
|
||||||
|
todo!("__rotateForward_Forward(parent, grandParent)");
|
||||||
|
stack.popDiscard();
|
||||||
|
return; // todo current = parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user