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.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[
|
||||||
ActiveBinaryTree[ActiveKeyType, MetaDataType],
|
tuple[
|
||||||
HashPoint[ActiveKeyType],
|
ActiveBinaryTree[ActiveKeyType, MetaDataType],
|
||||||
HashPoint[MetaDataType],
|
HashPoint[ActiveKeyType],
|
||||||
ActiveBinaryTree[ActiveKeyType, MetaDataType]
|
HashPoint[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():
|
||||||
assert isinstance(hash_point, HashPoint)
|
return None
|
||||||
resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = hash_point.resolve()
|
else:
|
||||||
assert isinstance(resolved, BinaryTree)
|
hash_point: HashPoint[
|
||||||
key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = resolved.key.resolve()
|
BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]
|
||||||
assert isinstance(key_metadata, KeyMetadata)
|
] = tree.reference.reference.resolve()
|
||||||
return tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer)
|
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(
|
def _tree(
|
||||||
self,
|
self,
|
||||||
|
@ -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
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user