diff --git a/rainbowadn/data/collection/trees/binary/activebinarytree.py b/rainbowadn/data/collection/trees/binary/activebinarytree.py index da67b2f..d54df1f 100644 --- a/rainbowadn/data/collection/trees/binary/activebinarytree.py +++ b/rainbowadn/data/collection/trees/binary/activebinarytree.py @@ -1,4 +1,4 @@ -from typing import Generic, TypeVar +from typing import Generic, Optional, TypeVar from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface @@ -68,14 +68,10 @@ class ActiveBinaryTree( def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': assert isinstance(key, HashPoint) - if self.creation.splittable(self): - treel: ActiveBinaryTree[ActiveKeyType, MetaDataType] - original: HashPoint[ActiveKeyType] - treer: ActiveBinaryTree[ActiveKeyType, MetaDataType] - treel, original, _, treer = self.creation.split(self) - assert isinstance(treel, ActiveBinaryTree) - assert isinstance(original, HashPoint) - assert isinstance(treer, ActiveBinaryTree) + 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): @@ -86,50 +82,41 @@ class ActiveBinaryTree( return self.creation.tree(treel, treer.add(key), original) else: raise TypeError - else: - return self.creation.tree(self, self, key) - def pop(self) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]: - assert self.creation.splittable(self) - treel: ActiveBinaryTree[ActiveKeyType, MetaDataType] - original: HashPoint[ActiveKeyType] - treer: ActiveBinaryTree[ActiveKeyType, MetaDataType] - treel, original, _, treer = self.creation.split(self) - assert isinstance(treel, ActiveBinaryTree) - assert isinstance(original, HashPoint) - assert isinstance(treer, ActiveBinaryTree) - if not self.creation.splittable(treel): + def pop( + self, + tree_split: tuple[ + 'ActiveBinaryTree[ActiveKeyType, MetaDataType]', + HashPoint[ActiveKeyType], + HashPoint[MetaDataType], + 'ActiveBinaryTree[ActiveKeyType, MetaDataType]' + ] + ) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]: + treel, original, _, treer = tree_split + if (splitl := self.creation.split(treel)) is None: return treer, original - elif not self.creation.splittable(treer): - return treel, original else: - treel, key = treel.pop() + treel, key = treel.pop(splitl) assert isinstance(treel, ActiveBinaryTree) assert isinstance(key, HashPoint) return self.creation.tree(treel, treer, key), original def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': assert isinstance(key, HashPoint) - if self.creation.splittable(self): - treel: ActiveBinaryTree[ActiveKeyType, MetaDataType] - original: HashPoint[ActiveKeyType] - treer: ActiveBinaryTree[ActiveKeyType, MetaDataType] - treel, original, _, treer = self.creation.split(self) - assert isinstance(treel, ActiveBinaryTree) - assert isinstance(original, HashPoint) - assert isinstance(treer, ActiveBinaryTree) + if (split := self.creation.split(self)) is None: + return self + else: + treel, original, _, treer = tree_split = split comparison: Comparison = self.comparator.compare(original, key) assert isinstance(comparison, Comparison) if isinstance(comparison, Equal): - return self.pop()[0] + return self.pop(tree_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 - else: - return self def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]: return KeyMetadataQueryCollection( @@ -139,27 +126,32 @@ class ActiveBinaryTree( class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, ActiveBinaryTree]): - def splittable(self, tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]) -> bool: - assert isinstance(tree, ActiveBinaryTree) - return not tree.reference.reference.null() - def split( self, tree: ActiveBinaryTree[ActiveKeyType, MetaDataType] - ) -> tuple[ - ActiveBinaryTree[ActiveKeyType, MetaDataType], - HashPoint[ActiveKeyType], - HashPoint[MetaDataType], - ActiveBinaryTree[ActiveKeyType, MetaDataType] + ) -> Optional[ + tuple[ + ActiveBinaryTree[ActiveKeyType, MetaDataType], + HashPoint[ActiveKeyType], + HashPoint[MetaDataType], + ActiveBinaryTree[ActiveKeyType, MetaDataType] + ] ]: assert isinstance(tree, ActiveBinaryTree) - hash_point: HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] = tree.reference.reference.resolve() - assert isinstance(hash_point, HashPoint) - resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = hash_point.resolve() - assert isinstance(resolved, BinaryTree) - key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = resolved.key.resolve() - assert isinstance(key_metadata, KeyMetadata) - return tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer) + if tree.reference.reference.null(): + return None + else: + hash_point: HashPoint[ + BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] + ] = tree.reference.reference.resolve() + assert isinstance(hash_point, HashPoint) + resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = hash_point.resolve() + assert isinstance(resolved, BinaryTree) + key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = resolved.key.resolve() + assert isinstance(key_metadata, KeyMetadata) + return ( + (tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer)) + ) def _tree( self, diff --git a/rainbowadn/data/collection/trees/binary/avl.py b/rainbowadn/data/collection/trees/binary/avl.py index 8b82c35..cda032e 100644 --- a/rainbowadn/data/collection/trees/binary/avl.py +++ b/rainbowadn/data/collection/trees/binary/avl.py @@ -32,27 +32,29 @@ class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]): tree: TreeType, protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] ) -> int: - if protocol.splittable(tree): - _, _, metadata, _ = protocol.split(tree) - return metadata.resolve().integer - else: + if (split := protocol.split(tree)) is None: return 0 + else: + _, _, metadata, _ = split + return metadata.resolve().integer def balance( self, tree: TreeType, protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] ) -> TreeType: - if protocol.splittable(tree): - treel, key, _, treer = protocol.split(tree) + if (split := protocol.split(tree)) is None: + return tree + else: + treel, key, _, treer = split delta = self.height(treel, protocol) - self.height(treer, protocol) assert isinstance(delta, int) if delta < -1: - assert protocol.splittable(treer) - treerl, keyr, _, treerr = protocol.split(treer) + assert (splitr := protocol.split(treer)) is not None + treerl, keyr, _, treerr = splitr if self.height(treerl, protocol) > self.height(treerr, protocol): - assert protocol.splittable(treerl) - treerll, keyrl, _, treerlr = protocol.split(treerl) + assert (splitrl := protocol.split(treerl)) is not None + treerll, keyrl, _, treerlr = splitrl return protocol.tree( protocol.tree(treel, treerll, key), protocol.tree(treerlr, treerr, keyr), @@ -65,11 +67,11 @@ class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]): keyr ) elif delta > 1: - assert protocol.splittable(treel) - treell, keyl, _, treelr = protocol.split(treel) + assert (splitl := protocol.split(treel)) is not None + treell, keyl, _, treelr = splitl if self.height(treelr, protocol) > self.height(treell, protocol): - assert protocol.splittable(treelr) - treelrl, keylr, _, treelrr = protocol.split(treelr) + assert (splitlr := protocol.split(treelr)) is not None + treelrl, keylr, _, treelrr = splitlr return protocol.tree( protocol.tree(treell, treelrl, keyl), protocol.tree(treelrr, treer, key), @@ -83,5 +85,3 @@ class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]): ) else: return tree - else: - return tree diff --git a/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py b/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py index 37f2b52..8f10013 100644 --- a/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py +++ b/rainbowadn/data/collection/trees/binary/balancedtreecreationprotocol.py @@ -1,3 +1,4 @@ +import abc from typing import Generic, TypeVar from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol @@ -13,7 +14,8 @@ MetaDataType = TypeVar('MetaDataType') class BalancedTreeCreationProtocol( BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], - Generic[ActiveKeyType, MetaDataType, TreeType] + Generic[ActiveKeyType, MetaDataType, TreeType], + abc.ABC ): def __init__( self, @@ -22,12 +24,6 @@ class BalancedTreeCreationProtocol( assert isinstance(protocol, BinaryTreeBalancingProtocol) self.protocol = protocol - def splittable(self, tree: TreeType) -> bool: - raise NotImplementedError - - def split(self, tree: TreeType) -> tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]: - raise NotImplementedError - def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: raise NotImplementedError diff --git a/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py b/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py index 1768be8..78cc6c8 100644 --- a/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py +++ b/rainbowadn/data/collection/trees/binary/binarytreecreationprotocol.py @@ -1,4 +1,4 @@ -from typing import Generic, TypeVar +from typing import Generic, Optional, TypeVar from rainbowadn.hashing.hashpoint import HashPoint @@ -10,10 +10,9 @@ MetaDataType = TypeVar('MetaDataType') class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]): - def splittable(self, tree: TreeType) -> bool: - raise NotImplementedError - - def split(self, tree: TreeType) -> tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]: + def split(self, tree: TreeType) -> Optional[ + tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType] + ]: raise NotImplementedError def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: