From 6b04eec9ae6ee75c3f71b992e87aef8071079bab Mon Sep 17 00:00:00 2001 From: timofey Date: Fri, 16 Jun 2023 06:23:03 +0000 Subject: [PATCH] reduce `Rc` usage with `binary` --- src/flow/binary.rs | 34 +++++++---------- src/flow/binary/avl.rs | 29 +++++---------- src/rstd/collections/avl.rs | 2 +- src/rstd/collections/avl/binary.rs | 4 +- src/rstd/collections/avl/bounds.rs | 58 +++++++++++------------------ src/rstd/collections/avl/context.rs | 20 +++++----- 6 files changed, 57 insertions(+), 90 deletions(-) diff --git a/src/flow/binary.rs b/src/flow/binary.rs index ec6a11f..7ce3ac5 100644 --- a/src/flow/binary.rs +++ b/src/flow/binary.rs @@ -1,16 +1,12 @@ mod avl; -use std::rc::Rc; - use crate::flow::comparator::*; use crate::func::{context::*, *}; -pub type KeyRc<'a, BT> = Rc<>::Key>; - pub type Split<'a, BT> = ( >::Tree, >::Tree, - KeyRc<'a, BT>, + >::Key, ); pub type KeySplit<'a, BT> = (>::Tree, >::Tree); @@ -20,7 +16,7 @@ pub trait BinaryTrees<'a>: FunctorContext<'a, T = Self::_Tm> + Clone { type Node: 'a; type Reference: 'a; type Tree: 'a; - type Key: 'a; + type Key: 'a + Clone; type Comparator: Comparator; type _Tm: Monad<'a>; @@ -43,14 +39,14 @@ pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> { fn join_key( self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node>; fn join_key_tree( self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Tree> { self.clone().tree_bind(self.join_key(tl, key, tr)) @@ -82,13 +78,13 @@ pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> { fn split_key_empty( &self, tree: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, ) -> BTWrap<'a, Self, KeySplit<'a, Self>>; fn split_key_node( self, node: Self::Node, - key: KeyRc<'a, Self>, + key: Self::Key, ) -> BTWrap<'a, Self, KeySplit<'a, Self>> { let (tl, tr, k) = self.split(&node); match self.comparator().pick_smaller(&key, &k) { @@ -102,11 +98,7 @@ pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> { } } - fn split_key( - self, - tree: Self::Tree, - key: KeyRc<'a, Self>, - ) -> BTWrap<'a, Self, KeySplit<'a, Self>> { + fn split_key(self, tree: Self::Tree, key: Self::Key) -> BTWrap<'a, Self, KeySplit<'a, Self>> { match self.refer(&tree) { Some(reference) => Self::bind(self.resolve(&reference), |node| { self.split_key_node(node, key) @@ -115,17 +107,17 @@ pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> { } } - fn add(self, tree: Self::Tree, key: KeyRc<'a, Self>) -> BTWrap<'a, Self, Self::Node> { + fn add(self, tree: Self::Tree, key: Self::Key) -> BTWrap<'a, Self, Self::Node> { Self::bind(self.clone().split_key(tree, key.clone()), |(tl, tr)| { self.join_key(tl, key, tr) }) } - fn add_tree(self, tree: Self::Tree, key: KeyRc<'a, Self>) -> BTWrap<'a, Self, Self::Tree> { + fn add_tree(self, tree: Self::Tree, key: Self::Key) -> BTWrap<'a, Self, Self::Tree> { self.clone().tree_bind(self.add(tree, key)) } - fn remove(self, tree: Self::Tree, key: KeyRc<'a, Self>) -> BTWrap<'a, Self, Self::Tree> { + fn remove(self, tree: Self::Tree, key: Self::Key) -> BTWrap<'a, Self, Self::Tree> { Self::bind(self.clone().split_key(tree, key.clone()), |(tl, tr)| { self.join(tl, tr) }) @@ -147,14 +139,14 @@ pub trait BinaryTreesAvl<'a>: BinaryTrees<'a> { fn join_key_unbalanced( &self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node>; fn join_key_balanced_tree( &self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Tree> { self.clone() @@ -164,7 +156,7 @@ pub trait BinaryTreesAvl<'a>: BinaryTrees<'a> { fn join_key_balanced( self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node> { let (hl, hr) = (self.height(&tl), self.height(&tr)); diff --git a/src/flow/binary/avl.rs b/src/flow/binary/avl.rs index 1235f73..73b94b2 100644 --- a/src/flow/binary/avl.rs +++ b/src/flow/binary/avl.rs @@ -4,20 +4,11 @@ use crate::flow::comparator::*; use super::*; +#[derive(Clone)] struct AvlN { l: AvlT, r: AvlT, - key: Rc, -} - -impl Clone for AvlN { - fn clone(&self) -> Self { - Self { - l: self.l.clone(), - r: self.r.clone(), - key: self.key.clone(), - } - } + key: A, } impl Display for AvlN { @@ -112,7 +103,7 @@ impl<'a, A: 'a> FunctorContext<'a> for AvlTs { type T = instances::solo::SoloInstance; } -impl<'a, A: 'a + PartialOrd> BinaryTrees<'a> for AvlTs { +impl<'a, A: 'a + PartialOrd + Clone> BinaryTrees<'a> for AvlTs { type Node = AvlN; type Reference = AvlR; @@ -155,7 +146,7 @@ impl<'a, A: 'a + PartialOrd> BinaryTrees<'a> for AvlTs { } } -impl<'a, A: 'a + PartialOrd> BinaryTreesMutable<'a> for AvlTs { +impl<'a, A: 'a + PartialOrd + Clone> BinaryTreesMutable<'a> for AvlTs { fn empty(&self) -> Self::Tree { AvlT { reference: None, @@ -166,7 +157,7 @@ impl<'a, A: 'a + PartialOrd> BinaryTreesMutable<'a> for AvlTs { fn join_key( self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node> { self.join_key_balanced(tl, key, tr) @@ -175,13 +166,13 @@ impl<'a, A: 'a + PartialOrd> BinaryTreesMutable<'a> for AvlTs { fn split_key_empty( &self, _tree: Self::Tree, - _key: KeyRc<'a, Self>, + _key: Self::Key, ) -> BTWrap<'a, Self, KeySplit<'a, Self>> { (self.empty(), self.empty()) } } -impl<'a, A: 'a + PartialOrd> BinaryTreesAvl<'a> for AvlTs { +impl<'a, A: 'a + PartialOrd + Clone> BinaryTreesAvl<'a> for AvlTs { fn height(&self, tree: &Self::Tree) -> u64 { tree.height } @@ -193,7 +184,7 @@ impl<'a, A: 'a + PartialOrd> BinaryTreesAvl<'a> for AvlTs { fn join_key_unbalanced( &self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node> { AvlN { l: tl, r: tr, key } @@ -211,14 +202,14 @@ mod tests { for i in [ 8, 3, 10, 17, 0, 13, 6, 1, 11, 5, 4, 7, 18, 14, 15, 9, 2, 19, 16, 12, ] { - tree = trees.clone().add_tree(tree, i.into()); + tree = trees.clone().add_tree(tree, i); assert!(tree.balanced()); // println!("{} {}", tree.height, tree); } for i in [ 2, 9, 4, 7, 8, 10, 17, 1, 13, 15, 18, 12, 5, 0, 3, 6, 16, 19, 14, 11, ] { - tree = trees.clone().remove(tree, i.into()); + tree = trees.clone().remove(tree, i); assert!(tree.balanced()); // println!("{} {}", tree.height, tree); } diff --git a/src/rstd/collections/avl.rs b/src/rstd/collections/avl.rs index 59990b3..d51a3e2 100644 --- a/src/rstd/collections/avl.rs +++ b/src/rstd/collections/avl.rs @@ -65,7 +65,7 @@ impl Error for AvlError {} pub struct AvlNode<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { l: AvlTree<'a, Ctx, A>, r: AvlTree<'a, Ctx, A>, - key: Rc, + key: A, } pub struct AvlTree<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { diff --git a/src/rstd/collections/avl/binary.rs b/src/rstd/collections/avl/binary.rs index fdd1007..3ddcd00 100644 --- a/src/rstd/collections/avl/binary.rs +++ b/src/rstd/collections/avl/binary.rs @@ -35,7 +35,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> AvlNode<'a, Ctx, A> { pub fn new( l: AvlTree<'a, Ctx, A>, r: AvlTree<'a, Ctx, A>, - key: Rc, + key: A, ) -> AvlNodeResult<'a, Ctx, A> { balanced(l.height, r.height)?; Ok(Self { l, r, key }) @@ -94,7 +94,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for AvlTree<'a, Ctx, A } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for AvlNode<'a, Ctx, A> { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> Clone for AvlNode<'a, Ctx, A> { fn clone(&self) -> Self { Self { l: self.l.clone(), diff --git a/src/rstd/collections/avl/bounds.rs b/src/rstd/collections/avl/bounds.rs index 6d1b947..1376f04 100644 --- a/src/rstd/collections/avl/bounds.rs +++ b/src/rstd/collections/avl/bounds.rs @@ -3,23 +3,15 @@ use crate::func::context::*; use super::{binary::*, *}; +#[derive(Clone)] struct Bounds { - l: Option>, - r: Option>, -} - -impl Clone for Bounds { - fn clone(&self) -> Self { - Self { - l: self.l.clone(), - r: self.r.clone(), - } - } + l: Option, + r: Option, } pub enum BoundsError { - BoundsViolated { l: Rc, r: Rc }, - CannotJoin(Rc), + BoundsViolated { l: A, r: A }, + CannotJoin(A), } pub enum BoundError { @@ -55,7 +47,7 @@ pub struct BoundTree<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { pub struct BoundNode<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { l: BoundTree<'a, Ctx, A>, r: BoundTree<'a, Ctx, A>, - key: Rc, + key: A, bounds: Bounds, } @@ -64,16 +56,12 @@ pub struct BoundReference<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> { bounds: Bounds, } -impl Bounds { +impl Bounds { fn unbound() -> Self { Bounds { l: None, r: None } } - fn ordered( - l: &Rc, - r: &Rc, - comparator: &impl Comparator, - ) -> Result<(), BoundsError> { + fn ordered(l: &A, r: &A, comparator: &impl Comparator) -> Result<(), BoundsError> { if let Comparison::R = comparator.pick_smaller(l, r) { Err(BoundsError::BoundsViolated { l: l.clone(), @@ -85,8 +73,8 @@ impl Bounds { } fn new( - l: Option>, - r: Option>, + l: Option, + r: Option, comparator: &impl Comparator, ) -> Result> { if let (Some(kl), Some(kr)) = (&l, &r) { @@ -97,7 +85,7 @@ impl Bounds { fn split( self, - key: &Rc, + key: &A, comparator: &impl Comparator, ) -> Result<(Self, Self), BoundsError> { Ok(( @@ -109,7 +97,7 @@ impl Bounds { fn join( l: Self, r: Self, - key: &Rc, + key: &A, comparator: &impl Comparator, ) -> Result> { if let Some(lr) = &l.r { @@ -125,11 +113,7 @@ impl Bounds { Self::new(l.l, r.r, comparator) } - pub fn equal_bound( - l: &Option>, - r: &Option>, - comparator: &impl Comparator, - ) -> bool { + pub fn equal_bound(l: &Option, r: &Option, comparator: &impl Comparator) -> bool { match (l, r) { (None, None) => true, (Some(kl), Some(kr)) => matches!(comparator.pick_smaller(kl, kr), Comparison::E), @@ -142,9 +126,9 @@ impl Bounds { } } -pub type BoundSplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>, Rc); +pub type BoundSplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>, A); -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> BoundNode<'a, Ctx, A> { pub fn into_tree(self) -> BoundTreeResult<'a, Ctx, A> { let tree = AvlNode::new(self.l.tree, self.r.tree, self.key)?.into_tree()?; let bounds = self.bounds; @@ -161,7 +145,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> { pub fn new( l: BoundTree<'a, Ctx, A>, r: BoundTree<'a, Ctx, A>, - key: Rc, + key: A, comparator: &impl Comparator, ) -> BoundNodeResult<'a, Ctx, A> { let bounds = Bounds::join(l.bounds.clone(), r.bounds.clone(), &key, comparator)?; @@ -175,7 +159,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> { pub type BoundKeySplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>); -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> BoundTree<'a, Ctx, A> { pub fn height(&self) -> u64 { self.tree.height } @@ -202,7 +186,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> { fn split_empty( bounds: Bounds, - key: &Rc, + key: &A, factory: &Fctr<'a, Ctx, A>, comparator: &impl Comparator, ) -> Result<(Self, Self), BoundsError> { @@ -215,7 +199,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> { pub fn split_empty_res( self, - key: Rc, + key: A, factory: Fctr<'a, Ctx, A>, comparator: Rc>, ) -> BrKeySplit<'a, Ctx, A> { @@ -227,7 +211,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> { } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for BoundTree<'a, Ctx, A> { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> Clone for BoundTree<'a, Ctx, A> { fn clone(&self) -> Self { Self { tree: self.tree.clone(), @@ -249,7 +233,7 @@ pub type BrTree<'a, Ctx, A> = BoundResolution<'a, Ctx, A, BoundTree<'a, Ctx, A>> pub type BrKeySplit<'a, Ctx, A> = BoundResolution<'a, Ctx, A, BoundKeySplit<'a, Ctx, A>>; -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundReference<'a, Ctx, A> { +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone> BoundReference<'a, Ctx, A> { pub fn resolve(&self, comparator: Rc>) -> BrNode<'a, Ctx, A> { let bounds = self.bounds.clone(); Ctx::fmap(self.reference.resolve(), move |resolved| { diff --git a/src/rstd/collections/avl/context.rs b/src/rstd/collections/avl/context.rs index ca1c0b3..c8d3b17 100644 --- a/src/rstd/collections/avl/context.rs +++ b/src/rstd/collections/avl/context.rs @@ -21,13 +21,13 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> Clone } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> FunctorContext<'a> - for BoundContext<'a, Ctx, A, C> +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator> + FunctorContext<'a> for BoundContext<'a, Ctx, A, C> { type T = FallibleMonad<'a, Ctx, BoundResolutionError<'a, Ctx, A>>; } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> BinaryTrees<'a> +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator> BinaryTrees<'a> for BoundContext<'a, Ctx, A, C> { type Node = BoundNode<'a, Ctx, A>; @@ -66,8 +66,8 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> Binar } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> BinaryTreesMutable<'a> - for BoundContext<'a, Ctx, A, C> +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator> + BinaryTreesMutable<'a> for BoundContext<'a, Ctx, A, C> { fn empty(&self) -> Self::Tree { BoundTree::empty(self.factory.clone()) @@ -76,7 +76,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> Binar fn join_key( self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node> { self.join_key_balanced(tl, key, tr) @@ -85,14 +85,14 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> Binar fn split_key_empty( &self, tree: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, ) -> BTWrap<'a, Self, KeySplit<'a, Self>> { Ctx::stuff(tree.split_empty_res(key, self.factory.clone(), self.comparator.clone())) } } -impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> BinaryTreesAvl<'a> - for BoundContext<'a, Ctx, A, C> +impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator> + BinaryTreesAvl<'a> for BoundContext<'a, Ctx, A, C> { fn height(&self, tree: &Self::Tree) -> u64 { tree.height() @@ -107,7 +107,7 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator> Binar fn join_key_unbalanced( &self, tl: Self::Tree, - key: KeyRc<'a, Self>, + key: Self::Key, tr: Self::Tree, ) -> BTWrap<'a, Self, Self::Node> { match BoundNode::new(tl, tr, key, self.comparator.as_ref()) {