reduce Rc usage with binary

This commit is contained in:
AF 2023-06-16 06:23:03 +00:00
parent 5dbd034b86
commit 6b04eec9ae
6 changed files with 57 additions and 90 deletions

View File

@ -1,16 +1,12 @@
mod avl;
use std::rc::Rc;
use crate::flow::comparator::*;
use crate::func::{context::*, *};
pub type KeyRc<'a, BT> = Rc<<BT as BinaryTrees<'a>>::Key>;
pub type Split<'a, BT> = (
<BT as BinaryTrees<'a>>::Tree,
<BT as BinaryTrees<'a>>::Tree,
KeyRc<'a, BT>,
<BT as BinaryTrees<'a>>::Key,
);
pub type KeySplit<'a, BT> = (<BT as BinaryTrees<'a>>::Tree, <BT as BinaryTrees<'a>>::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<Self::Key>;
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));

View File

@ -4,20 +4,11 @@ use crate::flow::comparator::*;
use super::*;
#[derive(Clone)]
struct AvlN<A> {
l: AvlT<A>,
r: AvlT<A>,
key: Rc<A>,
}
impl<A> Clone for AvlN<A> {
fn clone(&self) -> Self {
Self {
l: self.l.clone(),
r: self.r.clone(),
key: self.key.clone(),
}
}
key: A,
}
impl<A: Display> Display for AvlN<A> {
@ -112,7 +103,7 @@ impl<'a, A: 'a> FunctorContext<'a> for AvlTs<A> {
type T = instances::solo::SoloInstance;
}
impl<'a, A: 'a + PartialOrd> BinaryTrees<'a> for AvlTs<A> {
impl<'a, A: 'a + PartialOrd + Clone> BinaryTrees<'a> for AvlTs<A> {
type Node = AvlN<A>;
type Reference = AvlR<A>;
@ -155,7 +146,7 @@ impl<'a, A: 'a + PartialOrd> BinaryTrees<'a> for AvlTs<A> {
}
}
impl<'a, A: 'a + PartialOrd> BinaryTreesMutable<'a> for AvlTs<A> {
impl<'a, A: 'a + PartialOrd + Clone> BinaryTreesMutable<'a> for AvlTs<A> {
fn empty(&self) -> Self::Tree {
AvlT {
reference: None,
@ -166,7 +157,7 @@ impl<'a, A: 'a + PartialOrd> BinaryTreesMutable<'a> for AvlTs<A> {
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<A> {
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<A> {
impl<'a, A: 'a + PartialOrd + Clone> BinaryTreesAvl<'a> for AvlTs<A> {
fn height(&self, tree: &Self::Tree) -> u64 {
tree.height
}
@ -193,7 +184,7 @@ impl<'a, A: 'a + PartialOrd> BinaryTreesAvl<'a> for AvlTs<A> {
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);
}

View File

@ -65,7 +65,7 @@ impl<E: Error> Error for AvlError<E> {}
pub struct AvlNode<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
l: AvlTree<'a, Ctx, A>,
r: AvlTree<'a, Ctx, A>,
key: Rc<A>,
key: A,
}
pub struct AvlTree<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {

View File

@ -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<A>,
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(),

View File

@ -3,23 +3,15 @@ use crate::func::context::*;
use super::{binary::*, *};
#[derive(Clone)]
struct Bounds<A> {
l: Option<Rc<A>>,
r: Option<Rc<A>>,
}
impl<A> Clone for Bounds<A> {
fn clone(&self) -> Self {
Self {
l: self.l.clone(),
r: self.r.clone(),
}
}
l: Option<A>,
r: Option<A>,
}
pub enum BoundsError<A> {
BoundsViolated { l: Rc<A>, r: Rc<A> },
CannotJoin(Rc<A>),
BoundsViolated { l: A, r: A },
CannotJoin(A),
}
pub enum BoundError<A, E> {
@ -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<A>,
key: A,
bounds: Bounds<A>,
}
@ -64,16 +56,12 @@ pub struct BoundReference<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> {
bounds: Bounds<A>,
}
impl<A> Bounds<A> {
impl<A: Clone> Bounds<A> {
fn unbound() -> Self {
Bounds { l: None, r: None }
}
fn ordered(
l: &Rc<A>,
r: &Rc<A>,
comparator: &impl Comparator<A>,
) -> Result<(), BoundsError<A>> {
fn ordered(l: &A, r: &A, comparator: &impl Comparator<A>) -> Result<(), BoundsError<A>> {
if let Comparison::R = comparator.pick_smaller(l, r) {
Err(BoundsError::BoundsViolated {
l: l.clone(),
@ -85,8 +73,8 @@ impl<A> Bounds<A> {
}
fn new(
l: Option<Rc<A>>,
r: Option<Rc<A>>,
l: Option<A>,
r: Option<A>,
comparator: &impl Comparator<A>,
) -> Result<Self, BoundsError<A>> {
if let (Some(kl), Some(kr)) = (&l, &r) {
@ -97,7 +85,7 @@ impl<A> Bounds<A> {
fn split(
self,
key: &Rc<A>,
key: &A,
comparator: &impl Comparator<A>,
) -> Result<(Self, Self), BoundsError<A>> {
Ok((
@ -109,7 +97,7 @@ impl<A> Bounds<A> {
fn join(
l: Self,
r: Self,
key: &Rc<A>,
key: &A,
comparator: &impl Comparator<A>,
) -> Result<Self, BoundsError<A>> {
if let Some(lr) = &l.r {
@ -125,11 +113,7 @@ impl<A> Bounds<A> {
Self::new(l.l, r.r, comparator)
}
pub fn equal_bound(
l: &Option<Rc<A>>,
r: &Option<Rc<A>>,
comparator: &impl Comparator<A>,
) -> bool {
pub fn equal_bound(l: &Option<A>, r: &Option<A>, comparator: &impl Comparator<A>) -> bool {
match (l, r) {
(None, None) => true,
(Some(kl), Some(kr)) => matches!(comparator.pick_smaller(kl, kr), Comparison::E),
@ -142,9 +126,9 @@ impl<A> Bounds<A> {
}
}
pub type BoundSplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>, Rc<A>);
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<A>,
key: A,
comparator: &impl Comparator<A>,
) -> 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<A>,
key: &Rc<A>,
key: &A,
factory: &Fctr<'a, Ctx, A>,
comparator: &impl Comparator<A>,
) -> Result<(Self, Self), BoundsError<A>> {
@ -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<A>,
key: A,
factory: Fctr<'a, Ctx, A>,
comparator: Rc<impl 'a + Comparator<A>>,
) -> 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<impl 'a + Comparator<A>>) -> BrNode<'a, Ctx, A> {
let bounds = self.bounds.clone();
Ctx::fmap(self.reference.resolve(), move |resolved| {

View File

@ -21,13 +21,13 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> Clone
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> FunctorContext<'a>
for BoundContext<'a, Ctx, A, C>
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>>
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<A>> BinaryTrees<'a>
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>> 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<A>> Binar
}
}
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> BinaryTreesMutable<'a>
for BoundContext<'a, Ctx, A, C>
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>>
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<A>> 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<A>> 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<A>> BinaryTreesAvl<'a>
for BoundContext<'a, Ctx, A, C>
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx> + Clone, C: 'a + Comparator<A>>
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<A>> 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()) {