From bd89611f70d5c70f95157a92f4514ebec3f768f9 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Wed, 24 Dec 2025 12:48:32 +0300 Subject: [PATCH] Splited context to multiple traits and extracted directed contexts as independent --- src/context.rs | 49 +++++- src/directed/context.rs | 40 +++++ src/directed/impls/dynamic_wrapper.rs | 161 +++++++++++++++++++ src/directed/impls/fixed_wrapper.rs | 221 ++++++++++++++++++++++++++ src/directed/impls/mod.rs | 2 + src/directed/mod.rs | 2 + src/direction.rs | 4 + src/lib.rs | 7 +- src/swap/neighbors/context.rs | 25 --- 9 files changed, 478 insertions(+), 33 deletions(-) create mode 100644 src/directed/context.rs create mode 100644 src/directed/impls/dynamic_wrapper.rs create mode 100644 src/directed/impls/fixed_wrapper.rs create mode 100644 src/directed/impls/mod.rs create mode 100644 src/directed/mod.rs create mode 100644 src/direction.rs delete mode 100644 src/swap/neighbors/context.rs diff --git a/src/context.rs b/src/context.rs index 0e9c3c0..3c71e5b 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,11 +1,46 @@ -pub unsafe trait BinTreeContext { - type NodeRef: Sized; +pub trait NodeRefContainer { + type NodeRef: Sized + Copy; +} - fn getParent(&self, node: Self::NodeRef) -> Option; +pub trait BinaryTreeDownWalker: NodeRefContainer { fn getLeftChild(&self, node: Self::NodeRef) -> Option; fn getRightChild(&self, node: Self::NodeRef) -> Option; - - fn setParent(&mut self, node: Self::NodeRef, newParent: Option); - fn setLeftChild(&mut self, node: Self::NodeRef, newChild: Option); - fn setRightChild(&mut self, node: Self::NodeRef, newChild: Option); +} + +pub trait BinaryTreeUpWalker: NodeRefContainer { + fn getParent(&self, node: Self::NodeRef) -> Option; +} + +pub unsafe trait BinaryTreeDownBuilder: NodeRefContainer { + fn xSetLeftChild(&mut self, node: Self::NodeRef, newChild: Option) { + match newChild { + None => self.clearLeftChild(node), + Some(nn) => self.setLeftChild(node, nn), + } + } + fn xSetRightChild(&mut self, node: Self::NodeRef, newChild: Option) { + match newChild { + None => self.clearLeftChild(node), + Some(nn) => self.setRightChild(node, nn), + } + } + + fn setLeftChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef); + fn setRightChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef); + + fn clearLeftChild(&mut self, node: Self::NodeRef); + fn clearRightChild(&mut self, node: Self::NodeRef); +} + +pub unsafe trait BinaryTreeBuilder: BinaryTreeDownBuilder { + fn xSetParent(&mut self, node: Self::NodeRef, newParent: Option) { + match newParent { + None => self.clearParent(node), + Some(nn) => self.setParent(node, nn), + } + } + + fn setParent(&mut self, node: Self::NodeRef, newParent: Self::NodeRef); + + fn clearParent(&mut self, node: Self::NodeRef); } diff --git a/src/directed/context.rs b/src/directed/context.rs new file mode 100644 index 0000000..430892d --- /dev/null +++ b/src/directed/context.rs @@ -0,0 +1,40 @@ +use crate::NodeRefContainer; + +pub trait DirectedBinaryTreeDownWalker: NodeRefContainer { + fn getForwardChild(&self, node: Self::NodeRef) -> Option; + fn getOppositeChild(&self, node: Self::NodeRef) -> Option; +} + +pub unsafe trait DirectedBinaryTreeDownBuilder: NodeRefContainer { + fn xSetForwardChild(&mut self, node: Self::NodeRef, newChild: Option) { + match newChild { + None => self.clearForwardChild(node), + Some(nn) => self.setForwardChild(node, nn), + } + } + fn xSetOppositeChild(&mut self, node: Self::NodeRef, newChild: Option) { + match newChild { + None => self.clearForwardChild(node), + Some(nn) => self.setOppositeChild(node, nn), + } + } + + fn setForwardChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef); + fn setOppositeChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef); + + fn clearForwardChild(&mut self, node: Self::NodeRef); + fn clearOppositeChild(&mut self, node: Self::NodeRef); +} + +pub unsafe trait DirectedBinaryTreeBuilder: DirectedBinaryTreeDownBuilder { + fn xSetParent(&mut self, node: Self::NodeRef, newParent: Option) { + match newParent { + None => self.clearParent(node), + Some(nn) => self.setParent(node, nn), + } + } + + fn setParent(&mut self, node: Self::NodeRef, newParent: Self::NodeRef); + + fn clearParent(&mut self, node: Self::NodeRef); +} diff --git a/src/directed/impls/dynamic_wrapper.rs b/src/directed/impls/dynamic_wrapper.rs new file mode 100644 index 0000000..b8a45b1 --- /dev/null +++ b/src/directed/impls/dynamic_wrapper.rs @@ -0,0 +1,161 @@ +use crate::NodeRefContainer; +use crate::context::{ + BinaryTreeBuilder, BinaryTreeDownBuilder, BinaryTreeDownWalker, BinaryTreeUpWalker, +}; +use crate::direction::BinaryTreeDirection; +use crate::directed::context::{ + DirectedBinaryTreeBuilder, DirectedBinaryTreeDownBuilder, DirectedBinaryTreeDownWalker, +}; + +pub struct DynamicDirectedBinaryTreeWalker<'ctx, Ctx: NodeRefContainer> { + ctx: &'ctx Ctx, + dir: BinaryTreeDirection, +} + +pub struct DynamicDirectedBinaryTreeEditor<'ctx, Ctx: NodeRefContainer> { + ctx: &'ctx mut Ctx, + dir: BinaryTreeDirection, +} + +impl<'ctx, Ctx: NodeRefContainer> DynamicDirectedBinaryTreeWalker<'ctx, Ctx> { + pub fn wrap(ctx: &'ctx Ctx, initialDirection: BinaryTreeDirection) -> Self { + return Self { + ctx, + dir: initialDirection, + }; + } + + pub fn changeDirection(&mut self, newDirection: BinaryTreeDirection) { + self.dir = newDirection + } +} +impl<'ctx, Ctx: NodeRefContainer> DynamicDirectedBinaryTreeEditor<'ctx, Ctx> { + pub fn wrap(ctx: &'ctx mut Ctx, initialDirection: BinaryTreeDirection) -> Self { + return Self { + ctx, + dir: initialDirection, + }; + } + + pub fn changeDirection(&mut self, newDirection: BinaryTreeDirection) { + self.dir = newDirection + } +} + +impl NodeRefContainer for DynamicDirectedBinaryTreeWalker<'_, Ctx> { + type NodeRef = Ctx::NodeRef; +} + +impl NodeRefContainer for DynamicDirectedBinaryTreeEditor<'_, Ctx> { + type NodeRef = Ctx::NodeRef; +} + +impl BinaryTreeUpWalker for DynamicDirectedBinaryTreeWalker<'_, Ctx> { + fn getParent(&self, node: Self::NodeRef) -> Option { + return self.ctx.getParent(node); + } +} + +impl BinaryTreeUpWalker for DynamicDirectedBinaryTreeEditor<'_, Ctx> { + fn getParent(&self, node: Self::NodeRef) -> Option { + return self.ctx.getParent(node); + } +} + +impl DirectedBinaryTreeDownWalker + for DynamicDirectedBinaryTreeWalker<'_, Ctx> +{ + fn getForwardChild(&self, node: Self::NodeRef) -> Option { + match self.dir { + BinaryTreeDirection::LEFT => return self.ctx.getLeftChild(node), + BinaryTreeDirection::RIGHT => return self.ctx.getRightChild(node), + } + } + + fn getOppositeChild(&self, node: Self::NodeRef) -> Option { + match self.dir { + BinaryTreeDirection::LEFT => return self.ctx.getRightChild(node), + BinaryTreeDirection::RIGHT => return self.ctx.getLeftChild(node), + } + } +} + +impl DirectedBinaryTreeDownWalker + for DynamicDirectedBinaryTreeEditor<'_, Ctx> +{ + fn getForwardChild(&self, node: Self::NodeRef) -> Option { + match self.dir { + BinaryTreeDirection::LEFT => return self.ctx.getLeftChild(node), + BinaryTreeDirection::RIGHT => return self.ctx.getRightChild(node), + } + } + + fn getOppositeChild(&self, node: Self::NodeRef) -> Option { + match self.dir { + BinaryTreeDirection::LEFT => return self.ctx.getRightChild(node), + BinaryTreeDirection::RIGHT => return self.ctx.getLeftChild(node), + } + } +} + +unsafe impl DirectedBinaryTreeDownBuilder + for DynamicDirectedBinaryTreeEditor<'_, Ctx> +{ + fn xSetForwardChild(&mut self, node: Self::NodeRef, newChild: Option) { + match self.dir { + BinaryTreeDirection::LEFT => self.ctx.xSetLeftChild(node, newChild), + BinaryTreeDirection::RIGHT => self.ctx.xSetRightChild(node, newChild), + } + } + + fn xSetOppositeChild(&mut self, node: Self::NodeRef, newChild: Option) { + match self.dir { + BinaryTreeDirection::LEFT => self.ctx.xSetRightChild(node, newChild), + BinaryTreeDirection::RIGHT => self.ctx.xSetLeftChild(node, newChild), + } + } + + fn setForwardChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { + match self.dir { + BinaryTreeDirection::LEFT => self.ctx.setLeftChild(node, newChild), + BinaryTreeDirection::RIGHT => self.ctx.setRightChild(node, newChild), + } + } + + fn setOppositeChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { + match self.dir { + BinaryTreeDirection::LEFT => self.ctx.setRightChild(node, newChild), + BinaryTreeDirection::RIGHT => self.ctx.setLeftChild(node, newChild), + } + } + + fn clearForwardChild(&mut self, node: Self::NodeRef) { + match self.dir { + BinaryTreeDirection::LEFT => self.ctx.clearLeftChild(node), + BinaryTreeDirection::RIGHT => self.ctx.clearRightChild(node), + } + } + + fn clearOppositeChild(&mut self, node: Self::NodeRef) { + match self.dir { + BinaryTreeDirection::LEFT => self.ctx.clearRightChild(node), + BinaryTreeDirection::RIGHT => self.ctx.clearLeftChild(node), + } + } +} + +unsafe impl DirectedBinaryTreeBuilder + for DynamicDirectedBinaryTreeEditor<'_, Ctx> +{ + fn xSetParent(&mut self, node: Self::NodeRef, newParent: Option) { + self.ctx.xSetParent(node, newParent); + } + + fn setParent(&mut self, node: Self::NodeRef, newParent: Self::NodeRef) { + self.ctx.setParent(node, newParent); + } + + fn clearParent(&mut self, node: Self::NodeRef) { + self.ctx.clearParent(node) + } +} diff --git a/src/directed/impls/fixed_wrapper.rs b/src/directed/impls/fixed_wrapper.rs new file mode 100644 index 0000000..e8c01f5 --- /dev/null +++ b/src/directed/impls/fixed_wrapper.rs @@ -0,0 +1,221 @@ +use crate::NodeRefContainer; +use crate::context::{ + BinaryTreeBuilder, BinaryTreeDownBuilder, BinaryTreeDownWalker, BinaryTreeUpWalker, +}; +use crate::directed::context::{ + DirectedBinaryTreeBuilder, DirectedBinaryTreeDownBuilder, DirectedBinaryTreeDownWalker, +}; + +pub struct LeftDirectedBinaryTreeWalker<'ctx, Ctx: NodeRefContainer> { + ctx: &'ctx Ctx, +} + +pub struct LeftDirectedBinaryTreeEditor<'ctx, Ctx: NodeRefContainer> { + ctx: &'ctx mut Ctx, +} + +pub struct RightDirectedBinaryTreeWalker<'ctx, Ctx: NodeRefContainer> { + ctx: &'ctx Ctx, +} + +pub struct RightDirectedBinaryTreeEditor<'ctx, Ctx: NodeRefContainer> { + ctx: &'ctx mut Ctx, +} + +impl<'ctx, Ctx: NodeRefContainer> LeftDirectedBinaryTreeWalker<'ctx, Ctx> { + pub fn wrap(ctx: &'ctx Ctx) -> Self { + return Self { ctx }; + } +} +impl<'ctx, Ctx: NodeRefContainer> LeftDirectedBinaryTreeEditor<'ctx, Ctx> { + pub fn wrap(ctx: &'ctx mut Ctx) -> Self { + return Self { ctx }; + } +} + +impl<'ctx, Ctx: NodeRefContainer> RightDirectedBinaryTreeWalker<'ctx, Ctx> { + pub fn wrap(ctx: &'ctx Ctx) -> Self { + return Self { ctx }; + } +} + +impl<'ctx, Ctx: NodeRefContainer> RightDirectedBinaryTreeEditor<'ctx, Ctx> { + pub fn wrap(ctx: &'ctx mut Ctx) -> Self { + return Self { ctx }; + } +} + +impl NodeRefContainer for LeftDirectedBinaryTreeWalker<'_, Ctx> { + type NodeRef = Ctx::NodeRef; +} + +impl NodeRefContainer for LeftDirectedBinaryTreeEditor<'_, Ctx> { + type NodeRef = Ctx::NodeRef; +} + +impl NodeRefContainer for RightDirectedBinaryTreeWalker<'_, Ctx> { + type NodeRef = Ctx::NodeRef; +} + +impl NodeRefContainer for RightDirectedBinaryTreeEditor<'_, Ctx> { + type NodeRef = Ctx::NodeRef; +} + +impl BinaryTreeUpWalker for LeftDirectedBinaryTreeWalker<'_, Ctx> { + fn getParent(&self, node: Self::NodeRef) -> Option { + return self.ctx.getParent(node); + } +} + +impl BinaryTreeUpWalker for LeftDirectedBinaryTreeEditor<'_, Ctx> { + fn getParent(&self, node: Self::NodeRef) -> Option { + return self.ctx.getParent(node); + } +} + +impl BinaryTreeUpWalker for RightDirectedBinaryTreeWalker<'_, Ctx> { + fn getParent(&self, node: Self::NodeRef) -> Option { + return self.ctx.getParent(node); + } +} + +impl BinaryTreeUpWalker for RightDirectedBinaryTreeEditor<'_, Ctx> { + fn getParent(&self, node: Self::NodeRef) -> Option { + return self.ctx.getParent(node); + } +} + +impl DirectedBinaryTreeDownWalker + for LeftDirectedBinaryTreeWalker<'_, Ctx> +{ + fn getForwardChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getLeftChild(node); + } + + fn getOppositeChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getRightChild(node); + } +} + +impl DirectedBinaryTreeDownWalker + for LeftDirectedBinaryTreeEditor<'_, Ctx> +{ + fn getForwardChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getLeftChild(node); + } + + fn getOppositeChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getRightChild(node); + } +} + +impl DirectedBinaryTreeDownWalker + for RightDirectedBinaryTreeWalker<'_, Ctx> +{ + fn getForwardChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getRightChild(node); + } + + fn getOppositeChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getLeftChild(node); + } +} + +impl DirectedBinaryTreeDownWalker + for RightDirectedBinaryTreeEditor<'_, Ctx> +{ + fn getForwardChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getRightChild(node); + } + + fn getOppositeChild(&self, node: Self::NodeRef) -> Option { + return self.ctx.getLeftChild(node); + } +} + +unsafe impl DirectedBinaryTreeDownBuilder + for LeftDirectedBinaryTreeEditor<'_, Ctx> +{ + fn xSetForwardChild(&mut self, node: Self::NodeRef, newChild: Option) { + self.ctx.xSetLeftChild(node, newChild) + } + + fn xSetOppositeChild(&mut self, node: Self::NodeRef, newChild: Option) { + self.ctx.xSetRightChild(node, newChild) + } + + fn setForwardChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { + self.ctx.setLeftChild(node, newChild) + } + + fn setOppositeChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { + self.ctx.setRightChild(node, newChild) + } + + fn clearForwardChild(&mut self, node: Self::NodeRef) { + self.ctx.clearLeftChild(node) + } + + fn clearOppositeChild(&mut self, node: Self::NodeRef) { + self.ctx.clearRightChild(node) + } +} + +unsafe impl DirectedBinaryTreeDownBuilder + for RightDirectedBinaryTreeEditor<'_, Ctx> +{ + fn xSetForwardChild(&mut self, node: Self::NodeRef, newChild: Option) { + self.ctx.xSetRightChild(node, newChild) + } + + fn xSetOppositeChild(&mut self, node: Self::NodeRef, newChild: Option) { + self.ctx.xSetLeftChild(node, newChild) + } + + fn setForwardChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { + self.ctx.setRightChild(node, newChild) + } + + fn setOppositeChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { + self.ctx.setLeftChild(node, newChild) + } + + fn clearForwardChild(&mut self, node: Self::NodeRef) { + self.ctx.clearRightChild(node) + } + + fn clearOppositeChild(&mut self, node: Self::NodeRef) { + self.ctx.clearLeftChild(node) + } +} +unsafe impl DirectedBinaryTreeBuilder + for LeftDirectedBinaryTreeEditor<'_, Ctx> +{ + fn xSetParent(&mut self, node: Self::NodeRef, newParent: Option) { + self.ctx.xSetParent(node, newParent); + } + + fn setParent(&mut self, node: Self::NodeRef, newParent: Self::NodeRef) { + self.ctx.setParent(node, newParent); + } + + fn clearParent(&mut self, node: Self::NodeRef) { + self.ctx.clearParent(node) + } +} + +unsafe impl DirectedBinaryTreeBuilder + for RightDirectedBinaryTreeEditor<'_, Ctx> +{ + fn xSetParent(&mut self, node: Self::NodeRef, newParent: Option) { + self.ctx.xSetParent(node, newParent); + } + + fn setParent(&mut self, node: Self::NodeRef, newParent: Self::NodeRef) { + self.ctx.setParent(node, newParent); + } + + fn clearParent(&mut self, node: Self::NodeRef) { + self.ctx.clearParent(node) + } +} diff --git a/src/directed/impls/mod.rs b/src/directed/impls/mod.rs new file mode 100644 index 0000000..99757bf --- /dev/null +++ b/src/directed/impls/mod.rs @@ -0,0 +1,2 @@ +mod fixed_wrapper; +mod dynamic_wrapper; \ No newline at end of file diff --git a/src/directed/mod.rs b/src/directed/mod.rs new file mode 100644 index 0000000..1b23bdd --- /dev/null +++ b/src/directed/mod.rs @@ -0,0 +1,2 @@ +mod context; +mod impls; \ No newline at end of file diff --git a/src/direction.rs b/src/direction.rs new file mode 100644 index 0000000..7963a57 --- /dev/null +++ b/src/direction.rs @@ -0,0 +1,4 @@ +pub enum BinaryTreeDirection { + LEFT, + RIGHT, +} diff --git a/src/lib.rs b/src/lib.rs index 7c3d45b..12ed672 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,7 @@ mod context; -mod swap; \ No newline at end of file +mod swap; +mod directed; +mod direction; + +pub use context::NodeRefContainer; +pub use direction::BinaryTreeDirection; \ No newline at end of file diff --git a/src/swap/neighbors/context.rs b/src/swap/neighbors/context.rs deleted file mode 100644 index 84dcefd..0000000 --- a/src/swap/neighbors/context.rs +++ /dev/null @@ -1,25 +0,0 @@ -pub trait OrientedNeighborSwapContext { - type NodeRef: Sized + Copy; - - fn getParent(&self, node: Self::NodeRef) -> Option; - fn getForwardChild(&self, node: Self::NodeRef) -> Option; - fn getOppositeChild(&self, node: Self::NodeRef) -> Option; - - fn setParent(&mut self, node: Self::NodeRef, newParent: Option); - fn setForwardChild(&mut self, node: Self::NodeRef, newChild: Option); - fn setOppositeChild(&mut self, node: Self::NodeRef, newChild: Option); - - fn setGrandparentToParent(&mut self, newParent: Self::NodeRef); -} - -pub trait NeighbourSwapSupport { - fn leftChild_unknownParent(&self) -> impl OrientedNeighborSwapContext; - fn leftChild_root(&self) -> impl OrientedNeighborSwapContext; - fn leftChild_grandparentToLeft(&self) -> impl OrientedNeighborSwapContext; - fn leftChild_grandparentToRight(&self) -> impl OrientedNeighborSwapContext; - - fn rightChild_unknownParent(&self) -> impl OrientedNeighborSwapContext; - fn rightChild_root(&self) -> impl OrientedNeighborSwapContext; - fn rightChild_grandparentToLeft(&self) -> impl OrientedNeighborSwapContext; - fn rightChild_grandparentToRight(&self) -> impl OrientedNeighborSwapContext; -} \ No newline at end of file