Passing info about parents replaced with stack-allocated buffer
This commit is contained in:
parent
104e3e4cd9
commit
f349a8751b
206
src/algo/add.rs
206
src/algo/add.rs
@ -4,10 +4,14 @@ use binary_tree_core_0::base_context::{
|
||||
BinaryTreeChildrenGetterContext, BinaryTreeDirection, BinaryTreeDirectionDispatcherClojure,
|
||||
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::{
|
||||
BinaryTreeRelationSetterContext, BinaryTreeRootRelationSetterContext,
|
||||
};
|
||||
use std::mem::MaybeUninit;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
pub trait AddRecContext:
|
||||
BinaryTreeRootGetter
|
||||
@ -19,19 +23,97 @@ pub trait AddRecContext:
|
||||
{
|
||||
}
|
||||
|
||||
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
|
||||
ctx.clearLeftChild(newNode.clone());
|
||||
ctx.clearRightChild(newNode.clone());
|
||||
ctx.setColor(newNode.clone(), Color::RED);
|
||||
|
||||
let node = ctx.getRoot();
|
||||
match node {
|
||||
None => {
|
||||
ctx.setColor(newNode.clone(), Color::BLACK);
|
||||
ctx.setRootRelation(newNode);
|
||||
return;
|
||||
struct Frame<NodeRef> {
|
||||
node: NodeRef,
|
||||
dir: BinaryTreeDirection,
|
||||
}
|
||||
Some(node) => {
|
||||
|
||||
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);
|
||||
@ -40,86 +122,84 @@ pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
|
||||
BinaryTreeDirection::LEFT => child = ctx.getLeftChild(node.clone()),
|
||||
BinaryTreeDirection::RIGHT => child = ctx.getRightChild(node.clone()),
|
||||
}
|
||||
_add_recursive(ctx, None, None, (node.clone(), dir), child, newNode);
|
||||
ctx.setColor(node, Color::BLACK)
|
||||
stack.push(Frame { node, dir });
|
||||
return child;
|
||||
}
|
||||
|
||||
pub fn add_recursive<Ctx: AddRecContext>(ctx: &mut Ctx, newNode: Ctx::NodeRef) {
|
||||
ctx.clearLeftChild(newNode.clone());
|
||||
ctx.clearRightChild(newNode.clone());
|
||||
ctx.setColor(newNode.clone(), Color::RED);
|
||||
|
||||
let root = ctx.getRoot();
|
||||
match root {
|
||||
None => {
|
||||
ctx.setColor(newNode.clone(), Color::BLACK);
|
||||
ctx.setRootRelation(newNode);
|
||||
return;
|
||||
}
|
||||
Some(root) => {
|
||||
let mut stack: Stack<Frame<Ctx::NodeRef>> =
|
||||
Stack::init(&mut [const { MaybeUninit::uninit() }; usize::BITS as usize]);
|
||||
|
||||
let child = _getChildFrame(ctx, root.clone(), &mut stack);
|
||||
_add_recursive(ctx, &mut stack, child, newNode);
|
||||
ctx.setColor(root, Color::BLACK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn _add_recursive<Ctx: AddRecContext>(
|
||||
ctx: &mut Ctx,
|
||||
grandgrandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>,
|
||||
grandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>,
|
||||
parent: (Ctx::NodeRef, BinaryTreeDirection),
|
||||
_node: Option<Ctx::NodeRef>,
|
||||
stack: &mut Stack<Frame<Ctx::NodeRef>>,
|
||||
nodeOrPlace: Option<Ctx::NodeRef>,
|
||||
newNode: Ctx::NodeRef,
|
||||
) {
|
||||
let node;
|
||||
match _node {
|
||||
None => {
|
||||
match parent.1 {
|
||||
BinaryTreeDirection::LEFT => ctx.setLeftRelation(parent.0.clone(), newNode.clone()),
|
||||
match nodeOrPlace {
|
||||
None => match stack.getParent().dir {
|
||||
BinaryTreeDirection::LEFT => {
|
||||
ctx.setLeftRelation(stack.getParent().node.clone(), newNode.clone())
|
||||
}
|
||||
BinaryTreeDirection::RIGHT => {
|
||||
ctx.setRightRelation(parent.0.clone(), newNode.clone())
|
||||
ctx.setRightRelation(stack.getParent().node.clone(), newNode.clone())
|
||||
}
|
||||
}
|
||||
node = newNode;
|
||||
}
|
||||
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,
|
||||
grandparent.clone(),
|
||||
Some(parent.clone()),
|
||||
(node.clone(), childDir),
|
||||
child,
|
||||
newNode,
|
||||
);
|
||||
},
|
||||
Some(node) => {
|
||||
let child = _getChildFrame(ctx, node, stack);
|
||||
_add_recursive(ctx, stack, child, newNode);
|
||||
}
|
||||
}
|
||||
|
||||
if ctx.getColor(parent.0.clone()) == Color::BLACK {
|
||||
if ctx.getColor(stack.getParent().node.clone()) == Color::BLACK {
|
||||
return; // todo break
|
||||
}
|
||||
match grandparent {
|
||||
None => {
|
||||
ctx.setColor(parent.0, Color::BLACK);
|
||||
if !stack.hasGrandParent() {
|
||||
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
|
||||
return; // todo break
|
||||
}
|
||||
Some(grandparent) => {
|
||||
let mut symCtx = DynamicDirectedBinaryTreeContextFromContext::wrap_mut(ctx, grandparent.1);
|
||||
let uncle = symCtx.getOppositeChild(grandparent.0.clone());
|
||||
|
||||
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(parent.0, Color::BLACK);
|
||||
ctx.setColor(stack.getParent().node.clone(), Color::BLACK);
|
||||
ctx.setColor(uncle, Color::BLACK);
|
||||
ctx.setColor(grandparent.0, Color::RED);
|
||||
ctx.setColor(stack.getGrandParent().node.clone(), Color::RED);
|
||||
return; // todo current = grandparent
|
||||
}
|
||||
}
|
||||
|
||||
match grandparent.1 == parent.1 {
|
||||
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