This commit is contained in:
AF 2022-05-20 05:04:31 +03:00
parent 56f876f905
commit 3cf10ed8d4
5 changed files with 117 additions and 11 deletions

View File

@ -158,6 +158,7 @@ def main():
tree = tree.create(target) tree = tree.create(target)
print(tree.reference.str(0)) print(tree.reference.str(0))
tree = tree.add(HashPoint.of(Plain(b'NEWKEY'))) tree = tree.add(HashPoint.of(Plain(b'NEWKEY')))
tree = tree.remove(HashPoint.of(Plain(b'Q')))
print(tree.reference.str(0)) print(tree.reference.str(0))
target = tree.reference target = tree.reference
eeed = Encrypted.encrypt(target, key) eeed = Encrypted.encrypt(target, key)

View File

View File

@ -0,0 +1,62 @@
from typing import Generic, Iterable, TypeVar
from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate
from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.hashresolver import HashResolver
from rainbowadn.hashing.rainbow_factory import RainbowFactory
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
from rainbowadn.hashing.resolverorigin import ResolverOrigin
__all__ = ('Pair', 'PairFactory',)
E0Type = TypeVar('E0Type')
E1Type = TypeVar('E1Type')
class Pair(
RecursiveMentionable,
Generic[E0Type, E1Type]
):
def __init__(self, element0: HashPoint[E0Type], element1: HashPoint[E1Type]):
assert isinstance(element0, HashPoint)
assert isinstance(element1, HashPoint)
self.element0 = element0
self.element1 = element1
def points(self) -> Iterable[HashPoint]:
return [self.element0, self.element1]
def __bytes__(self):
return bytes(self.element0) + bytes(self.element1)
def __factory__(self) -> RainbowFactory['Pair[E0Type, E1Type]']:
return PairFactory(self.element0.factory, self.element1.factory)
def str(self, tab: int) -> str:
assert isinstance(tab, int)
return f'(pair)' \
f'{tabulate(tab)}{hash_point_format(self.element0, tab)}' \
f'{tabulate(tab)}{hash_point_format(self.element1, tab)}'
class PairFactory(
RainbowFactory[Pair[E0Type, E1Type]],
Generic[E0Type, E1Type]
):
def __init__(
self,
e0_factory: RainbowFactory[E0Type],
e1_factory: RainbowFactory[E1Type],
):
assert isinstance(e0_factory, RainbowFactory)
assert isinstance(e1_factory, RainbowFactory)
self.e0_factory = e0_factory
self.e1_factory = e1_factory
def from_bytes(self, source: bytes, resolver: HashResolver) -> Pair[E0Type, E1Type]:
assert isinstance(source, bytes)
assert isinstance(resolver, HashResolver)
return Pair(
ResolverOrigin(self.e0_factory, source[:HashPoint.HASH_LENGTH], resolver).hash_point(),
ResolverOrigin(self.e1_factory, source[HashPoint.HASH_LENGTH:], resolver).hash_point(),
)

View File

@ -9,7 +9,7 @@ from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, Binar
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.binary.querybinarytree import QueryBinaryTree from rainbowadn.data.collection.trees.binary.querybinarytree import QueryBinaryTree
from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Left, Replace, Right) from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Equal, Left, Replace, Right)
from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator
from rainbowadn.hashing.hashpoint import HashPoint from rainbowadn.hashing.hashpoint import HashPoint
from rainbowadn.hashing.nullability.notnull import NotNull from rainbowadn.hashing.nullability.notnull import NotNull
@ -90,6 +90,48 @@ class ActiveBinaryTree(
else: else:
return self.creation.tree(self, self, key) 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):
return treer, original
elif not self.creation.splittable(treer):
return treel, original
else:
treel, key = treel.pop()
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)
comparison: Comparison = self.comparator.compare(original, key)
assert isinstance(comparison, Comparison)
if isinstance(comparison, Equal):
return self.pop()[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]: def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]:
return KeyMetadataQueryCollection( return KeyMetadataQueryCollection(
self.protocol.empty_metadata(), self.protocol.empty_metadata(),

View File

@ -116,18 +116,19 @@ class EncryptedFactory(RainbowFactory[Encrypted[EncryptedType]], Generic[Encrypt
) )
hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else () hashpoints = tuple(decrypted.points()) if isinstance(decrypted, RecursiveMentionable) else ()
assert len(hashpoints) == resolution_size assert len(hashpoints) == resolution_size
resolution: tuple[HashPoint[Encrypted], ...] = tuple(
ResolverOrigin(
EncryptedFactory(
hashpoint.factory,
self.key
),
plain[8 + i * HashPoint.HASH_LENGTH: 8 + (i + 1) * HashPoint.HASH_LENGTH],
resolver
).hash_point() for i, hashpoint in enumerate(hashpoints)
)
encrypted.__init__( encrypted.__init__(
self.key, self.key,
tuple( resolution,
ResolverOrigin(
EncryptedFactory(
hashpoint.factory,
self.key
),
plain[8 + i * HashPoint.HASH_LENGTH: 8 + (i + 1) * HashPoint.HASH_LENGTH],
resolver
).hash_point() for i, hashpoint in enumerate(hashpoints)
),
decrypted decrypted
) )
return encrypted return encrypted