rainbowadn/rainbowadn/data/collection/trees/binary/activebinarytree.py
2022-06-19 22:53:02 +03:00

134 lines
5.2 KiB
Python

from typing import Generic, Optional, TypeVar
from rainbowadn.core.hashpoint import HashPoint
from rainbowadn.core.nullability.null import Null
from rainbowadn.core.nullability.nullablereference import NullableReference
from rainbowadn.core.rainbow_factory import RainbowFactory
from rainbowadn.data.collection.collection_interface.collectioninterface import CollectionInterface
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
from rainbowadn.data.collection.trees.binary.actions.stdactions import AddAction, ContainsAction, RemoveAction
from rainbowadn.data.collection.trees.binary.balancedtreecreationprotocol import BalancedTreeCreationProtocol
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory
from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.data.collection.trees.binary.binarytreesplit import BinaryTreeSplit
__all__ = ('ActiveBinaryTree',)
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
class ActiveBinaryTree(
CollectionInterface[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
Generic[ActiveKeyType, MetaDataType]
):
def __init__(
self,
protocol: BinaryTreeBalancingProtocol[
ActiveKeyType,
MetaDataType,
'ActiveBinaryTree[ActiveKeyType, MetaDataType]'
],
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
):
assert isinstance(protocol, BinaryTreeBalancingProtocol)
assert isinstance(reference, NullableReference)
super().__init__(reference)
self.protocol = protocol
self.creation = ActiveCreationProtocol(protocol)
assert isinstance(self.creation, BinaryTreeCreationProtocol)
@classmethod
def empty(
cls,
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
factory: RainbowFactory[ActiveKeyType]
):
assert isinstance(protocol, BinaryTreeBalancingProtocol)
assert isinstance(factory, RainbowFactory)
return cls(
protocol,
NullableReference(
Null(),
BinaryTreeFactory(KeyMetadataFactory(factory, protocol.empty_metadata().factory))
)
)
def create(
self,
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(reference, NullableReference)
return ActiveBinaryTree(
self.protocol,
reference
)
async def add(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint)
return await AddAction(key).on(self.creation, self)
async def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint)
return await RemoveAction(key).on(self.creation, self)
async def contains(self, key: HashPoint[ActiveKeyType]) -> bool:
assert isinstance(key, HashPoint)
return await ContainsAction(key).on(self.creation, self)
def loose(self) -> CollectionInterface[
BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]
]:
return self
class ActiveCreationProtocol(
BalancedTreeCreationProtocol[
ActiveKeyType,
MetaDataType,
ActiveBinaryTree[ActiveKeyType, MetaDataType]
]
):
async def split(
self,
tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]
) -> Optional[
BinaryTreeSplit[
ActiveKeyType,
MetaDataType,
ActiveBinaryTree[ActiveKeyType, MetaDataType]
]
]:
assert isinstance(tree, ActiveBinaryTree)
if tree.reference.null():
return None
else:
resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = await tree.reference.resolve()
assert isinstance(resolved, BinaryTree)
key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = await resolved.key.resolve()
assert isinstance(key_metadata, KeyMetadata)
return BinaryTreeSplit(
tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer)
)
async def _tree(
self,
treel: ActiveBinaryTree,
treer: ActiveBinaryTree,
key: HashPoint[ActiveKeyType]
) -> ActiveBinaryTree:
assert isinstance(treel, ActiveBinaryTree)
assert isinstance(treer, ActiveBinaryTree)
assert isinstance(key, HashPoint)
return ActiveBinaryTree(
self.protocol,
NullableReference.off(
BinaryTree(
treel.reference,
treer.reference,
HashPoint.of(KeyMetadata(key, await self.protocol.metadata(treel, treer, key, self)))
)
)
)