Passing info about parents replaced with stack-allocated buffer

This commit is contained in:
Andrew Golovashevich 2025-12-29 18:03:33 +03:00
parent 104e3e4cd9
commit f349a8751b

View File

@ -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);
struct Frame<NodeRef> {
node: NodeRef,
dir: BinaryTreeDirection,
}
let node = ctx.getRoot();
match node {
None => {
ctx.setColor(newNode.clone(), Color::BLACK);
ctx.setRootRelation(newNode);
return;
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 };
}
Some(node) => {
}
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
},
}
}
}
}