better binary tree splitting types
This commit is contained in:
parent
2870c78c93
commit
296063a538
@ -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[
|
||||
) -> 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()
|
||||
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)
|
||||
return (
|
||||
(tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer))
|
||||
)
|
||||
|
||||
def _tree(
|
||||
self,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user