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.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,

View File

@ -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

View File

@ -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

View File

@ -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: