stdactions

This commit is contained in:
AF 2022-06-08 15:45:42 +03:00
parent 75de7ff5db
commit 5e435268c3
5 changed files with 230 additions and 63 deletions

View File

@ -6,7 +6,8 @@ from rainbowadn.data.collection.trees.binary.balancedtreecreationprotocol import
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory 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.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Equal, Left, Replace, Right) from rainbowadn.data.collection.trees.binary.stdactions import AddAction, ContainsAction, RemoveAction
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.null import Null from rainbowadn.hashing.nullability.null import Null
from rainbowadn.hashing.nullability.nullablereference import NullableReference from rainbowadn.hashing.nullability.nullablereference import NullableReference
@ -24,7 +25,11 @@ class ActiveBinaryTree(
): ):
def __init__( def __init__(
self, self,
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'], protocol: BinaryTreeBalancingProtocol[
ActiveKeyType,
MetaDataType,
'ActiveBinaryTree[ActiveKeyType, MetaDataType]'
],
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
): ):
assert isinstance(protocol, BinaryTreeBalancingProtocol) assert isinstance(protocol, BinaryTreeBalancingProtocol)
@ -64,72 +69,15 @@ 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 (split := self.creation.split(self)) is None: return AddAction(key).on(self.creation, self)
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):
return self.creation.tree(treel, treer, key)
elif isinstance(comparison, Left):
return self.creation.tree(treel.add(key), treer, original)
elif isinstance(comparison, Right):
return self.creation.tree(treel, treer.add(key), original)
else:
raise TypeError
def pop(
self,
split: tuple[
'ActiveBinaryTree[ActiveKeyType, MetaDataType]',
HashPoint[ActiveKeyType],
HashPoint[MetaDataType],
'ActiveBinaryTree[ActiveKeyType, MetaDataType]'
]
) -> tuple['ActiveBinaryTree[ActiveKeyType, MetaDataType]', HashPoint[ActiveKeyType]]:
treel, original, _, treer = split
if (splitl := self.creation.split(treel)) is None:
return treer, original
else:
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]': def remove(self, key: HashPoint[ActiveKeyType]) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
if (split := self.creation.split(self)) is None: return RemoveAction(key).on(self.creation, self)
return self
else:
treel, original, _, treer = split
comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal):
return self.pop(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
def contains(self, key: HashPoint[ActiveKeyType]) -> bool: def contains(self, key: HashPoint[ActiveKeyType]) -> bool:
assert isinstance(key, HashPoint) assert isinstance(key, HashPoint)
if (split := self.creation.split(self)) is None: return ContainsAction(key).on(self.creation, self)
return False
else:
treel, original, _, treer = split
comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal):
return True
elif isinstance(comparison, Left):
return treel.contains(key)
elif isinstance(comparison, Right):
return treer.contains(key)
else:
raise TypeError
def loose(self) -> CollectionInterface[ def loose(self) -> CollectionInterface[
BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]
@ -137,7 +85,13 @@ class ActiveBinaryTree(
return self return self
class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, ActiveBinaryTree]): class ActiveCreationProtocol(
BalancedTreeCreationProtocol[
ActiveKeyType,
MetaDataType,
ActiveBinaryTree[ActiveKeyType, MetaDataType]
]
):
def split( def split(
self, self,
tree: ActiveBinaryTree[ActiveKeyType, MetaDataType] tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]

View File

@ -23,6 +23,7 @@ class BalancedTreeCreationProtocol(
): ):
assert isinstance(protocol, BinaryTreeBalancingProtocol) assert isinstance(protocol, BinaryTreeBalancingProtocol)
self.protocol = protocol self.protocol = protocol
super().__init__(protocol.comparator)
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

@ -0,0 +1,46 @@
from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.hashing.hashpoint import HashPoint
__all__ = ('BinaryTreeAction',)
TreeType = TypeVar('TreeType')
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
ActionType = TypeVar('ActionType')
class BinaryTreeAction(Generic[ActiveKeyType, MetaDataType, TreeType, ActionType]):
def on(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType
) -> ActionType:
if (split := protocol.split(tree)) is None:
return self.on_null(protocol, tree)
else:
treel, key, _, treer = split
return self.on_split(protocol, treel, key, treer)
def on_null(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType
) -> ActionType:
raise NotImplementedError
def on_split(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
treel: TreeType,
key: HashPoint[ActiveKeyType],
treer: TreeType
) -> ActionType:
raise NotImplementedError
def per(
self: 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]',
_protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]
) -> 'BinaryTreeAction[ActiveKeyType, MetaDataType, TreeType, ActionType]':
return self

View File

@ -1,5 +1,6 @@
from typing import Generic, Optional, TypeVar from typing import Generic, Optional, TypeVar
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
__all__ = ('BinaryTreeCreationProtocol',) __all__ = ('BinaryTreeCreationProtocol',)
@ -10,6 +11,9 @@ MetaDataType = TypeVar('MetaDataType')
class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]): class BinaryTreeCreationProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]):
def __init__(self, comparator: Comparator[ActiveKeyType]):
self.comparator = comparator
def split(self, tree: TreeType) -> Optional[ def split(self, tree: TreeType) -> Optional[
tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType] tuple[TreeType, HashPoint[ActiveKeyType], HashPoint[MetaDataType], TreeType]
]: ]:

View File

@ -0,0 +1,162 @@
from typing import Generic, TypeVar
from rainbowadn.data.collection.trees.binary.binarytreeaction import BinaryTreeAction
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
from rainbowadn.data.collection.trees.comparison.comparator import Comparison, Equal, Left, Replace, Right
from rainbowadn.hashing.hashpoint import HashPoint
__all__ = ('AddAction', 'RemoveAction', 'ContainsAction',)
TreeType = TypeVar('TreeType')
ActiveKeyType = TypeVar('ActiveKeyType')
MetaDataType = TypeVar('MetaDataType')
class AddAction(
BinaryTreeAction[
ActiveKeyType,
MetaDataType,
TreeType,
TreeType
],
Generic[ActiveKeyType, MetaDataType, TreeType]
):
def __init__(self, key: HashPoint[ActiveKeyType]):
assert isinstance(key, HashPoint)
self.key = key
def on_null(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType
) -> TreeType:
return protocol.tree(tree, tree, self.key)
def on_split(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
treel: TreeType,
key: HashPoint[ActiveKeyType],
treer: TreeType
) -> TreeType:
comparison: Comparison = protocol.comparator.compare(key, self.key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Replace):
return protocol.tree(treel, treer, self.key)
elif isinstance(comparison, Left):
return protocol.tree(self.on(protocol, treel), treer, key)
elif isinstance(comparison, Right):
return protocol.tree(treel, self.on(protocol, treer), key)
else:
raise TypeError
class MergeAction(
BinaryTreeAction[
ActiveKeyType,
MetaDataType,
TreeType,
TreeType
],
Generic[ActiveKeyType, MetaDataType, TreeType]
):
def __init__(self, treer: TreeType):
self.treer = treer
def on_null(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType
) -> TreeType:
return self.treer
def on_split(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
treel: TreeType,
key: HashPoint[ActiveKeyType],
treer: TreeType
) -> TreeType:
return protocol.tree(
MergeAction(treer).on(protocol, treel),
self.treer,
key
)
class RemoveAction(
BinaryTreeAction[
ActiveKeyType,
MetaDataType,
TreeType,
TreeType
],
Generic[ActiveKeyType, MetaDataType, TreeType]
):
def __init__(self, key: HashPoint[ActiveKeyType]):
assert isinstance(key, HashPoint)
self.key = key
def on_null(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType
) -> TreeType:
return tree
def on_split(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
treel: TreeType,
key: HashPoint[ActiveKeyType],
treer: TreeType
) -> TreeType:
comparison: Comparison = protocol.comparator.compare(key, self.key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal):
return MergeAction(treer).on(protocol, treel)
elif isinstance(comparison, Left):
return protocol.tree(self.on(protocol, treel), treer, key)
elif isinstance(comparison, Right):
return protocol.tree(treel, self.on(protocol, treer), key)
else:
raise TypeError
class ContainsAction(
BinaryTreeAction[
ActiveKeyType,
MetaDataType,
TreeType,
bool
],
Generic[ActiveKeyType, MetaDataType, TreeType]
):
def __init__(self, key: HashPoint[ActiveKeyType]):
assert isinstance(key, HashPoint)
self.key = key
def on_null(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
tree: TreeType
) -> bool:
return False
def on_split(
self,
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
treel: TreeType,
key: HashPoint[ActiveKeyType],
treer: TreeType
) -> bool:
comparison: Comparison = protocol.comparator.compare(key, self.key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal):
return True
elif isinstance(comparison, Left):
return self.on(protocol, treel)
elif isinstance(comparison, Right):
return self.on(protocol, treer)
else:
raise TypeError