better binary tree splitting types

This commit is contained in:
AF 2022-05-30 18:11:59 +03:00
parent 2870c78c93
commit 296063a538
4 changed files with 66 additions and 79 deletions

View File

@ -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.activecollectioninterface import ActiveCollectionInterface
from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface from rainbowadn.data.collection.collection_interface.querycollectioninterface import QueryCollectionInterface
@ -68,14 +68,10 @@ class ActiveBinaryTree(
def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
if self.creation.splittable(self): if (split := self.creation.split(self)) is None:
treel: ActiveBinaryTree[ActiveKeyType, MetaDataType] return self.creation.tree(self, self, key)
original: HashPoint[ActiveKeyType] else:
treer: ActiveBinaryTree[ActiveKeyType, MetaDataType] treel, original, _, treer = split
treel, original, _, treer = self.creation.split(self)
assert isinstance(treel, ActiveBinaryTree)
assert isinstance(original, HashPoint)
assert isinstance(treer, ActiveBinaryTree)
comparison: Comparison = self.comparator.compare(original, key) comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison) assert isinstance(comparison, Comparison)
if isinstance(comparison, Replace): if isinstance(comparison, Replace):
@ -86,50 +82,41 @@ class ActiveBinaryTree(
return self.creation.tree(treel, treer.add(key), original) return self.creation.tree(treel, treer.add(key), original)
else: else:
raise TypeError raise TypeError
else:
return self.creation.tree(self, self, key)
def pop(self) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]: def pop(
assert self.creation.splittable(self) self,
treel: ActiveBinaryTree[ActiveKeyType, MetaDataType] tree_split: tuple[
original: HashPoint[ActiveKeyType] 'ActiveBinaryTree[ActiveKeyType, MetaDataType]',
treer: ActiveBinaryTree[ActiveKeyType, MetaDataType] HashPoint[ActiveKeyType],
treel, original, _, treer = self.creation.split(self) HashPoint[MetaDataType],
assert isinstance(treel, ActiveBinaryTree) 'ActiveBinaryTree[ActiveKeyType, MetaDataType]'
assert isinstance(original, HashPoint) ]
assert isinstance(treer, ActiveBinaryTree) ) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]:
if not self.creation.splittable(treel): treel, original, _, treer = tree_split
if (splitl := self.creation.split(treel)) is None:
return treer, original return treer, original
elif not self.creation.splittable(treer):
return treel, original
else: else:
treel, key = treel.pop() treel, key = treel.pop(splitl)
assert isinstance(treel, ActiveBinaryTree) assert isinstance(treel, ActiveBinaryTree)
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
return self.creation.tree(treel, treer, key), original return self.creation.tree(treel, treer, key), original
def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]': def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
if self.creation.splittable(self): if (split := self.creation.split(self)) is None:
treel: ActiveBinaryTree[ActiveKeyType, MetaDataType] return self
original: HashPoint[ActiveKeyType] else:
treer: ActiveBinaryTree[ActiveKeyType, MetaDataType] treel, original, _, treer = tree_split = split
treel, original, _, treer = self.creation.split(self)
assert isinstance(treel, ActiveBinaryTree)
assert isinstance(original, HashPoint)
assert isinstance(treer, ActiveBinaryTree)
comparison: Comparison = self.comparator.compare(original, key) comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison) assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal): if isinstance(comparison, Equal):
return self.pop()[0] return self.pop(tree_split)[0]
elif isinstance(comparison, Left): elif isinstance(comparison, Left):
return self.creation.tree(treel.remove(key), treer, original) return self.creation.tree(treel.remove(key), treer, original)
elif isinstance(comparison, Right): elif isinstance(comparison, Right):
return self.creation.tree(treel, treer.remove(key), original) return self.creation.tree(treel, treer.remove(key), original)
else: else:
raise TypeError raise TypeError
else:
return self
def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]: def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]:
return KeyMetadataQueryCollection( return KeyMetadataQueryCollection(
@ -139,27 +126,32 @@ class ActiveBinaryTree(
class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, 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( def split(
self, self,
tree: ActiveBinaryTree[ActiveKeyType, MetaDataType] tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]
) -> tuple[ ) -> Optional[
tuple[
ActiveBinaryTree[ActiveKeyType, MetaDataType], ActiveBinaryTree[ActiveKeyType, MetaDataType],
HashPoint[ActiveKeyType], HashPoint[ActiveKeyType],
HashPoint[MetaDataType], HashPoint[MetaDataType],
ActiveBinaryTree[ActiveKeyType, MetaDataType] ActiveBinaryTree[ActiveKeyType, MetaDataType]
]
]: ]:
assert isinstance(tree, ActiveBinaryTree) assert isinstance(tree, ActiveBinaryTree)
hash_point: HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] = tree.reference.reference.resolve() if tree.reference.reference.null():
return None
else:
hash_point: HashPoint[
BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]
] = tree.reference.reference.resolve()
assert isinstance(hash_point, HashPoint) assert isinstance(hash_point, HashPoint)
resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = hash_point.resolve() resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = hash_point.resolve()
assert isinstance(resolved, BinaryTree) assert isinstance(resolved, BinaryTree)
key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = resolved.key.resolve() key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = resolved.key.resolve()
assert isinstance(key_metadata, KeyMetadata) assert isinstance(key_metadata, KeyMetadata)
return tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer) return (
(tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer))
)
def _tree( def _tree(
self, self,

View File

@ -32,27 +32,29 @@ class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
tree: TreeType, tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> int: ) -> int:
if protocol.splittable(tree): if (split := protocol.split(tree)) is None:
_, _, metadata, _ = protocol.split(tree)
return metadata.resolve().integer
else:
return 0 return 0
else:
_, _, metadata, _ = split
return metadata.resolve().integer
def balance( def balance(
self, self,
tree: TreeType, tree: TreeType,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType] protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
) -> TreeType: ) -> TreeType:
if protocol.splittable(tree): if (split := protocol.split(tree)) is None:
treel, key, _, treer = protocol.split(tree) return tree
else:
treel, key, _, treer = split
delta = self.height(treel, protocol) - self.height(treer, protocol) delta = self.height(treel, protocol) - self.height(treer, protocol)
assert isinstance(delta, int) assert isinstance(delta, int)
if delta < -1: if delta < -1:
assert protocol.splittable(treer) assert (splitr := protocol.split(treer)) is not None
treerl, keyr, _, treerr = protocol.split(treer) treerl, keyr, _, treerr = splitr
if self.height(treerl, protocol) > self.height(treerr, protocol): if self.height(treerl, protocol) > self.height(treerr, protocol):
assert protocol.splittable(treerl) assert (splitrl := protocol.split(treerl)) is not None
treerll, keyrl, _, treerlr = protocol.split(treerl) treerll, keyrl, _, treerlr = splitrl
return protocol.tree( return protocol.tree(
protocol.tree(treel, treerll, key), protocol.tree(treel, treerll, key),
protocol.tree(treerlr, treerr, keyr), protocol.tree(treerlr, treerr, keyr),
@ -65,11 +67,11 @@ class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
keyr keyr
) )
elif delta > 1: elif delta > 1:
assert protocol.splittable(treel) assert (splitl := protocol.split(treel)) is not None
treell, keyl, _, treelr = protocol.split(treel) treell, keyl, _, treelr = splitl
if self.height(treelr, protocol) > self.height(treell, protocol): if self.height(treelr, protocol) > self.height(treell, protocol):
assert protocol.splittable(treelr) assert (splitlr := protocol.split(treelr)) is not None
treelrl, keylr, _, treelrr = protocol.split(treelr) treelrl, keylr, _, treelrr = splitlr
return protocol.tree( return protocol.tree(
protocol.tree(treell, treelrl, keyl), protocol.tree(treell, treelrl, keyl),
protocol.tree(treelrr, treer, key), protocol.tree(treelrr, treer, key),
@ -83,5 +85,3 @@ class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
) )
else: else:
return tree return tree
else:
return tree

View File

@ -1,3 +1,4 @@
import abc
from typing import Generic, TypeVar from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
@ -13,7 +14,8 @@ MetaDataType = TypeVar('MetaDataType')
class BalancedTreeCreationProtocol( class BalancedTreeCreationProtocol(
BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType], BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
Generic[ActiveKeyType, MetaDataType, TreeType] Generic[ActiveKeyType, MetaDataType, TreeType],
abc.ABC
): ):
def __init__( def __init__(
self, self,
@ -22,12 +24,6 @@ class BalancedTreeCreationProtocol(
assert isinstance(protocol, BinaryTreeBalancingProtocol) assert isinstance(protocol, BinaryTreeBalancingProtocol)
self.protocol = protocol 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: def _tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
raise NotImplementedError raise NotImplementedError

View File

@ -1,4 +1,4 @@
from typing import Generic, TypeVar from typing import Generic, Optional, TypeVar
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
@ -10,10 +10,9 @@ MetaDataType = TypeVar('MetaDataType')
class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]): class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]):
def splittable(self, tree: TreeType) -> bool: def split(self, tree: TreeType) -> Optional[
raise NotImplementedError tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]
]:
def split(self, tree: TreeType) -> tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]:
raise NotImplementedError raise NotImplementedError
def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType: