From f349a8751b48c6f0d5384c7694703a20020a39a1 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Mon, 29 Dec 2025 18:03:33 +0300 Subject: [PATCH] Passing info about parents replaced with stack-allocated buffer --- src/algo/add.rs | 230 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 155 insertions(+), 75 deletions(-) diff --git a/src/algo/add.rs b/src/algo/add.rs index bed5850..aac993d 100644 --- a/src/algo/add.rs +++ b/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,107 +23,183 @@ pub trait AddRecContext: { } +struct Frame { + node: NodeRef, + dir: BinaryTreeDirection, +} + +struct Stack { + start: NonNull, + ptr: NonNull, +} + +impl Stack { + fn init(buffer: &mut [MaybeUninit; 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(&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(&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: &mut Ctx, + node: Ctx::NodeRef, + stack: &mut Stack>, +) -> Option { + 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: &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 { + let root = ctx.getRoot(); + match root { None => { ctx.setColor(newNode.clone(), Color::BLACK); ctx.setRootRelation(newNode); return; } - Some(node) => { - 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()), - } - _add_recursive(ctx, None, None, (node.clone(), dir), child, newNode); - ctx.setColor(node, Color::BLACK) + Some(root) => { + let mut stack: Stack> = + 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: &mut Ctx, - grandgrandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>, - grandparent: Option<(Ctx::NodeRef, BinaryTreeDirection)>, - parent: (Ctx::NodeRef, BinaryTreeDirection), - _node: Option, + stack: &mut Stack>, + nodeOrPlace: Option, newNode: Ctx::NodeRef, ) { - let node; - match _node { - None => { - match parent.1 { - BinaryTreeDirection::LEFT => ctx.setLeftRelation(parent.0.clone(), newNode.clone()), - BinaryTreeDirection::RIGHT => { - ctx.setRightRelation(parent.0.clone(), newNode.clone()) - } + match nodeOrPlace { + None => match stack.getParent().dir { + BinaryTreeDirection::LEFT => { + ctx.setLeftRelation(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()), + BinaryTreeDirection::RIGHT => { + ctx.setRightRelation(stack.getParent().node.clone(), newNode.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); - return; // todo break + if !stack.hasGrandParent() { + ctx.setColor(stack.getParent().node.clone(), Color::BLACK); + 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 } } } - -