From 5e435268c35786431f4eff2ba92acb312c9bd5ee Mon Sep 17 00:00:00 2001 From: timotheyca Date: Wed, 8 Jun 2022 15:45:42 +0300 Subject: [PATCH] stdactions --- .../trees/binary/activebinarytree.py | 80 ++------- .../binary/balancedtreecreationprotocol.py | 1 + .../trees/binary/binarytreeaction.py | 46 +++++ .../binary/binarytreecreationprotocol.py | 4 + .../collection/trees/binary/stdactions.py | 162 ++++++++++++++++++ 5 files changed, 230 insertions(+), 63 deletions(-) create mode 100644 rainbowadn/data/collection/trees/binary/binarytreeaction.py create mode 100644 rainbowadn/data/collection/trees/binary/stdactions.py diff --git a/rainbowadn/data/collection/trees/binary/activebinarytree.py b/rainbowadn/data/collection/trees/binary/activebinarytree.py index 5dc6721..43529cf 100644 --- a/rainbowadn/data/collection/trees/binary/activebinarytree.py +++ b/rainbowadn/data/collection/trees/binary/activebinarytree.py @@ -6,7 +6,8 @@ from rainbowadn.data.collection.trees.binary.balancedtreecreationprotocol import from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol -from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Equal, Left, Replace, Right) +from rainbowadn.data.collection.trees.binary.stdactions import AddAction, ContainsAction, RemoveAction +from rainbowadn.data.collection.trees.comparison.comparator import Comparator from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.nullability.null import Null from rainbowadn.hashing.nullability.nullablereference import NullableReference @@ -24,7 +25,11 @@ class ActiveBinaryTree( ): def __init__( self, - protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'], + protocol: BinaryTreeBalancingProtocol[ + ActiveKeyType, + MetaDataType, + 'ActiveBinaryTree[ActiveKeyType, MetaDataType]' + ], reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] ): assert isinstance(protocol, BinaryTreeBalancingProtocol) @@ -64,72 +69,15 @@ class ActiveBinaryTree( def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': assert isinstance(key, HashPoint) - if (split := self.creation.split(self)) is None: - return self.creation.tree(self, self, key) - else: - treel, original, _, treer = split - comparison: Comparison = self.comparator.compare(original, key) - assert isinstance(comparison, Comparison) - if isinstance(comparison, Replace): - return self.creation.tree(treel, treer, key) - elif isinstance(comparison, Left): - return self.creation.tree(treel.add(key), treer, original) - elif isinstance(comparison, Right): - return self.creation.tree(treel, treer.add(key), original) - else: - raise TypeError - - def pop( - self, - split: tuple[ - 'ActiveBinaryTree[ActiveKeyType, MetaDataType]', - HashPoint[ActiveKeyType], - HashPoint[MetaDataType], - 'ActiveBinaryTree[ActiveKeyType, MetaDataType]' - ] - ) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]: - treel, original, _, treer = split - if (splitl := self.creation.split(treel)) is None: - return treer, original - else: - treel, key = treel.pop(splitl) - assert isinstance(treel, ActiveBinaryTree) - assert isinstance(key, HashPoint) - return self.creation.tree(treel, treer, key), original + return AddAction(key).on(self.creation, self) def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': assert isinstance(key, HashPoint) - if (split := self.creation.split(self)) is None: - return self - else: - treel, original, _, treer = split - comparison: Comparison = self.comparator.compare(original, key) - assert isinstance(comparison, Comparison) - if isinstance(comparison, Equal): - return self.pop(split)[0] - elif isinstance(comparison, Left): - return self.creation.tree(treel.remove(key), treer, original) - elif isinstance(comparison, Right): - return self.creation.tree(treel, treer.remove(key), original) - else: - raise TypeError + return RemoveAction(key).on(self.creation, self) def contains(self, key: HashPoint[ActiveKeyType]) -> bool: assert isinstance(key, HashPoint) - if (split := self.creation.split(self)) is None: - return False - else: - treel, original, _, treer = split - comparison: Comparison = self.comparator.compare(original, key) - assert isinstance(comparison, Comparison) - if isinstance(comparison, Equal): - return True - elif isinstance(comparison, Left): - return treel.contains(key) - elif isinstance(comparison, Right): - return treer.contains(key) - else: - raise TypeError + return ContainsAction(key).on(self.creation, self) def loose(self) -> CollectionInterface[ BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] @@ -137,7 +85,13 @@ class ActiveBinaryTree( return self -class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, ActiveBinaryTree]): +class ActiveCreationProtocol( + BalancedTreeCreationProtocol[ + ActiveKeyType, + MetaDataType, + ActiveBinaryTree[ActiveKeyType, MetaDataType] + ] +): def split( self, tree: ActiveBinaryTree[ActiveKeyType, MetaDataType] diff --git a/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py b/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py index 8f10013..ba9062e 100644 --- a/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py +++ b/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py @@ -23,6 +23,7 @@ class BalancedTreeCreationProtocol( ): assert isinstance(protocol, BinaryTreeBalancingProtocol) self.protocol = protocol + super().__init__(protocol.comparator) def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: raise NotImplementedError diff --git a/rainbowadn/data/collection/trees/binary/binarytreeaction.py b/rainbowadn/data/collection/trees/binary/binarytreeaction.py new file mode 100644 index 0000000..2e9963f --- /dev/null +++ b/rainbowadn/data/collection/trees/binary/binarytreeaction.py @@ -0,0 +1,46 @@ +from typing import Generic, TypeVar + +from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol +from rainbowadn.hashing.hashpoint import HashPoint + +__all__ = ('BinaryTreeAction',) + +TreeType = TypeVar('TreeType') +ActiveKeyType = TypeVar('ActiveKeyType') +MetaDataType = TypeVar('MetaDataType') +ActionType = TypeVar('ActionType') + + +class BinaryTreeAction(Generic[ActiveKeyType, MetaDataType, TreeType, ActionType]): + def on( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + tree: TreeType + ) -> ActionType: + if (split := protocol.split(tree)) is None: + return self.on_null(protocol, tree) + else: + treel, key, _, treer = split + return self.on_split(protocol, treel, key, treer) + + def on_null( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + tree: TreeType + ) -> ActionType: + raise NotImplementedError + + def on_split( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + treel: TreeType, + key: HashPoint[ActiveKeyType], + treer: TreeType + ) -> ActionType: + raise NotImplementedError + + def per( + self: 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]', + _protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType] + ) -> 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]': + return self diff --git a/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py b/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py index 6380bb6..cd23941 100644 --- a/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py +++ b/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py @@ -1,5 +1,6 @@ from typing import Generic, Optional, TypeVar +from rainbowadn.data.collection.trees.comparison.comparator import Comparator from rainbowadn.hashing.hashpoint import HashPoint __all__ = ('BinaryTreeCreationProtocol',) @@ -10,6 +11,9 @@ MetaDataType = TypeVar('MetaDataType') class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]): + def __init__(self, comparator: Comparator[ActiveKeyType]): + self.comparator = comparator + def split(self, tree: TreeType) -> Optional[ tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType] ]: diff --git a/rainbowadn/data/collection/trees/binary/stdactions.py b/rainbowadn/data/collection/trees/binary/stdactions.py new file mode 100644 index 0000000..f4a8e74 --- /dev/null +++ b/rainbowadn/data/collection/trees/binary/stdactions.py @@ -0,0 +1,162 @@ +from typing import Generic, TypeVar + +from rainbowadn.data.collection.trees.binary.binarytreeaction import BinaryTreeAction +from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol +from rainbowadn.data.collection.trees.comparison.comparator import Comparison, Equal, Left, Replace, Right +from rainbowadn.hashing.hashpoint import HashPoint + +__all__ = ('AddAction', 'RemoveAction', 'ContainsAction',) + +TreeType = TypeVar('TreeType') +ActiveKeyType = TypeVar('ActiveKeyType') +MetaDataType = TypeVar('MetaDataType') + + +class AddAction( + BinaryTreeAction[ + ActiveKeyType, + MetaDataType, + TreeType, + TreeType + ], + Generic[ActiveKeyType, MetaDataType, TreeType] +): + def __init__(self, key: HashPoint[ActiveKeyType]): + assert isinstance(key, HashPoint) + self.key = key + + def on_null( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + tree: TreeType + ) -> TreeType: + return protocol.tree(tree, tree, self.key) + + def on_split( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + treel: TreeType, + key: HashPoint[ActiveKeyType], + treer: TreeType + ) -> TreeType: + comparison: Comparison = protocol.comparator.compare(key, self.key) + assert isinstance(comparison, Comparison) + if isinstance(comparison, Replace): + return protocol.tree(treel, treer, self.key) + elif isinstance(comparison, Left): + return protocol.tree(self.on(protocol, treel), treer, key) + elif isinstance(comparison, Right): + return protocol.tree(treel, self.on(protocol, treer), key) + else: + raise TypeError + + +class MergeAction( + BinaryTreeAction[ + ActiveKeyType, + MetaDataType, + TreeType, + TreeType + ], + Generic[ActiveKeyType, MetaDataType, TreeType] +): + def __init__(self, treer: TreeType): + self.treer = treer + + def on_null( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + tree: TreeType + ) -> TreeType: + return self.treer + + def on_split( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + treel: TreeType, + key: HashPoint[ActiveKeyType], + treer: TreeType + ) -> TreeType: + return protocol.tree( + MergeAction(treer).on(protocol, treel), + self.treer, + key + ) + + +class RemoveAction( + BinaryTreeAction[ + ActiveKeyType, + MetaDataType, + TreeType, + TreeType + ], + Generic[ActiveKeyType, MetaDataType, TreeType] +): + def __init__(self, key: HashPoint[ActiveKeyType]): + assert isinstance(key, HashPoint) + self.key = key + + def on_null( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + tree: TreeType + ) -> TreeType: + return tree + + def on_split( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + treel: TreeType, + key: HashPoint[ActiveKeyType], + treer: TreeType + ) -> TreeType: + comparison: Comparison = protocol.comparator.compare(key, self.key) + assert isinstance(comparison, Comparison) + if isinstance(comparison, Equal): + return MergeAction(treer).on(protocol, treel) + elif isinstance(comparison, Left): + return protocol.tree(self.on(protocol, treel), treer, key) + elif isinstance(comparison, Right): + return protocol.tree(treel, self.on(protocol, treer), key) + else: + raise TypeError + + +class ContainsAction( + BinaryTreeAction[ + ActiveKeyType, + MetaDataType, + TreeType, + bool + ], + Generic[ActiveKeyType, MetaDataType, TreeType] +): + def __init__(self, key: HashPoint[ActiveKeyType]): + assert isinstance(key, HashPoint) + self.key = key + + def on_null( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + tree: TreeType + ) -> bool: + return False + + def on_split( + self, + protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], + treel: TreeType, + key: HashPoint[ActiveKeyType], + treer: TreeType + ) -> bool: + comparison: Comparison = protocol.comparator.compare(key, self.key) + assert isinstance(comparison, Comparison) + if isinstance(comparison, Equal): + return True + elif isinstance(comparison, Left): + return self.on(protocol, treel) + elif isinstance(comparison, Right): + return self.on(protocol, treer) + else: + raise TypeError