wrisbt + better bst + better blockchain
This commit is contained in:
parent
244997690d
commit
c743da7bb6
71
main.py
71
main.py
@ -1,9 +1,20 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from typing import MutableMapping
|
from typing import Any, MutableMapping
|
||||||
|
|
||||||
import nacl.signing
|
import nacl.signing
|
||||||
|
|
||||||
|
from rainbowadn.chain.blockchain import BlockChainFactory
|
||||||
|
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
|
||||||
from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory
|
from rainbowadn.chain.reduction.reductionchainmetafactory import ReductionChainMetaFactory
|
||||||
|
from rainbowadn.data.atomic.integer import Integer
|
||||||
|
from rainbowadn.data.atomic.plain import Plain
|
||||||
|
from rainbowadn.data.collection.array.array import Array
|
||||||
|
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
|
||||||
|
from rainbowadn.data.collection.trees.binary.avl import AVLBTBP
|
||||||
|
from rainbowadn.data.collection.trees.comparison.comparator import Replace
|
||||||
|
from rainbowadn.data.collection.trees.comparison.plaincomparator import PlainComparator
|
||||||
from rainbowadn.hashing.hashmentionable import HashMentionable
|
from rainbowadn.hashing.hashmentionable import HashMentionable
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
from rainbowadn.hashing.hashresolver import HashResolver
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
@ -13,6 +24,8 @@ from rainbowadn.v13.algo import MINT_CONST
|
|||||||
from rainbowadn.v13.bankchain import BankChain
|
from rainbowadn.v13.bankchain import BankChain
|
||||||
from rainbowadn.v13.subject import Subject
|
from rainbowadn.v13.subject import Subject
|
||||||
from rainbowadn.v13.transaction import CoinData, Transaction
|
from rainbowadn.v13.transaction import CoinData, Transaction
|
||||||
|
from rainbowadn.wrisbt.wrisbtchainprotocol import WrisbtChainProtocol
|
||||||
|
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
|
||||||
|
|
||||||
|
|
||||||
class DumbResolver(HashResolver):
|
class DumbResolver(HashResolver):
|
||||||
@ -37,7 +50,7 @@ class DumbResolver(HashResolver):
|
|||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main0():
|
||||||
dr = DumbResolver()
|
dr = DumbResolver()
|
||||||
bank = BankChain.empty(ReductionChainMetaFactory(), dr)
|
bank = BankChain.empty(ReductionChainMetaFactory(), dr)
|
||||||
key_0 = nacl.signing.SigningKey.generate()
|
key_0 = nacl.signing.SigningKey.generate()
|
||||||
@ -66,8 +79,58 @@ def main():
|
|||||||
bank = BankChain.from_reference(ReductionChainMetaFactory(), dr.resolve(HashPoint.of(bank.reference).loose()), dr)
|
bank = BankChain.from_reference(ReductionChainMetaFactory(), dr.resolve(HashPoint.of(bank.reference).loose()), dr)
|
||||||
print(bank)
|
print(bank)
|
||||||
print(bank.verify())
|
print(bank.verify())
|
||||||
for key, value in dr.table.items():
|
# for key, value in dr.table.items():
|
||||||
print(key.hex(), value.hex())
|
# print(key.hex(), value.hex())
|
||||||
|
|
||||||
|
|
||||||
|
def main1():
|
||||||
|
stoptime = time.process_time()
|
||||||
|
|
||||||
|
def measure(message: str):
|
||||||
|
nonlocal stoptime
|
||||||
|
now = time.process_time()
|
||||||
|
print(message, now - stoptime)
|
||||||
|
stoptime = now
|
||||||
|
|
||||||
|
dr = DumbResolver()
|
||||||
|
btree = WrisbtRoot.empty(16)
|
||||||
|
measure('init')
|
||||||
|
for _ in range(10000):
|
||||||
|
btree = btree.add(dr, HashPoint.hash(os.urandom(32)))
|
||||||
|
btree = btree.add(dr, HashPoint.hash(b'aaa'))
|
||||||
|
print(btree.contains(dr, HashPoint.hash(b'aaa')))
|
||||||
|
measure('add')
|
||||||
|
dr.save(HashPoint.of(btree))
|
||||||
|
measure('save')
|
||||||
|
btree = dr.resolve(HashPoint.of(btree).loose())
|
||||||
|
print(btree)
|
||||||
|
measure('resolve')
|
||||||
|
print(btree.height)
|
||||||
|
print(WrisbtRoot.empty(128).index(dr, HashPoint.of(btree), WrisbtRoot.empty(128)).height)
|
||||||
|
measure('index')
|
||||||
|
|
||||||
|
|
||||||
|
def main2():
|
||||||
|
dr = DumbResolver()
|
||||||
|
chain: ChainCollectionInterface[Any, Plain, Array[WrisbtRoot]] = BlockChainFactory(
|
||||||
|
WrisbtChainProtocol(dr, Plain.factory(), 2).loose()
|
||||||
|
).loose().empty().loose()
|
||||||
|
for _ in range(1000):
|
||||||
|
chain = chain.add(HashPoint.of(Plain(os.urandom(16))))
|
||||||
|
|
||||||
|
assert chain
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
|
print(dr.resolve(chain.actual_state().reference.value).height)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
dr = DumbResolver()
|
||||||
|
tree: ActiveBinaryTree[Plain, Integer] = ActiveBinaryTree.empty(
|
||||||
|
AVLBTBP(PlainComparator(dr, Replace())), Plain.factory()
|
||||||
|
)
|
||||||
|
for i in range(26):
|
||||||
|
tree = tree.add(HashPoint.of(Plain(bytes([ord('A') + i]))))
|
||||||
|
print(tree.reference.str(dr, 0))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
232
rainbowadn/chain/blockchain.py
Normal file
232
rainbowadn/chain/blockchain.py
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.block import Block, BlockFactory
|
||||||
|
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
|
||||||
|
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
|
||||||
|
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.nullability.notnull import NotNull
|
||||||
|
from rainbowadn.hashing.nullability.null import Null
|
||||||
|
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
|
||||||
|
__all__ = ('BlockChain', 'BlockChainFactory',)
|
||||||
|
|
||||||
|
HeaderType = TypeVar('HeaderType')
|
||||||
|
StateType = TypeVar('StateType')
|
||||||
|
ActualStateType = TypeVar('ActualStateType')
|
||||||
|
|
||||||
|
|
||||||
|
class BlockChain(
|
||||||
|
ChainCollectionInterface[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
HeaderType,
|
||||||
|
ActualStateType
|
||||||
|
],
|
||||||
|
Generic[HeaderType, StateType, ActualStateType],
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
reference: NullableReference[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
]
|
||||||
|
],
|
||||||
|
protocol: BlockChainProtocol[HeaderType, StateType, ActualStateType],
|
||||||
|
):
|
||||||
|
assert isinstance(reference, NullableReference)
|
||||||
|
assert isinstance(protocol, BlockChainProtocol)
|
||||||
|
super().__init__(reference, protocol.resolver)
|
||||||
|
self.protocol = protocol
|
||||||
|
|
||||||
|
def factory(self) -> ChainCollectionFactory[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
HeaderType,
|
||||||
|
ActualStateType
|
||||||
|
]:
|
||||||
|
return BlockChainFactory(self.protocol)
|
||||||
|
|
||||||
|
def add(
|
||||||
|
self,
|
||||||
|
header: HashPoint[HeaderType]
|
||||||
|
) -> ChainCollectionInterface[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
HeaderType,
|
||||||
|
ActualStateType
|
||||||
|
]:
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
return self.factory().from_reference(
|
||||||
|
NullableReference.off(
|
||||||
|
self._add(header)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def state(
|
||||||
|
self
|
||||||
|
) -> NullableReference[
|
||||||
|
StateType
|
||||||
|
]:
|
||||||
|
if isinstance(self.reference.reference, Null):
|
||||||
|
return NullableReference(
|
||||||
|
Null(),
|
||||||
|
self.protocol.state_factory
|
||||||
|
)
|
||||||
|
elif isinstance(self.reference.reference, NotNull):
|
||||||
|
block: Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
] = self.resolver.resolve(self.reference.reference.value)
|
||||||
|
assert isinstance(block, Block)
|
||||||
|
return NullableReference.of(block.state)
|
||||||
|
else:
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
def _add(
|
||||||
|
self,
|
||||||
|
header: HashPoint[HeaderType]
|
||||||
|
) -> Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
]:
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
return Block(
|
||||||
|
self.reference,
|
||||||
|
header,
|
||||||
|
self.protocol.state_protocol.derive(
|
||||||
|
self.state(),
|
||||||
|
header,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def previous(
|
||||||
|
self
|
||||||
|
) -> ChainCollectionInterface[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
HeaderType,
|
||||||
|
ActualStateType
|
||||||
|
]:
|
||||||
|
assert isinstance(self.reference.reference, NotNull)
|
||||||
|
block: Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
] = self.resolver.resolve(self.reference.reference.value)
|
||||||
|
assert isinstance(block, Block)
|
||||||
|
return self.factory().from_reference(block.previous)
|
||||||
|
|
||||||
|
def verify(self) -> bool:
|
||||||
|
if isinstance(self.reference.reference, Null):
|
||||||
|
return True
|
||||||
|
elif isinstance(self.reference.reference, NotNull):
|
||||||
|
return self.verify_link(
|
||||||
|
self.previous().reference
|
||||||
|
) and self.previous().verify()
|
||||||
|
else:
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
def _verify_link(
|
||||||
|
self,
|
||||||
|
block: Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
previous: NullableReference[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
]
|
||||||
|
]
|
||||||
|
) -> bool:
|
||||||
|
assert isinstance(block, Block)
|
||||||
|
assert isinstance(previous, NullableReference)
|
||||||
|
assert block.previous == previous
|
||||||
|
previous_chain = self.factory().from_reference(previous)
|
||||||
|
assert isinstance(previous_chain, BlockChain)
|
||||||
|
return self.protocol.state_protocol.verify(
|
||||||
|
previous_chain.state(),
|
||||||
|
block.header,
|
||||||
|
block.state,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
|
||||||
|
return self.protocol.actual_state_factory()
|
||||||
|
|
||||||
|
def _actual_state(
|
||||||
|
self,
|
||||||
|
block: Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
]
|
||||||
|
) -> HashPoint[ActualStateType]:
|
||||||
|
assert isinstance(block, Block)
|
||||||
|
return self.protocol.actual_state(self.resolver.resolve(block.state))
|
||||||
|
|
||||||
|
def loose(self) -> ChainCollectionInterface[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
HeaderType,
|
||||||
|
ActualStateType
|
||||||
|
]:
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class BlockChainFactory(
|
||||||
|
ChainCollectionFactory[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
HeaderType,
|
||||||
|
ActualStateType
|
||||||
|
],
|
||||||
|
Generic[HeaderType, StateType, ActualStateType]
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol: BlockChainProtocol[HeaderType, StateType, ActualStateType],
|
||||||
|
):
|
||||||
|
assert isinstance(protocol, BlockChainProtocol)
|
||||||
|
self.protocol = protocol
|
||||||
|
|
||||||
|
def empty(self) -> BlockChain[HeaderType, StateType, ActualStateType]:
|
||||||
|
return BlockChain(
|
||||||
|
NullableReference(
|
||||||
|
Null(),
|
||||||
|
BlockFactory(
|
||||||
|
self.protocol.header_factory,
|
||||||
|
self.protocol.state_factory
|
||||||
|
)
|
||||||
|
),
|
||||||
|
self.protocol
|
||||||
|
)
|
||||||
|
|
||||||
|
def from_reference(
|
||||||
|
self,
|
||||||
|
reference: NullableReference[
|
||||||
|
Block[
|
||||||
|
HeaderType,
|
||||||
|
StateType
|
||||||
|
],
|
||||||
|
]
|
||||||
|
) -> BlockChain[
|
||||||
|
HeaderType, StateType, ActualStateType
|
||||||
|
]:
|
||||||
|
assert isinstance(reference, NullableReference)
|
||||||
|
return BlockChain(
|
||||||
|
reference,
|
||||||
|
self.protocol
|
||||||
|
)
|
43
rainbowadn/chain/blockchainprotocol.py
Normal file
43
rainbowadn/chain/blockchainprotocol.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
|
||||||
|
__all__ = ('BlockChainProtocol',)
|
||||||
|
|
||||||
|
HeaderType = TypeVar('HeaderType')
|
||||||
|
StateType = TypeVar('StateType')
|
||||||
|
ActualStateType = TypeVar('ActualStateType')
|
||||||
|
|
||||||
|
|
||||||
|
class BlockChainProtocol(
|
||||||
|
Generic[HeaderType, StateType, ActualStateType],
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol: ActiveStateProtocol[HeaderType, StateType],
|
||||||
|
header_factory: RainbowFactory[StateType],
|
||||||
|
state_factory: RainbowFactory[StateType]
|
||||||
|
):
|
||||||
|
assert isinstance(protocol, ActiveStateProtocol)
|
||||||
|
assert isinstance(header_factory, RainbowFactory)
|
||||||
|
assert isinstance(state_factory, RainbowFactory)
|
||||||
|
self.state_protocol = protocol
|
||||||
|
self.header_factory = header_factory
|
||||||
|
self.state_factory = state_factory
|
||||||
|
self.resolver = protocol.resolver
|
||||||
|
assert isinstance(self.resolver, HashResolver)
|
||||||
|
|
||||||
|
def actual_state_factory(self) -> RainbowFactory[ActualStateType]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def actual_state(
|
||||||
|
self,
|
||||||
|
state: StateType
|
||||||
|
) -> HashPoint[ActualStateType]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def loose(self) -> 'BlockChainProtocol[HeaderType, StateType, ActualStateType]':
|
||||||
|
return self
|
@ -53,17 +53,17 @@ class BlockCollectionInterface(
|
|||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
def _base_state_factory(self) -> RainbowFactory[ActualStateType]:
|
def _actual_state_factory(self) -> RainbowFactory[ActualStateType]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def _base_state(self, block: BlockType) -> HashPoint[ActualStateType]:
|
def _actual_state(self, block: BlockType) -> HashPoint[ActualStateType]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def base_state(self) -> NullableReference[ActualStateType]:
|
def actual_state(self) -> NullableReference[ActualStateType]:
|
||||||
if isinstance(self.reference.reference, Null):
|
if isinstance(self.reference.reference, Null):
|
||||||
return NullableReference(Null(), self._base_state_factory())
|
return NullableReference(Null(), self._actual_state_factory())
|
||||||
elif isinstance(self.reference.reference, NotNull):
|
elif isinstance(self.reference.reference, NotNull):
|
||||||
return NullableReference.of(self._base_state(self.resolver.resolve(self.reference.reference.value)))
|
return NullableReference.of(self._actual_state(self.resolver.resolve(self.reference.reference.value)))
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
|
@ -19,3 +19,6 @@ class ChainCollectionFactory(Generic[BlockType, HeaderType, ActualStateType]):
|
|||||||
reference: NullableReference[BlockType]
|
reference: NullableReference[BlockType]
|
||||||
) -> ChainCollectionInterface[BlockType, HeaderType, ActualStateType]:
|
) -> ChainCollectionInterface[BlockType, HeaderType, ActualStateType]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def loose(self) -> 'ChainCollectionFactory[BlockType, HeaderType, ActualStateType]':
|
||||||
|
return self
|
||||||
|
@ -1,306 +0,0 @@
|
|||||||
from typing import Generic, TypeVar
|
|
||||||
|
|
||||||
from rainbowadn.chain.block import Block, BlockFactory
|
|
||||||
from rainbowadn.chain.blockcollectioninterface import BlockCollectionInterface
|
|
||||||
from rainbowadn.chain.chaincollectioninterface import ChainCollectionInterface
|
|
||||||
from rainbowadn.chain.reduction.reduction import Reduction, ReductionFactory
|
|
||||||
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
|
|
||||||
from rainbowadn.chain.reduction.reductionstageprotocol import ReductionStageProtocol
|
|
||||||
from rainbowadn.chain.stages.stage import StageStageFactory, StateStage, StateStageFactory
|
|
||||||
from rainbowadn.chain.stages.stageprotocol import StageProtocol
|
|
||||||
from rainbowadn.chain.stages.stagestateprotocol import StageStateProtocol
|
|
||||||
from rainbowadn.chain.states.stateprotocol import StateProtocol
|
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
|
||||||
from rainbowadn.hashing.nullability.notnull import NotNull
|
|
||||||
from rainbowadn.hashing.nullability.null import Null
|
|
||||||
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
|
||||||
|
|
||||||
__all__ = ('ReductionChain',)
|
|
||||||
|
|
||||||
ReductorType = TypeVar('ReductorType')
|
|
||||||
AccumulatorType = TypeVar('AccumulatorType')
|
|
||||||
|
|
||||||
|
|
||||||
class ReductionChain(
|
|
||||||
ChainCollectionInterface[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType
|
|
||||||
],
|
|
||||||
Generic[ReductorType, AccumulatorType]
|
|
||||||
):
|
|
||||||
def _verify_link(
|
|
||||||
self,
|
|
||||||
block: Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
previous: NullableReference[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
) -> bool:
|
|
||||||
assert isinstance(block, Block)
|
|
||||||
assert isinstance(previous, NullableReference)
|
|
||||||
assert block.previous == previous
|
|
||||||
previous_chain = ReductionChain(previous, self.reductor_factory, self.accumulator_factory, self.protocol)
|
|
||||||
assert isinstance(previous_chain, BlockCollectionInterface)
|
|
||||||
state_protocol = StageStateProtocol(self.resolver)
|
|
||||||
assert isinstance(state_protocol, StateProtocol)
|
|
||||||
return state_protocol.verify(
|
|
||||||
previous_chain.state(),
|
|
||||||
block.header,
|
|
||||||
block.state,
|
|
||||||
)
|
|
||||||
|
|
||||||
def _base_state_factory(self) -> RainbowFactory[AccumulatorType]:
|
|
||||||
return self.accumulator_factory
|
|
||||||
|
|
||||||
def _base_state(
|
|
||||||
self,
|
|
||||||
block: Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
) -> HashPoint[AccumulatorType]:
|
|
||||||
assert isinstance(block, Block)
|
|
||||||
return self.resolver.resolve(block.state).state
|
|
||||||
|
|
||||||
def add(
|
|
||||||
self,
|
|
||||||
header: HashPoint[ReductorType]
|
|
||||||
) -> 'ReductionChain[ReductorType, AccumulatorType]':
|
|
||||||
assert isinstance(header, HashPoint)
|
|
||||||
return ReductionChain(
|
|
||||||
NullableReference.off(
|
|
||||||
self._add(header)
|
|
||||||
),
|
|
||||||
header.factory,
|
|
||||||
self.accumulator_factory,
|
|
||||||
self.protocol
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
reference: NullableReference[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
reductor_factory: RainbowFactory[ReductorType],
|
|
||||||
accumulator_factory: RainbowFactory[AccumulatorType],
|
|
||||||
protocol: ReductionProtocol[ReductorType, AccumulatorType]
|
|
||||||
):
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
assert isinstance(reductor_factory, RainbowFactory)
|
|
||||||
assert isinstance(accumulator_factory, RainbowFactory)
|
|
||||||
assert isinstance(protocol, ReductionProtocol)
|
|
||||||
super().__init__(reference, protocol.resolver)
|
|
||||||
self.reductor_factory = reductor_factory
|
|
||||||
self.accumulator_factory = accumulator_factory
|
|
||||||
self.protocol = protocol
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _state_stage_factory(
|
|
||||||
cls,
|
|
||||||
reductor_factory: RainbowFactory[ReductorType],
|
|
||||||
accumulator_factory: RainbowFactory[AccumulatorType],
|
|
||||||
protocol: ReductionProtocol[ReductorType, AccumulatorType]
|
|
||||||
) -> RainbowFactory[
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]:
|
|
||||||
assert isinstance(reductor_factory, RainbowFactory)
|
|
||||||
assert isinstance(accumulator_factory, RainbowFactory)
|
|
||||||
assert isinstance(protocol, ReductionProtocol)
|
|
||||||
stage_protocol = ReductionStageProtocol(protocol)
|
|
||||||
assert isinstance(stage_protocol, StageProtocol)
|
|
||||||
return StateStageFactory(
|
|
||||||
stage_protocol,
|
|
||||||
StageStageFactory(
|
|
||||||
stage_protocol,
|
|
||||||
ReductionFactory(
|
|
||||||
reductor_factory,
|
|
||||||
accumulator_factory
|
|
||||||
)
|
|
||||||
),
|
|
||||||
accumulator_factory
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _block_factory(
|
|
||||||
cls,
|
|
||||||
reductor_factory: RainbowFactory[ReductorType],
|
|
||||||
accumulator_factory: RainbowFactory[AccumulatorType],
|
|
||||||
protocol: ReductionProtocol[ReductorType, AccumulatorType]
|
|
||||||
) -> RainbowFactory[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]:
|
|
||||||
assert isinstance(reductor_factory, RainbowFactory)
|
|
||||||
assert isinstance(accumulator_factory, RainbowFactory)
|
|
||||||
assert isinstance(protocol, ReductionProtocol)
|
|
||||||
return BlockFactory(
|
|
||||||
reductor_factory,
|
|
||||||
cls._state_stage_factory(
|
|
||||||
reductor_factory,
|
|
||||||
accumulator_factory,
|
|
||||||
protocol
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def empty(
|
|
||||||
cls,
|
|
||||||
reductor_factory: RainbowFactory[ReductorType],
|
|
||||||
accumulator_factory: RainbowFactory[AccumulatorType],
|
|
||||||
protocol: ReductionProtocol[ReductorType, AccumulatorType]
|
|
||||||
) -> 'ReductionChain[ReductorType, AccumulatorType]':
|
|
||||||
assert isinstance(reductor_factory, RainbowFactory)
|
|
||||||
assert isinstance(accumulator_factory, RainbowFactory)
|
|
||||||
assert isinstance(protocol, ReductionProtocol)
|
|
||||||
return cls(
|
|
||||||
NullableReference(
|
|
||||||
Null(),
|
|
||||||
cls._block_factory(
|
|
||||||
reductor_factory,
|
|
||||||
accumulator_factory,
|
|
||||||
protocol
|
|
||||||
)
|
|
||||||
),
|
|
||||||
reductor_factory,
|
|
||||||
accumulator_factory,
|
|
||||||
protocol
|
|
||||||
)
|
|
||||||
|
|
||||||
def state(
|
|
||||||
self
|
|
||||||
) -> NullableReference[
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]:
|
|
||||||
if isinstance(self.reference.reference, Null):
|
|
||||||
return NullableReference(
|
|
||||||
Null(),
|
|
||||||
self._state_stage_factory(
|
|
||||||
self.reductor_factory,
|
|
||||||
self.accumulator_factory,
|
|
||||||
self.protocol
|
|
||||||
)
|
|
||||||
)
|
|
||||||
elif isinstance(self.reference.reference, NotNull):
|
|
||||||
block: Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
] = self.resolver.resolve(self.reference.reference.value)
|
|
||||||
assert isinstance(block, Block)
|
|
||||||
return NullableReference.of(block.state)
|
|
||||||
else:
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
def _add(
|
|
||||||
self,
|
|
||||||
reductor: HashPoint[ReductorType]
|
|
||||||
) -> Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
]:
|
|
||||||
assert isinstance(reductor, HashPoint)
|
|
||||||
stage_protocol = ReductionStageProtocol(self.protocol)
|
|
||||||
assert isinstance(stage_protocol, StageProtocol)
|
|
||||||
return Block(
|
|
||||||
self.reference,
|
|
||||||
reductor,
|
|
||||||
stage_protocol.derive_full(
|
|
||||||
self.state(),
|
|
||||||
reductor,
|
|
||||||
self.accumulator_factory,
|
|
||||||
ReductionFactory(reductor.factory, self.accumulator_factory)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def previous(
|
|
||||||
self
|
|
||||||
):
|
|
||||||
assert isinstance(self.reference.reference, NotNull)
|
|
||||||
block: Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
] = self.resolver.resolve(self.reference.reference.value)
|
|
||||||
assert isinstance(block, Block)
|
|
||||||
return ReductionChain(block.previous, self.reductor_factory, self.accumulator_factory, self.protocol)
|
|
||||||
|
|
||||||
def verify(self) -> bool:
|
|
||||||
if isinstance(self.reference.reference, Null):
|
|
||||||
return True
|
|
||||||
elif isinstance(self.reference.reference, NotNull):
|
|
||||||
return self.verify_link(
|
|
||||||
self.previous().reference
|
|
||||||
) and self.previous().verify()
|
|
||||||
else:
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
def loose(self) -> ChainCollectionInterface[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType
|
|
||||||
]:
|
|
||||||
return self
|
|
@ -1,73 +0,0 @@
|
|||||||
from typing import Generic, TypeVar
|
|
||||||
|
|
||||||
from rainbowadn.chain.block import Block
|
|
||||||
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
|
|
||||||
from rainbowadn.chain.reduction.reduction import Reduction
|
|
||||||
from rainbowadn.chain.reduction.reductionchain import ReductionChain
|
|
||||||
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
|
|
||||||
from rainbowadn.chain.stages.stage import StateStage
|
|
||||||
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
|
||||||
|
|
||||||
__all__ = ('ReductionChainFactory',)
|
|
||||||
|
|
||||||
ReductorType = TypeVar('ReductorType')
|
|
||||||
AccumulatorType = TypeVar('AccumulatorType')
|
|
||||||
|
|
||||||
|
|
||||||
class ReductionChainFactory(
|
|
||||||
ChainCollectionFactory[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType
|
|
||||||
],
|
|
||||||
Generic[ReductorType, AccumulatorType]
|
|
||||||
):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
reductor_factory: RainbowFactory[ReductorType],
|
|
||||||
accumulator_factory: RainbowFactory[AccumulatorType],
|
|
||||||
protocol: ReductionProtocol[ReductorType, AccumulatorType],
|
|
||||||
):
|
|
||||||
assert isinstance(reductor_factory, RainbowFactory)
|
|
||||||
assert isinstance(accumulator_factory, RainbowFactory)
|
|
||||||
assert isinstance(protocol, ReductionProtocol)
|
|
||||||
self.reductor_factory = reductor_factory
|
|
||||||
self.accumulator_factory = accumulator_factory
|
|
||||||
self.protocol = protocol
|
|
||||||
|
|
||||||
def empty(self) -> ReductionChain[ReductorType, AccumulatorType]:
|
|
||||||
return ReductionChain.empty(
|
|
||||||
self.reductor_factory,
|
|
||||||
self.accumulator_factory,
|
|
||||||
self.protocol,
|
|
||||||
)
|
|
||||||
|
|
||||||
def from_reference(
|
|
||||||
self, reference: NullableReference[
|
|
||||||
Block[
|
|
||||||
ReductorType,
|
|
||||||
StateStage[
|
|
||||||
ReductorType,
|
|
||||||
AccumulatorType,
|
|
||||||
Reduction[ReductorType, AccumulatorType]
|
|
||||||
]
|
|
||||||
],
|
|
||||||
]
|
|
||||||
) -> ReductionChain[
|
|
||||||
ReductorType, AccumulatorType
|
|
||||||
]:
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
return ReductionChain(
|
|
||||||
reference,
|
|
||||||
self.reductor_factory,
|
|
||||||
self.accumulator_factory,
|
|
||||||
self.protocol,
|
|
||||||
)
|
|
@ -2,8 +2,10 @@ from typing import Generic, TypeVar
|
|||||||
|
|
||||||
from rainbowadn.chain.abstractreductionchainmetafactory import AbstractReductionChainMetaFactory
|
from rainbowadn.chain.abstractreductionchainmetafactory import AbstractReductionChainMetaFactory
|
||||||
from rainbowadn.chain.block import Block
|
from rainbowadn.chain.block import Block
|
||||||
|
from rainbowadn.chain.blockchain import BlockChainFactory
|
||||||
|
from rainbowadn.chain.chaincollectionfactory import ChainCollectionFactory
|
||||||
from rainbowadn.chain.reduction.reduction import Reduction
|
from rainbowadn.chain.reduction.reduction import Reduction
|
||||||
from rainbowadn.chain.reduction.reductionchainfactory import ReductionChainFactory
|
from rainbowadn.chain.reduction.reductionchainprotocol import ReductionChainProtocol
|
||||||
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
|
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
|
||||||
from rainbowadn.chain.stages.stage import StateStage
|
from rainbowadn.chain.stages.stage import StateStage
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
@ -34,9 +36,25 @@ class ReductionChainMetaFactory(
|
|||||||
reductor_factory: RainbowFactory[ReductorType],
|
reductor_factory: RainbowFactory[ReductorType],
|
||||||
accumulator_factory: RainbowFactory[AccumulatorType],
|
accumulator_factory: RainbowFactory[AccumulatorType],
|
||||||
protocol: ReductionProtocol[ReductorType, AccumulatorType],
|
protocol: ReductionProtocol[ReductorType, AccumulatorType],
|
||||||
):
|
) -> ChainCollectionFactory[
|
||||||
return ReductionChainFactory(
|
Block[
|
||||||
|
ReductorType,
|
||||||
|
StateStage[
|
||||||
|
ReductorType,
|
||||||
|
AccumulatorType,
|
||||||
|
Reduction[ReductorType, AccumulatorType]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
ReductorType,
|
||||||
|
AccumulatorType
|
||||||
|
]:
|
||||||
|
assert isinstance(reductor_factory, RainbowFactory)
|
||||||
|
assert isinstance(accumulator_factory, RainbowFactory)
|
||||||
|
assert isinstance(protocol, ReductionProtocol)
|
||||||
|
return BlockChainFactory(
|
||||||
|
ReductionChainProtocol(
|
||||||
|
protocol,
|
||||||
reductor_factory,
|
reductor_factory,
|
||||||
accumulator_factory,
|
accumulator_factory,
|
||||||
protocol,
|
)
|
||||||
)
|
)
|
||||||
|
82
rainbowadn/chain/reduction/reductionchainprotocol.py
Normal file
82
rainbowadn/chain/reduction/reductionchainprotocol.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
|
||||||
|
from rainbowadn.chain.reduction.reduction import Reduction, ReductionFactory
|
||||||
|
from rainbowadn.chain.reduction.reductionprotocol import ReductionProtocol
|
||||||
|
from rainbowadn.chain.reduction.reductionstageprotocol import ReductionStageProtocol
|
||||||
|
from rainbowadn.chain.stages.derivation.activestageprotocol import ActiveStageProtocol
|
||||||
|
from rainbowadn.chain.stages.derivation.activestagestateprotocol import ActiveStageStateProtocol
|
||||||
|
from rainbowadn.chain.stages.stage import StateStage, StateStageFactory
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
|
||||||
|
__all__ = ('ReductionChainProtocol',)
|
||||||
|
|
||||||
|
ReductorType = TypeVar('ReductorType')
|
||||||
|
AccumulatorType = TypeVar('AccumulatorType')
|
||||||
|
|
||||||
|
|
||||||
|
class ReductionChainProtocol(
|
||||||
|
BlockChainProtocol[
|
||||||
|
ReductorType,
|
||||||
|
StateStage[
|
||||||
|
ReductorType,
|
||||||
|
AccumulatorType,
|
||||||
|
Reduction[ReductorType, AccumulatorType]
|
||||||
|
],
|
||||||
|
AccumulatorType
|
||||||
|
]
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol: ReductionProtocol[ReductorType, AccumulatorType],
|
||||||
|
reductor_factory: RainbowFactory[ReductorType],
|
||||||
|
accumulator_factory: RainbowFactory[AccumulatorType],
|
||||||
|
):
|
||||||
|
assert isinstance(protocol, ReductionProtocol)
|
||||||
|
assert isinstance(reductor_factory, RainbowFactory)
|
||||||
|
assert isinstance(accumulator_factory, RainbowFactory)
|
||||||
|
|
||||||
|
reduction_factory: RainbowFactory[
|
||||||
|
Reduction[ReductorType, AccumulatorType]
|
||||||
|
] = ReductionFactory(
|
||||||
|
reductor_factory, accumulator_factory
|
||||||
|
)
|
||||||
|
assert isinstance(reduction_factory, RainbowFactory)
|
||||||
|
stage_protocol: ActiveStageProtocol[
|
||||||
|
ReductorType,
|
||||||
|
AccumulatorType,
|
||||||
|
Reduction[ReductorType, AccumulatorType]
|
||||||
|
] = ReductionStageProtocol(protocol)
|
||||||
|
assert isinstance(stage_protocol, ActiveStageProtocol)
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
ActiveStageStateProtocol(
|
||||||
|
stage_protocol,
|
||||||
|
reduction_factory,
|
||||||
|
accumulator_factory,
|
||||||
|
),
|
||||||
|
reductor_factory,
|
||||||
|
StateStageFactory(
|
||||||
|
stage_protocol,
|
||||||
|
reduction_factory,
|
||||||
|
accumulator_factory
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.reductor_factory = reductor_factory
|
||||||
|
self.accumulator_factory = accumulator_factory
|
||||||
|
|
||||||
|
def actual_state_factory(self) -> RainbowFactory[AccumulatorType]:
|
||||||
|
return self.accumulator_factory
|
||||||
|
|
||||||
|
def actual_state(
|
||||||
|
self,
|
||||||
|
state: StateStage[
|
||||||
|
ReductorType,
|
||||||
|
AccumulatorType,
|
||||||
|
Reduction[ReductorType, AccumulatorType]
|
||||||
|
]
|
||||||
|
) -> HashPoint[AccumulatorType]:
|
||||||
|
assert isinstance(state, StateStage)
|
||||||
|
return state.state
|
@ -56,8 +56,10 @@ class ActiveStageProtocol(
|
|||||||
def _derive_cycle(
|
def _derive_cycle(
|
||||||
self,
|
self,
|
||||||
stage: StageStage[HeaderType, BaseStateType, StageType],
|
stage: StageStage[HeaderType, BaseStateType, StageType],
|
||||||
|
stage_factory: RainbowFactory[StageType]
|
||||||
) -> HashPoint[StateStage[HeaderType, BaseStateType, StageType]]:
|
) -> HashPoint[StateStage[HeaderType, BaseStateType, StageType]]:
|
||||||
assert isinstance(stage, StageStage)
|
assert isinstance(stage, StageStage)
|
||||||
|
assert isinstance(stage_factory, RainbowFactory)
|
||||||
while True:
|
while True:
|
||||||
derived = self.derive_stage_or_state(stage.stage)
|
derived = self.derive_stage_or_state(stage.stage)
|
||||||
assert isinstance(derived, Derived)
|
assert isinstance(derived, Derived)
|
||||||
@ -65,7 +67,7 @@ class ActiveStageProtocol(
|
|||||||
stage = StageStage(self, NullableReference.off(stage), derived.stage)
|
stage = StageStage(self, NullableReference.off(stage), derived.stage)
|
||||||
assert isinstance(stage, StageStage)
|
assert isinstance(stage, StageStage)
|
||||||
elif isinstance(derived, DerivedState):
|
elif isinstance(derived, DerivedState):
|
||||||
return HashPoint.of(StateStage(self, HashPoint.of(stage), derived.state))
|
return HashPoint.of(StateStage(self, HashPoint.of(stage), derived.state, stage_factory))
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
@ -109,7 +111,8 @@ class ActiveStageProtocol(
|
|||||||
),
|
),
|
||||||
header,
|
header,
|
||||||
stage_factory
|
stage_factory
|
||||||
)
|
),
|
||||||
|
stage_factory
|
||||||
)
|
)
|
||||||
|
|
||||||
def verify_header(
|
def verify_header(
|
||||||
|
@ -0,0 +1,91 @@
|
|||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.stages.derivation.activestageprotocol import ActiveStageProtocol
|
||||||
|
from rainbowadn.chain.stages.stage import StateStage
|
||||||
|
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
|
||||||
|
__all__ = ('ActiveStageStateProtocol',)
|
||||||
|
|
||||||
|
HeaderType = TypeVar('HeaderType')
|
||||||
|
BaseStateType = TypeVar('BaseStateType')
|
||||||
|
StageType = TypeVar('StageType')
|
||||||
|
|
||||||
|
|
||||||
|
class ActiveStageStateProtocol(
|
||||||
|
ActiveStateProtocol[
|
||||||
|
HeaderType,
|
||||||
|
StateStage[
|
||||||
|
HeaderType,
|
||||||
|
BaseStateType,
|
||||||
|
StageType
|
||||||
|
]
|
||||||
|
]
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol: ActiveStageProtocol,
|
||||||
|
stage_factory: RainbowFactory[StageType],
|
||||||
|
base_state_factory: RainbowFactory[BaseStateType],
|
||||||
|
):
|
||||||
|
assert isinstance(protocol, ActiveStageProtocol)
|
||||||
|
assert isinstance(stage_factory, RainbowFactory)
|
||||||
|
assert isinstance(base_state_factory, RainbowFactory)
|
||||||
|
super().__init__(protocol.resolver)
|
||||||
|
self.protocol = protocol
|
||||||
|
self.stage_factory = stage_factory
|
||||||
|
self.base_state_factory = base_state_factory
|
||||||
|
|
||||||
|
def _initial_state(self) -> HashPoint[
|
||||||
|
StateStage[
|
||||||
|
HeaderType,
|
||||||
|
BaseStateType,
|
||||||
|
StageType
|
||||||
|
]
|
||||||
|
]:
|
||||||
|
raise TypeError('use .derive()')
|
||||||
|
|
||||||
|
def _derive(
|
||||||
|
self,
|
||||||
|
previous: HashPoint[StateStage[
|
||||||
|
HeaderType,
|
||||||
|
BaseStateType,
|
||||||
|
StageType
|
||||||
|
]],
|
||||||
|
header: HashPoint[HeaderType]
|
||||||
|
) -> HashPoint[
|
||||||
|
StateStage[
|
||||||
|
HeaderType,
|
||||||
|
BaseStateType,
|
||||||
|
StageType
|
||||||
|
]
|
||||||
|
]:
|
||||||
|
raise TypeError('use .derive()')
|
||||||
|
|
||||||
|
def derive(
|
||||||
|
self,
|
||||||
|
previous: NullableReference[
|
||||||
|
StateStage[
|
||||||
|
HeaderType,
|
||||||
|
BaseStateType,
|
||||||
|
StageType
|
||||||
|
]
|
||||||
|
],
|
||||||
|
header: HashPoint[HeaderType],
|
||||||
|
) -> HashPoint[
|
||||||
|
StateStage[
|
||||||
|
HeaderType,
|
||||||
|
BaseStateType,
|
||||||
|
StageType
|
||||||
|
]
|
||||||
|
]:
|
||||||
|
assert isinstance(previous, NullableReference)
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
return self.protocol.derive_full(
|
||||||
|
previous,
|
||||||
|
header,
|
||||||
|
self.base_state_factory,
|
||||||
|
self.stage_factory
|
||||||
|
)
|
@ -143,14 +143,17 @@ class StateStage(
|
|||||||
self,
|
self,
|
||||||
protocol: StageProtocol[HeaderType, BaseStateType, StageType],
|
protocol: StageProtocol[HeaderType, BaseStateType, StageType],
|
||||||
previous: HashPoint[StageStage[HeaderType, BaseStateType, StageType]],
|
previous: HashPoint[StageStage[HeaderType, BaseStateType, StageType]],
|
||||||
state: HashPoint[BaseStateType]
|
state: HashPoint[BaseStateType],
|
||||||
|
stage_factory: RainbowFactory[StageType]
|
||||||
):
|
):
|
||||||
assert isinstance(protocol, StageProtocol)
|
assert isinstance(protocol, StageProtocol)
|
||||||
assert isinstance(previous, HashPoint)
|
assert isinstance(previous, HashPoint)
|
||||||
assert isinstance(state, HashPoint)
|
assert isinstance(state, HashPoint)
|
||||||
|
assert isinstance(stage_factory, RainbowFactory)
|
||||||
super().__init__(protocol)
|
super().__init__(protocol)
|
||||||
self.previous = previous
|
self.previous = previous
|
||||||
self.state = state
|
self.state = state
|
||||||
|
self.stage_factory = stage_factory
|
||||||
|
|
||||||
def verify(
|
def verify(
|
||||||
self,
|
self,
|
||||||
@ -181,7 +184,7 @@ class StateStage(
|
|||||||
def __factory__(self) -> RainbowFactory['StateStage[HeaderType, BaseStateType, StageType]']:
|
def __factory__(self) -> RainbowFactory['StateStage[HeaderType, BaseStateType, StageType]']:
|
||||||
return StateStageFactory(
|
return StateStageFactory(
|
||||||
self.protocol,
|
self.protocol,
|
||||||
self.previous.factory,
|
self.stage_factory,
|
||||||
self.state.factory
|
self.state.factory
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -196,20 +199,27 @@ class StateStageFactory(RainbowFactory[StateStage[HeaderType, BaseStateType, Sta
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
protocol: StageProtocol[HeaderType, BaseStateType, StageType],
|
protocol: StageProtocol[HeaderType, BaseStateType, StageType],
|
||||||
stage_stage_factory: RainbowFactory[StageStage[HeaderType, BaseStateType, StageType]],
|
stage_factory: RainbowFactory[StageType],
|
||||||
state_factory: RainbowFactory[BaseStateType]
|
state_factory: RainbowFactory[BaseStateType]
|
||||||
):
|
):
|
||||||
assert isinstance(protocol, StageProtocol)
|
assert isinstance(protocol, StageProtocol)
|
||||||
assert isinstance(stage_stage_factory, RainbowFactory)
|
assert isinstance(stage_factory, RainbowFactory)
|
||||||
assert isinstance(state_factory, RainbowFactory)
|
assert isinstance(state_factory, RainbowFactory)
|
||||||
self.protocol = protocol
|
self.protocol = protocol
|
||||||
self.stage_stage_factory = stage_stage_factory
|
self.stage_factory = stage_factory
|
||||||
self.state_factory = state_factory
|
self.state_factory = state_factory
|
||||||
|
|
||||||
def from_bytes(self, source: bytes) -> StateStage[HeaderType, BaseStateType, StageType]:
|
def from_bytes(self, source: bytes) -> StateStage[HeaderType, BaseStateType, StageType]:
|
||||||
assert isinstance(source, bytes)
|
assert isinstance(source, bytes)
|
||||||
return StateStage(
|
return StateStage(
|
||||||
self.protocol,
|
self.protocol,
|
||||||
HashPoint(self.stage_stage_factory, source[:HashPoint.HASH_LENGTH], Null()),
|
HashPoint(
|
||||||
|
StageStageFactory(
|
||||||
|
self.protocol,
|
||||||
|
self.stage_factory
|
||||||
|
),
|
||||||
|
source[:HashPoint.HASH_LENGTH], Null()
|
||||||
|
),
|
||||||
HashPoint(self.state_factory, source[HashPoint.HASH_LENGTH:], Null()),
|
HashPoint(self.state_factory, source[HashPoint.HASH_LENGTH:], Null()),
|
||||||
|
self.stage_factory
|
||||||
)
|
)
|
||||||
|
52
rainbowadn/chain/states/activestateprotocol.py
Normal file
52
rainbowadn/chain/states/activestateprotocol.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.states.stateprotocol import StateProtocol
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.nullability.notnull import NotNull
|
||||||
|
from rainbowadn.hashing.nullability.null import Null
|
||||||
|
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
||||||
|
|
||||||
|
__all__ = ('ActiveStateProtocol',)
|
||||||
|
|
||||||
|
HeaderType = TypeVar('HeaderType')
|
||||||
|
StateType = TypeVar('StateType')
|
||||||
|
|
||||||
|
|
||||||
|
class ActiveStateProtocol(StateProtocol[HeaderType, StateType]):
|
||||||
|
def verify(
|
||||||
|
self,
|
||||||
|
previous: NullableReference[StateType],
|
||||||
|
header: HashPoint[HeaderType],
|
||||||
|
state: HashPoint[StateType]
|
||||||
|
) -> bool:
|
||||||
|
assert isinstance(previous, NullableReference)
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
assert isinstance(state, HashPoint)
|
||||||
|
assert state == self.derive(previous, header)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _initial_state(self) -> HashPoint[StateType]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def _derive(
|
||||||
|
self,
|
||||||
|
previous: HashPoint[StateType],
|
||||||
|
header: HashPoint[HeaderType],
|
||||||
|
) -> HashPoint[StateType]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def derive(
|
||||||
|
self,
|
||||||
|
previous: NullableReference[StateType],
|
||||||
|
header: HashPoint[HeaderType],
|
||||||
|
) -> HashPoint[StateType]:
|
||||||
|
assert isinstance(previous, NullableReference)
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
if isinstance(previous.reference, Null):
|
||||||
|
previous_state: HashPoint[StateType] = self._initial_state()
|
||||||
|
elif isinstance(previous.reference, NotNull):
|
||||||
|
previous_state: HashPoint[StateType] = previous.reference.value
|
||||||
|
else:
|
||||||
|
raise TypeError
|
||||||
|
assert isinstance(previous_state, HashPoint)
|
||||||
|
return self._derive(previous_state, header)
|
@ -19,6 +19,6 @@ class StateProtocol(Generic[HeaderType, StateType]):
|
|||||||
self,
|
self,
|
||||||
previous: NullableReference[StateType],
|
previous: NullableReference[StateType],
|
||||||
header: HashPoint[HeaderType],
|
header: HashPoint[HeaderType],
|
||||||
state: NullableReference[StateType]
|
state: HashPoint[StateType]
|
||||||
) -> bool:
|
) -> bool:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import abc
|
import abc
|
||||||
from typing import Generic, TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
from rainbowadn.hashing.static import StaticMentionable
|
from rainbowadn.hashing.static import StaticMentionable
|
||||||
@ -9,6 +9,6 @@ __all__ = ('Atomic',)
|
|||||||
AtomicMentioned = TypeVar('AtomicMentioned')
|
AtomicMentioned = TypeVar('AtomicMentioned')
|
||||||
|
|
||||||
|
|
||||||
class Atomic(StaticMentionable[AtomicMentioned], abc.ABC, Generic[AtomicMentioned]):
|
class Atomic(StaticMentionable, abc.ABC):
|
||||||
def __topology_hash__(self) -> bytes:
|
def __topology_hash__(self) -> bytes:
|
||||||
return HashPoint.NULL_HASH
|
return HashPoint.hash(b'')
|
||||||
|
@ -3,7 +3,7 @@ from rainbowadn.data.atomic.atomic import Atomic
|
|||||||
__all__ = ('Integer',)
|
__all__ = ('Integer',)
|
||||||
|
|
||||||
|
|
||||||
class Integer(Atomic['Integer']):
|
class Integer(Atomic):
|
||||||
def __init__(self, integer: int):
|
def __init__(self, integer: int):
|
||||||
assert isinstance(integer, int)
|
assert isinstance(integer, int)
|
||||||
assert integer >= 0
|
assert integer >= 0
|
||||||
|
@ -3,7 +3,7 @@ from rainbowadn.data.atomic.atomic import Atomic
|
|||||||
__all__ = ('Plain',)
|
__all__ = ('Plain',)
|
||||||
|
|
||||||
|
|
||||||
class Plain(Atomic['Plain']):
|
class Plain(Atomic):
|
||||||
def __init__(self, source: bytes):
|
def __init__(self, source: bytes):
|
||||||
assert isinstance(source, bytes)
|
assert isinstance(source, bytes)
|
||||||
self.source = source
|
self.source = source
|
||||||
|
0
rainbowadn/data/collection/array/__init__.py
Normal file
0
rainbowadn/data/collection/array/__init__.py
Normal file
64
rainbowadn/data/collection/array/array.py
Normal file
64
rainbowadn/data/collection/array/array.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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.nullability.null import Null
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
|
||||||
|
|
||||||
|
__all__ = ('Array', 'ArrayFactory',)
|
||||||
|
|
||||||
|
ElementType = TypeVar('ElementType')
|
||||||
|
|
||||||
|
|
||||||
|
class Array(RecursiveMentionable, Generic[ElementType]):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
factory: RainbowFactory[ElementType],
|
||||||
|
array: tuple[HashPoint[ElementType], ...]
|
||||||
|
):
|
||||||
|
assert isinstance(factory, RainbowFactory)
|
||||||
|
assert isinstance(array, tuple)
|
||||||
|
self.factory = factory
|
||||||
|
self.array = array
|
||||||
|
|
||||||
|
def points(self) -> Iterable[HashPoint]:
|
||||||
|
return self.array
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
return b''.join(map(HashPoint.__bytes__, self.array))
|
||||||
|
|
||||||
|
def __factory__(self) -> RainbowFactory['Array']:
|
||||||
|
return ArrayFactory(self.factory)
|
||||||
|
|
||||||
|
def str(self, resolver: HashResolver, tab: int) -> str:
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(tab, int)
|
||||||
|
formatted = f'('
|
||||||
|
for hash_point in self.array:
|
||||||
|
formatted += f'{tabulate(tab+1)}{hash_point_format(hash_point,resolver,tab+1)}'
|
||||||
|
return f'{formatted}' \
|
||||||
|
f'{tabulate(tab)})'
|
||||||
|
|
||||||
|
|
||||||
|
class ArrayFactory(RainbowFactory[Array], Generic[ElementType]):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
factory: RainbowFactory[ElementType]
|
||||||
|
):
|
||||||
|
assert isinstance(factory, RainbowFactory)
|
||||||
|
self.factory = factory
|
||||||
|
|
||||||
|
def from_bytes(self, source: bytes) -> Array:
|
||||||
|
assert isinstance(source, bytes)
|
||||||
|
return Array(
|
||||||
|
self.factory,
|
||||||
|
tuple(
|
||||||
|
HashPoint(self.factory, source[i:i + HashPoint.HASH_LENGTH], Null())
|
||||||
|
for
|
||||||
|
i
|
||||||
|
in
|
||||||
|
range(0, len(source), HashPoint.HASH_LENGTH)
|
||||||
|
)
|
||||||
|
)
|
@ -1,40 +0,0 @@
|
|||||||
from typing import Generic, TypeVar
|
|
||||||
|
|
||||||
from rainbowadn.data.collection.collection_interface.activecollectioninterface import ActiveCollectionInterface
|
|
||||||
from rainbowadn.data.collection.stack.stack import Stack
|
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
|
||||||
from rainbowadn.hashing.hashresolver import HashResolver
|
|
||||||
from rainbowadn.hashing.nullability.notnull import NotNull
|
|
||||||
from rainbowadn.hashing.nullability.null import Null
|
|
||||||
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
|
||||||
|
|
||||||
__all__ = ('ActiveStack',)
|
|
||||||
|
|
||||||
ElementType = TypeVar('ElementType')
|
|
||||||
|
|
||||||
|
|
||||||
class ActiveStack(ActiveCollectionInterface[Stack[ElementType], ElementType], Generic[ElementType]):
|
|
||||||
def __init__(self, reference: NullableReference[Stack[ElementType]]):
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
super().__init__(reference)
|
|
||||||
|
|
||||||
def add(self, element: HashPoint[ElementType]) -> 'ActiveStack[ElementType]':
|
|
||||||
assert isinstance(element, HashPoint)
|
|
||||||
return ActiveStack(NullableReference.off(Stack(self.reference, element)))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def empty(cls, factory: RainbowFactory[ElementType]) -> 'ActiveStack[ElementType]':
|
|
||||||
assert isinstance(factory, RainbowFactory)
|
|
||||||
return cls(NullableReference(Null(), Stack.factory(factory)))
|
|
||||||
|
|
||||||
def str(self, resolver: HashResolver):
|
|
||||||
assert isinstance(resolver, HashResolver)
|
|
||||||
if isinstance(self.reference.reference, Null):
|
|
||||||
return f'-'
|
|
||||||
elif isinstance(self.reference.reference, NotNull):
|
|
||||||
stack: Stack[ElementType] = resolver.resolve(self.reference.reference.value)
|
|
||||||
assert isinstance(stack, Stack)
|
|
||||||
return f'{ActiveStack(stack.previous).str(resolver)} {resolver.resolve(stack.element)}'
|
|
||||||
else:
|
|
||||||
raise TypeError
|
|
@ -50,9 +50,11 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
|
|||||||
]:
|
]:
|
||||||
assert isinstance(factory, RainbowFactory)
|
assert isinstance(factory, RainbowFactory)
|
||||||
reference: NullableReference[Stack[ElementType]] = NullableReference(Null(), cls.factory(factory))
|
reference: NullableReference[Stack[ElementType]] = NullableReference(Null(), cls.factory(factory))
|
||||||
|
assert isinstance(reference, NullableReference)
|
||||||
for element in elements:
|
for element in elements:
|
||||||
assert isinstance(element, HashPoint)
|
assert isinstance(element, HashPoint)
|
||||||
reference = NullableReference.off(cls(reference, element))
|
reference = NullableReference.off(cls(reference, element))
|
||||||
|
assert isinstance(reference, NullableReference)
|
||||||
return reference
|
return reference
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -63,6 +65,7 @@ class Stack(RecursiveMentionable, Generic[ElementType]):
|
|||||||
) -> NullableReference[
|
) -> NullableReference[
|
||||||
'Stack[ElementType]'
|
'Stack[ElementType]'
|
||||||
]:
|
]:
|
||||||
|
assert isinstance(factory, RainbowFactory)
|
||||||
return cls.of(factory, map(HashPoint.of, elements))
|
return cls.of(factory, map(HashPoint.of, elements))
|
||||||
|
|
||||||
|
|
||||||
|
0
rainbowadn/data/collection/trees/b/__init__.py
Normal file
0
rainbowadn/data/collection/trees/b/__init__.py
Normal file
@ -1,19 +1,22 @@
|
|||||||
from typing import Generic, TypeVar
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree
|
|
||||||
from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Left, Replace, Right)
|
|
||||||
from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator
|
|
||||||
from rainbowadn.data.collection.trees.binary.querybinarytree import QueryBinaryTree
|
|
||||||
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
|
||||||
from rainbowadn.data.collection.keymetadata import KeyMetadata
|
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
|
||||||
from rainbowadn.data.collection.keymetadataquerycollection import KeyMetadataQueryCollection
|
from rainbowadn.data.collection.keymetadataquerycollection import KeyMetadataQueryCollection
|
||||||
|
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.querybinarytree import QueryBinaryTree
|
||||||
|
from rainbowadn.data.collection.trees.comparison.comparator import (Comparator, Comparison, Left, Replace, Right)
|
||||||
|
from rainbowadn.data.collection.trees.comparison.keyedcomparator import KeyedComparator
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
from rainbowadn.hashing.hashresolver import HashResolver
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
from rainbowadn.hashing.nullability.notnull import NotNull
|
from rainbowadn.hashing.nullability.notnull import NotNull
|
||||||
from rainbowadn.hashing.nullability.null import Null
|
from rainbowadn.hashing.nullability.null import Null
|
||||||
from rainbowadn.hashing.nullability.nullable import Nullable
|
|
||||||
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
|
||||||
__all__ = ('ActiveBinaryTree',)
|
__all__ = ('ActiveBinaryTree',)
|
||||||
|
|
||||||
@ -27,40 +30,34 @@ class ActiveBinaryTree(
|
|||||||
):
|
):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
comparator: Comparator[ActiveKeyType],
|
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
|
||||||
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
||||||
):
|
):
|
||||||
assert isinstance(comparator, Comparator)
|
assert isinstance(protocol, BinaryTreeBalancingProtocol)
|
||||||
assert isinstance(reference, NullableReference)
|
assert isinstance(reference, NullableReference)
|
||||||
super().__init__(reference)
|
super().__init__(reference)
|
||||||
self.comparator = comparator
|
self.protocol = protocol
|
||||||
self.resolver = comparator.resolver
|
self.comparator = protocol.comparator
|
||||||
|
assert isinstance(self.comparator, Comparator)
|
||||||
|
self.resolver = protocol.resolver
|
||||||
assert isinstance(self.resolver, HashResolver)
|
assert isinstance(self.resolver, HashResolver)
|
||||||
|
self.creation = ActiveCreationProtocol(protocol)
|
||||||
|
assert isinstance(self.creation, BinaryTreeCreationProtocol)
|
||||||
|
|
||||||
def empty_metadata(self) -> HashPoint[MetaDataType]:
|
@classmethod
|
||||||
raise NotImplementedError
|
def empty(
|
||||||
|
cls,
|
||||||
def metadata(
|
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, 'ActiveBinaryTree'],
|
||||||
self,
|
factory: RainbowFactory[ActiveKeyType]
|
||||||
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
):
|
||||||
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
assert isinstance(protocol, BinaryTreeBalancingProtocol)
|
||||||
key: HashPoint[ActiveKeyType]
|
assert isinstance(factory, RainbowFactory)
|
||||||
) -> HashPoint[MetaDataType]:
|
return cls(
|
||||||
raise NotImplementedError
|
protocol,
|
||||||
|
NullableReference(
|
||||||
def _binary_tree(
|
Null(),
|
||||||
self,
|
BinaryTreeFactory(KeyMetadataFactory(factory, protocol.empty_metadata().factory))
|
||||||
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
)
|
||||||
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
|
||||||
key: HashPoint[ActiveKeyType]
|
|
||||||
) -> BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]:
|
|
||||||
assert isinstance(treel, NullableReference)
|
|
||||||
assert isinstance(treer, NullableReference)
|
|
||||||
assert isinstance(key, HashPoint)
|
|
||||||
return BinaryTree(
|
|
||||||
treel,
|
|
||||||
treer,
|
|
||||||
HashPoint.of(KeyMetadata(key, self.metadata(treel, treer, key)))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def create(
|
def create(
|
||||||
@ -68,81 +65,82 @@ class ActiveBinaryTree(
|
|||||||
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
||||||
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
|
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
|
||||||
assert isinstance(reference, NullableReference)
|
assert isinstance(reference, NullableReference)
|
||||||
return type(self)(
|
return ActiveBinaryTree(
|
||||||
self.comparator,
|
self.protocol,
|
||||||
reference
|
reference
|
||||||
)
|
)
|
||||||
|
|
||||||
def active_tree(
|
|
||||||
self,
|
|
||||||
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
|
||||||
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
|
||||||
key: HashPoint[ActiveKeyType]
|
|
||||||
) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
|
|
||||||
assert isinstance(treel, NullableReference)
|
|
||||||
assert isinstance(treer, NullableReference)
|
|
||||||
assert isinstance(key, HashPoint)
|
|
||||||
return self.create(
|
|
||||||
NullableReference.off(
|
|
||||||
self._binary_tree(
|
|
||||||
self.create(treel).balance().reference,
|
|
||||||
self.create(treer).balance().reference,
|
|
||||||
key
|
|
||||||
)
|
|
||||||
)
|
|
||||||
).balance()
|
|
||||||
|
|
||||||
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)
|
||||||
reference: Nullable[
|
if self.creation.splittable(self):
|
||||||
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
treel: ActiveBinaryTree[ActiveKeyType, MetaDataType]
|
||||||
] = self.reference.reference
|
original: HashPoint[ActiveKeyType]
|
||||||
assert isinstance(reference, Nullable)
|
treer: ActiveBinaryTree[ActiveKeyType, MetaDataType]
|
||||||
if isinstance(reference, Null):
|
treel, original, _, treer = self.creation.split(self)
|
||||||
return self.active_tree(self.reference, self.reference, key)
|
assert isinstance(treel, ActiveBinaryTree)
|
||||||
elif isinstance(reference, NotNull):
|
|
||||||
tree: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = self.resolver.resolve(reference.value)
|
|
||||||
assert isinstance(tree, BinaryTree)
|
|
||||||
original: HashPoint[ActiveKeyType] = self.resolver.resolve(tree.key).key
|
|
||||||
assert isinstance(original, HashPoint)
|
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):
|
||||||
return self.active_tree(tree.treel, tree.treer, key)
|
return self.creation.tree(treel, treer, key)
|
||||||
elif isinstance(comparison, Left):
|
elif isinstance(comparison, Left):
|
||||||
return self.active_tree(self.create(tree.treel).add(key).reference, tree.treer, original)
|
return self.creation.tree(treel.add(key), treer, original)
|
||||||
elif isinstance(comparison, Right):
|
elif isinstance(comparison, Right):
|
||||||
return self.active_tree(tree.treel, self.create(tree.treer).add(key).reference, original)
|
return self.creation.tree(treel, treer.add(key), original)
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
return self.creation.tree(self, self, key)
|
||||||
|
|
||||||
def balance(self) -> 'ActiveBinaryTree[ActiveKeyType, MetaDataType]':
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
reference: Nullable[
|
|
||||||
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
|
||||||
] = self.reference.reference
|
|
||||||
assert isinstance(reference, Nullable)
|
|
||||||
if isinstance(reference, Null):
|
|
||||||
return '_'
|
|
||||||
elif isinstance(reference, NotNull):
|
|
||||||
tree: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = self.resolver.resolve(reference.value)
|
|
||||||
assert isinstance(tree, BinaryTree)
|
|
||||||
key: KeyMetadata[ActiveKeyType, MetaDataType] = self.resolver.resolve(tree.key)
|
|
||||||
assert isinstance(key, KeyMetadata)
|
|
||||||
return f'( {self.create(tree.treel)}' \
|
|
||||||
f' {self.resolver.resolve(key.key)}' \
|
|
||||||
f' {self.resolver.resolve(key.metadata)}' \
|
|
||||||
f' {self.create(tree.treer)} )'
|
|
||||||
else:
|
|
||||||
raise TypeError
|
|
||||||
|
|
||||||
def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]:
|
def query_tree(self) -> QueryCollectionInterface[ActiveKeyType]:
|
||||||
return KeyMetadataQueryCollection(
|
return KeyMetadataQueryCollection(
|
||||||
self.empty_metadata(),
|
self.protocol.empty_metadata(),
|
||||||
QueryBinaryTree(KeyedComparator(self.resolver, self.comparator), self.reference),
|
QueryBinaryTree(KeyedComparator(self.comparator), self.reference),
|
||||||
self.resolver
|
self.resolver
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ActiveCreationProtocol(BalancedTreeCreationProtocol[ActiveKeyType, MetaDataType, ActiveBinaryTree]):
|
||||||
|
def splittable(self, tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]) -> bool:
|
||||||
|
assert isinstance(tree, ActiveBinaryTree)
|
||||||
|
return isinstance(tree.reference.reference, NotNull)
|
||||||
|
|
||||||
|
def split(
|
||||||
|
self,
|
||||||
|
tree: ActiveBinaryTree[ActiveKeyType, MetaDataType]
|
||||||
|
) -> tuple[
|
||||||
|
ActiveBinaryTree[ActiveKeyType, MetaDataType],
|
||||||
|
HashPoint[ActiveKeyType],
|
||||||
|
HashPoint[MetaDataType],
|
||||||
|
ActiveBinaryTree[ActiveKeyType, MetaDataType]
|
||||||
|
]:
|
||||||
|
assert isinstance(tree, ActiveBinaryTree)
|
||||||
|
assert isinstance(tree.reference.reference, NotNull)
|
||||||
|
hash_point: HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]] = tree.reference.reference.value
|
||||||
|
assert isinstance(hash_point, HashPoint)
|
||||||
|
resolved: BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]] = self.resolver.resolve(hash_point)
|
||||||
|
assert isinstance(resolved, BinaryTree)
|
||||||
|
key_metadata: KeyMetadata[ActiveKeyType, MetaDataType] = self.resolver.resolve(resolved.key)
|
||||||
|
assert isinstance(key_metadata, KeyMetadata)
|
||||||
|
return tree.create(resolved.treel), key_metadata.key, key_metadata.metadata, tree.create(resolved.treer)
|
||||||
|
|
||||||
|
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, self.protocol.metadata(treel, treer, key, self)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -1,180 +1,86 @@
|
|||||||
from typing import Generic, TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
from rainbowadn.data.atomic.integer import Integer
|
from rainbowadn.data.atomic.integer import Integer
|
||||||
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
|
from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
|
||||||
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory
|
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
|
||||||
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
|
|
||||||
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
|
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
from rainbowadn.hashing.nullability.notnull import NotNull
|
|
||||||
from rainbowadn.hashing.nullability.null import Null
|
|
||||||
from rainbowadn.hashing.nullability.nullable import Nullable
|
|
||||||
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
|
||||||
|
|
||||||
__all__ = ('AVLABT',)
|
__all__ = ('AVLBTBP',)
|
||||||
|
|
||||||
ActiveKeyType = TypeVar('ActiveKeyType')
|
ActiveKeyType = TypeVar('ActiveKeyType')
|
||||||
|
TreeType = TypeVar('TreeType')
|
||||||
|
|
||||||
|
|
||||||
class AVLABT(ActiveBinaryTree[ActiveKeyType, Integer], Generic[ActiveKeyType]):
|
class AVLBTBP(BinaryTreeBalancingProtocol[ActiveKeyType, Integer, TreeType]):
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
comparator: Comparator[ActiveKeyType],
|
|
||||||
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
|
|
||||||
):
|
|
||||||
assert isinstance(comparator, Comparator)
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
super().__init__(comparator, reference)
|
|
||||||
|
|
||||||
def create(
|
|
||||||
self, reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
|
|
||||||
) -> 'AVLABT[ActiveKeyType]':
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
return type(self)(
|
|
||||||
self.comparator,
|
|
||||||
reference
|
|
||||||
)
|
|
||||||
|
|
||||||
def height(self) -> int:
|
|
||||||
reference: Nullable[
|
|
||||||
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
|
|
||||||
] = self.reference.reference
|
|
||||||
assert isinstance(reference, Nullable)
|
|
||||||
if isinstance(reference, Null):
|
|
||||||
return 0
|
|
||||||
elif isinstance(reference, NotNull):
|
|
||||||
tree: BinaryTree[KeyMetadata[ActiveKeyType, Integer]] = self.resolver.resolve(reference.value)
|
|
||||||
assert isinstance(tree, BinaryTree)
|
|
||||||
key: KeyMetadata[ActiveKeyType, Integer] = self.resolver.resolve(tree.key)
|
|
||||||
assert isinstance(key, KeyMetadata)
|
|
||||||
return self.resolver.resolve(key.metadata).integer
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def empty(
|
|
||||||
cls,
|
|
||||||
comparator: Comparator[ActiveKeyType],
|
|
||||||
factory: RainbowFactory[ActiveKeyType]
|
|
||||||
):
|
|
||||||
assert isinstance(comparator, Comparator)
|
|
||||||
assert isinstance(factory, RainbowFactory)
|
|
||||||
return cls(
|
|
||||||
comparator,
|
|
||||||
NullableReference(
|
|
||||||
Null(),
|
|
||||||
BinaryTreeFactory(KeyMetadataFactory(factory, Integer.factory()))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def empty_metadata(self) -> HashPoint[Integer]:
|
def empty_metadata(self) -> HashPoint[Integer]:
|
||||||
return HashPoint.of(Integer(0))
|
return HashPoint.of(Integer(0))
|
||||||
|
|
||||||
def metadata(
|
def metadata(
|
||||||
self,
|
self,
|
||||||
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]],
|
treel: TreeType,
|
||||||
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]],
|
treer: TreeType,
|
||||||
key: HashPoint[ActiveKeyType]
|
key: HashPoint[ActiveKeyType],
|
||||||
|
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
|
||||||
) -> HashPoint[Integer]:
|
) -> HashPoint[Integer]:
|
||||||
assert isinstance(treel, NullableReference)
|
return HashPoint.of(
|
||||||
assert isinstance(treer, NullableReference)
|
Integer(1 + max(self.height(treel, protocol), self.height(treer, protocol)))
|
||||||
assert isinstance(key, HashPoint)
|
)
|
||||||
return HashPoint.of(Integer(1 + max(self.create(treel).height(), self.create(treer).height())))
|
|
||||||
|
|
||||||
def balance(self) -> ActiveBinaryTree[ActiveKeyType, Integer]:
|
def height(
|
||||||
reference: Nullable[
|
self,
|
||||||
HashPoint[BinaryTree[KeyMetadata[ActiveKeyType, Integer]]]
|
tree: TreeType,
|
||||||
] = self.reference.reference
|
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
|
||||||
assert isinstance(reference, Nullable)
|
) -> int:
|
||||||
if isinstance(reference, Null):
|
if protocol.splittable(tree):
|
||||||
return self
|
_, _, metadata, _ = protocol.split(tree)
|
||||||
elif isinstance(reference, NotNull):
|
return self.resolver.resolve(metadata).integer
|
||||||
tree: BinaryTree[KeyMetadata[ActiveKeyType, Integer]] = self.resolver.resolve(reference.value)
|
else:
|
||||||
assert isinstance(tree, BinaryTree)
|
return 0
|
||||||
atl = self.create(tree.treel)
|
|
||||||
assert isinstance(atl, ActiveBinaryTree)
|
def balance(
|
||||||
atr = self.create(tree.treer)
|
self,
|
||||||
assert isinstance(atr, ActiveBinaryTree)
|
tree: TreeType,
|
||||||
delta = atl.height() - atr.height()
|
protocol: BinaryTreeCreationProtocol[ActiveKeyType, Integer, TreeType]
|
||||||
|
) -> TreeType:
|
||||||
|
if protocol.splittable(tree):
|
||||||
|
treel, key, _, treer = protocol.split(tree)
|
||||||
|
delta = self.height(treel, protocol) - self.height(treer, protocol)
|
||||||
assert isinstance(delta, int)
|
assert isinstance(delta, int)
|
||||||
if delta < -1:
|
if delta < -1:
|
||||||
assert isinstance(atr.reference.reference, NotNull)
|
assert protocol.splittable(treer)
|
||||||
treer: BinaryTree[
|
treerl, keyr, _, treerr = protocol.split(treer)
|
||||||
KeyMetadata[ActiveKeyType, Integer]
|
if self.height(treerl, protocol) > self.height(treerr, protocol):
|
||||||
] = self.resolver.resolve(atr.reference.reference.value)
|
assert protocol.splittable(treerl)
|
||||||
assert isinstance(treer, BinaryTree)
|
treerll, keyrl, _, treerlr = protocol.split(treerl)
|
||||||
atrl = self.create(treer.treel)
|
return protocol.tree(
|
||||||
assert isinstance(atrl, ActiveBinaryTree)
|
protocol.tree(treel, treerll, key),
|
||||||
atrr = self.create(treer.treer)
|
protocol.tree(treerlr, treerr, keyr),
|
||||||
assert isinstance(atrr, ActiveBinaryTree)
|
keyrl
|
||||||
if atrl.height() > atrr.height():
|
|
||||||
assert isinstance(atrl.reference.reference, NotNull)
|
|
||||||
treerl: BinaryTree[
|
|
||||||
KeyMetadata[ActiveKeyType, Integer]
|
|
||||||
] = self.resolver.resolve(atrl.reference.reference.value)
|
|
||||||
assert isinstance(treerl, BinaryTree)
|
|
||||||
return self.active_tree(
|
|
||||||
self.active_tree(
|
|
||||||
atl.reference,
|
|
||||||
treerl.treel,
|
|
||||||
self.resolver.resolve(tree.key).key
|
|
||||||
).reference,
|
|
||||||
self.active_tree(
|
|
||||||
treerl.treer,
|
|
||||||
atrr.reference,
|
|
||||||
self.resolver.resolve(treer.key).key
|
|
||||||
).reference,
|
|
||||||
self.resolver.resolve(treerl.key).key
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return self.active_tree(
|
return protocol.tree(
|
||||||
self.active_tree(
|
protocol.tree(treel, treerl, key),
|
||||||
atl.reference,
|
treerr,
|
||||||
atrl.reference,
|
keyr
|
||||||
self.resolver.resolve(tree.key).key
|
|
||||||
).reference,
|
|
||||||
atrr.reference,
|
|
||||||
self.resolver.resolve(treer.key).key
|
|
||||||
)
|
)
|
||||||
elif delta > 1:
|
elif delta > 1:
|
||||||
assert isinstance(atl.reference.reference, NotNull)
|
assert protocol.splittable(treel)
|
||||||
treel: BinaryTree[
|
treell, keyl, _, treelr = protocol.split(treel)
|
||||||
KeyMetadata[ActiveKeyType, Integer]
|
if self.height(treelr, protocol) > self.height(treell, protocol):
|
||||||
] = self.resolver.resolve(atl.reference.reference.value)
|
assert protocol.splittable(treelr)
|
||||||
assert isinstance(treel, BinaryTree)
|
treelrl, keylr, _, treelrr = protocol.split(treelr)
|
||||||
atlr = self.create(treel.treer)
|
return protocol.tree(
|
||||||
assert isinstance(atlr, ActiveBinaryTree)
|
protocol.tree(treell, treelrl, keyl),
|
||||||
atll = self.create(treel.treel)
|
protocol.tree(treelrr, treer, key),
|
||||||
assert isinstance(atll, ActiveBinaryTree)
|
keylr
|
||||||
if atlr.height() > atll.height():
|
|
||||||
assert isinstance(atlr.reference.reference, NotNull)
|
|
||||||
treelr: BinaryTree[
|
|
||||||
KeyMetadata[ActiveKeyType, Integer]
|
|
||||||
] = self.resolver.resolve(atlr.reference.reference.value)
|
|
||||||
assert isinstance(treelr, BinaryTree)
|
|
||||||
return self.active_tree(
|
|
||||||
self.active_tree(
|
|
||||||
atll.reference,
|
|
||||||
treelr.treel,
|
|
||||||
self.resolver.resolve(treel.key).key
|
|
||||||
).reference,
|
|
||||||
self.active_tree(
|
|
||||||
treelr.treer,
|
|
||||||
atr.reference,
|
|
||||||
self.resolver.resolve(tree.key).key
|
|
||||||
).reference,
|
|
||||||
self.resolver.resolve(treelr.key).key
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return self.active_tree(
|
return protocol.tree(
|
||||||
atll.reference,
|
treell,
|
||||||
self.active_tree(
|
protocol.tree(treelr, treer, key),
|
||||||
atlr.reference,
|
keyl
|
||||||
atr.reference,
|
|
||||||
self.resolver.resolve(tree.key).key
|
|
||||||
).reference,
|
|
||||||
self.resolver.resolve(treel.key).key
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return self
|
return tree
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
return tree
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.data.collection.trees.binary.binarytreebalancingprotocol import BinaryTreeBalancingProtocol
|
||||||
|
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
|
|
||||||
|
__all__ = ('BalancedTreeCreationProtocol',)
|
||||||
|
|
||||||
|
TreeType = TypeVar('TreeType')
|
||||||
|
ActiveKeyType = TypeVar('ActiveKeyType')
|
||||||
|
MetaDataType = TypeVar('MetaDataType')
|
||||||
|
|
||||||
|
|
||||||
|
class BalancedTreeCreationProtocol(
|
||||||
|
BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType],
|
||||||
|
Generic[ActiveKeyType, MetaDataType, TreeType]
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
protocol: BinaryTreeBalancingProtocol[ActiveKeyType, MetaDataType, TreeType]
|
||||||
|
):
|
||||||
|
assert isinstance(protocol, BinaryTreeBalancingProtocol)
|
||||||
|
self.protocol = protocol
|
||||||
|
self.resolver = protocol.resolver
|
||||||
|
assert isinstance(self.resolver, HashResolver)
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
|
||||||
|
assert isinstance(key, HashPoint)
|
||||||
|
return self.protocol.balance(
|
||||||
|
self._tree(
|
||||||
|
self.protocol.balance(treel, self),
|
||||||
|
self.protocol.balance(treer, self),
|
||||||
|
key
|
||||||
|
),
|
||||||
|
self
|
||||||
|
)
|
@ -0,0 +1,42 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.data.collection.trees.binary.binarytreecreationprotocol import BinaryTreeCreationProtocol
|
||||||
|
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
|
|
||||||
|
__all__ = ('BinaryTreeBalancingProtocol',)
|
||||||
|
|
||||||
|
TreeType = TypeVar('TreeType')
|
||||||
|
ActiveKeyType = TypeVar('ActiveKeyType')
|
||||||
|
MetaDataType = TypeVar('MetaDataType')
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryTreeBalancingProtocol(Generic[ActiveKeyType, MetaDataType, TreeType]):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
comparator: Comparator[ActiveKeyType]
|
||||||
|
):
|
||||||
|
assert isinstance(comparator, Comparator)
|
||||||
|
self.comparator = comparator
|
||||||
|
self.resolver = comparator.resolver
|
||||||
|
assert isinstance(self.resolver, HashResolver)
|
||||||
|
|
||||||
|
def empty_metadata(self) -> HashPoint[MetaDataType]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def metadata(
|
||||||
|
self,
|
||||||
|
treel: TreeType,
|
||||||
|
treer: TreeType,
|
||||||
|
key: HashPoint[ActiveKeyType],
|
||||||
|
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]
|
||||||
|
) -> HashPoint[MetaDataType]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def balance(
|
||||||
|
self,
|
||||||
|
tree: TreeType,
|
||||||
|
protocol: BinaryTreeCreationProtocol[ActiveKeyType, MetaDataType, TreeType]
|
||||||
|
) -> TreeType:
|
||||||
|
raise NotImplementedError
|
@ -0,0 +1,20 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
|
||||||
|
__all__ = ('BinaryTreeCreationProtocol',)
|
||||||
|
|
||||||
|
TreeType = TypeVar('TreeType')
|
||||||
|
ActiveKeyType = TypeVar('ActiveKeyType')
|
||||||
|
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]:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def tree(self, treel: TreeType, treer: TreeType, key: HashPoint[ActiveKeyType]) -> TreeType:
|
||||||
|
raise NotImplementedError
|
@ -1,75 +0,0 @@
|
|||||||
from typing import Generic, TypeVar
|
|
||||||
|
|
||||||
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
|
|
||||||
from rainbowadn.data.collection.trees.binary.binarytree import BinaryTree, BinaryTreeFactory
|
|
||||||
from rainbowadn.data.collection.trees.comparison.comparator import Comparator
|
|
||||||
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
|
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
|
||||||
from rainbowadn.hashing.nullability.null import Null
|
|
||||||
from rainbowadn.hashing.nullability.nullablereference import NullableReference
|
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
|
||||||
|
|
||||||
__all__ = ('UnbalancedABT',)
|
|
||||||
|
|
||||||
ActiveKeyType = TypeVar('ActiveKeyType')
|
|
||||||
MetaDataType = TypeVar('MetaDataType')
|
|
||||||
|
|
||||||
|
|
||||||
class UnbalancedABT(ActiveBinaryTree[ActiveKeyType, MetaDataType], Generic[ActiveKeyType, MetaDataType]):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
comparator: Comparator[ActiveKeyType],
|
|
||||||
reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
|
||||||
metadata: HashPoint[MetaDataType]
|
|
||||||
):
|
|
||||||
assert isinstance(comparator, Comparator)
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
assert isinstance(metadata, HashPoint)
|
|
||||||
super().__init__(comparator, reference)
|
|
||||||
self._metadata = metadata
|
|
||||||
|
|
||||||
def create(
|
|
||||||
self, reference: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]]
|
|
||||||
) -> 'UnbalancedABT[ActiveKeyType, MetaDataType]':
|
|
||||||
assert isinstance(reference, NullableReference)
|
|
||||||
return type(self)(
|
|
||||||
self.comparator,
|
|
||||||
reference,
|
|
||||||
self._metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def empty(
|
|
||||||
cls,
|
|
||||||
comparator: Comparator[ActiveKeyType],
|
|
||||||
metadata: HashPoint[MetaDataType],
|
|
||||||
factory: RainbowFactory[ActiveKeyType]
|
|
||||||
):
|
|
||||||
assert isinstance(comparator, Comparator)
|
|
||||||
assert isinstance(metadata, HashPoint)
|
|
||||||
assert isinstance(factory, RainbowFactory)
|
|
||||||
return cls(
|
|
||||||
comparator,
|
|
||||||
NullableReference(
|
|
||||||
Null(),
|
|
||||||
BinaryTreeFactory(KeyMetadataFactory(factory, metadata.factory))
|
|
||||||
),
|
|
||||||
metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
def empty_metadata(self) -> HashPoint[MetaDataType]:
|
|
||||||
return self._metadata
|
|
||||||
|
|
||||||
def metadata(
|
|
||||||
self,
|
|
||||||
treel: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
|
||||||
treer: NullableReference[BinaryTree[KeyMetadata[ActiveKeyType, MetaDataType]]],
|
|
||||||
key: HashPoint[ActiveKeyType]
|
|
||||||
) -> HashPoint[MetaDataType]:
|
|
||||||
assert isinstance(treel, NullableReference)
|
|
||||||
assert isinstance(treer, NullableReference)
|
|
||||||
assert isinstance(key, HashPoint)
|
|
||||||
return self._metadata
|
|
||||||
|
|
||||||
def balance(self) -> 'UnbalancedABT[ActiveKeyType, MetaDataType]':
|
|
||||||
return self
|
|
@ -1,9 +1,8 @@
|
|||||||
from typing import Generic, TypeVar
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
from rainbowadn.data.collection.trees.comparison.comparator import Comparator, Comparison
|
|
||||||
from rainbowadn.data.collection.keyed import Keyed
|
from rainbowadn.data.collection.keyed import Keyed
|
||||||
|
from rainbowadn.data.collection.trees.comparison.comparator import Comparator, Comparison
|
||||||
from rainbowadn.hashing.hashpoint import HashPoint
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
from rainbowadn.hashing.hashresolver import HashResolver
|
|
||||||
|
|
||||||
__all__ = ('KeyedComparator',)
|
__all__ = ('KeyedComparator',)
|
||||||
|
|
||||||
@ -13,11 +12,10 @@ ComparatorKeyType = TypeVar('ComparatorKeyType')
|
|||||||
class KeyedComparator(
|
class KeyedComparator(
|
||||||
Comparator[Keyed[ComparatorKeyType]], Generic[ComparatorKeyType]
|
Comparator[Keyed[ComparatorKeyType]], Generic[ComparatorKeyType]
|
||||||
):
|
):
|
||||||
def __init__(self, resolver: HashResolver, comparator: Comparator[ComparatorKeyType]):
|
def __init__(self, comparator: Comparator[ComparatorKeyType]):
|
||||||
assert isinstance(resolver, HashResolver)
|
|
||||||
assert isinstance(comparator, Comparator)
|
assert isinstance(comparator, Comparator)
|
||||||
self.comparator = comparator
|
self.comparator = comparator
|
||||||
super().__init__(resolver)
|
super().__init__(comparator.resolver)
|
||||||
|
|
||||||
def compare(
|
def compare(
|
||||||
self,
|
self,
|
||||||
|
@ -10,8 +10,10 @@ class PlainComparator(ProtocolComparator[Plain]):
|
|||||||
def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison:
|
def compare(self, original: HashPoint[Plain], key: HashPoint[Plain]) -> Comparison:
|
||||||
assert isinstance(original, HashPoint)
|
assert isinstance(original, HashPoint)
|
||||||
assert isinstance(key, HashPoint)
|
assert isinstance(key, HashPoint)
|
||||||
original_value = self.resolver.resolve(original)
|
original_value: Plain = self.resolver.resolve(original)
|
||||||
key_value = self.resolver.resolve(key)
|
assert isinstance(original_value, Plain)
|
||||||
|
key_value: Plain = self.resolver.resolve(key)
|
||||||
|
assert isinstance(key, Plain)
|
||||||
if key_value.source < original_value.source:
|
if key_value.source < original_value.source:
|
||||||
return Left()
|
return Left()
|
||||||
elif key_value.source > original_value.source:
|
elif key_value.source > original_value.source:
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
|
||||||
__all__ = ('HashMentionable',)
|
__all__ = ('HashMentionable',)
|
||||||
|
|
||||||
|
HashMentioned = TypeVar('HashMentioned')
|
||||||
|
|
||||||
|
|
||||||
class HashMentionable:
|
class HashMentionable:
|
||||||
def __bytes__(self):
|
def __bytes__(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def __factory__(self) -> RainbowFactory['HashMentionable']:
|
def __factory__(self: HashMentioned) -> RainbowFactory[HashMentioned]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def __topology_hash__(self) -> bytes:
|
def __topology_hash__(self) -> bytes:
|
||||||
|
@ -12,6 +12,11 @@ __all__ = ('HashPoint',)
|
|||||||
HashMentioned = TypeVar('HashMentioned')
|
HashMentioned = TypeVar('HashMentioned')
|
||||||
|
|
||||||
|
|
||||||
|
def _hash(source: bytes) -> bytes:
|
||||||
|
assert isinstance(source, bytes)
|
||||||
|
return hashlib.sha256(source).digest()
|
||||||
|
|
||||||
|
|
||||||
class HashPoint(Generic[HashMentioned]):
|
class HashPoint(Generic[HashMentioned]):
|
||||||
def __init__(self, factory: RainbowFactory[HashMentioned], point: bytes, value: Nullable[HashMentioned]):
|
def __init__(self, factory: RainbowFactory[HashMentioned], point: bytes, value: Nullable[HashMentioned]):
|
||||||
assert isinstance(factory, RainbowFactory)
|
assert isinstance(factory, RainbowFactory)
|
||||||
@ -25,13 +30,13 @@ class HashPoint(Generic[HashMentioned]):
|
|||||||
def __bytes__(self):
|
def __bytes__(self):
|
||||||
return self.point
|
return self.point
|
||||||
|
|
||||||
HASH_LENGTH = 32
|
HASH_LENGTH = len(_hash(b''))
|
||||||
NULL_HASH = b'\0' * HASH_LENGTH
|
NULL_HASH = b'\0' * HASH_LENGTH
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def hash(cls, source: bytes) -> bytes:
|
def hash(cls, source: bytes) -> bytes:
|
||||||
assert isinstance(source, bytes)
|
assert isinstance(source, bytes)
|
||||||
return hashlib.sha256(source).digest()
|
return _hash(source)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def bytes_of_mentioned(cls, mentioned: HashMentionable):
|
def bytes_of_mentioned(cls, mentioned: HashMentionable):
|
||||||
|
@ -9,16 +9,16 @@ __all__ = ('StaticMentionable', 'StaticFactory',)
|
|||||||
StaticMentioned = TypeVar('StaticMentioned')
|
StaticMentioned = TypeVar('StaticMentioned')
|
||||||
|
|
||||||
|
|
||||||
class StaticMentionable(HashMentionable, abc.ABC, Generic[StaticMentioned]):
|
class StaticMentionable(HashMentionable, abc.ABC):
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bytes(cls, source: bytes) -> StaticMentioned:
|
def from_bytes(cls: Type[StaticMentioned], source: bytes) -> StaticMentioned:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def __factory__(self) -> RainbowFactory[StaticMentioned]:
|
def __factory__(self) -> RainbowFactory[StaticMentioned]:
|
||||||
return self.factory()
|
return self.factory()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def factory(cls) -> RainbowFactory[StaticMentioned]:
|
def factory(cls: Type[StaticMentioned]) -> RainbowFactory[StaticMentioned]:
|
||||||
return StaticFactory(cls)
|
return StaticFactory(cls)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ from typing import Iterable
|
|||||||
from rainbowadn.data.atomic.integer import Integer
|
from rainbowadn.data.atomic.integer import Integer
|
||||||
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
|
from rainbowadn.data.collection.keymetadata import KeyMetadata, KeyMetadataFactory
|
||||||
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
|
from rainbowadn.data.collection.trees.binary.activebinarytree import ActiveBinaryTree
|
||||||
from rainbowadn.data.collection.trees.binary.avl import AVLABT
|
from rainbowadn.data.collection.trees.binary.avl import AVLBTBP
|
||||||
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.comparison.comparator import Fail
|
from rainbowadn.data.collection.trees.comparison.comparator import Fail
|
||||||
from rainbowadn.data.collection.trees.comparison.hashcomparator import HashComparator
|
from rainbowadn.data.collection.trees.comparison.hashcomparator import HashComparator
|
||||||
@ -24,7 +24,7 @@ from rainbowadn.v13.transaction import Coin, Transaction, TransactionData
|
|||||||
__all__ = ('BankState',)
|
__all__ = ('BankState',)
|
||||||
|
|
||||||
|
|
||||||
class BankState(RecursiveMentionable, StaticMentionable['BankState']):
|
class BankState(RecursiveMentionable, StaticMentionable):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
minted: NullableReference[BinaryTree[KeyMetadata[Coin, Integer]]],
|
minted: NullableReference[BinaryTree[KeyMetadata[Coin, Integer]]],
|
||||||
@ -107,9 +107,13 @@ class BankState(RecursiveMentionable, StaticMentionable['BankState']):
|
|||||||
transaction_data: TransactionData = resolver.resolve(transaction_resolved.data)
|
transaction_data: TransactionData = resolver.resolve(transaction_resolved.data)
|
||||||
assert isinstance(transaction_data, TransactionData)
|
assert isinstance(transaction_data, TransactionData)
|
||||||
|
|
||||||
minted: ActiveBinaryTree[Coin, Integer] = AVLABT(HashComparator(resolver, Fail()), self.minted)
|
minted: ActiveBinaryTree[Coin, Integer] = ActiveBinaryTree(
|
||||||
|
AVLBTBP(HashComparator(resolver, Fail())), self.minted
|
||||||
|
)
|
||||||
assert isinstance(minted, ActiveBinaryTree)
|
assert isinstance(minted, ActiveBinaryTree)
|
||||||
used: ActiveBinaryTree[Coin, Integer] = AVLABT(HashComparator(resolver, Fail()), self.used)
|
used: ActiveBinaryTree[Coin, Integer] = ActiveBinaryTree(
|
||||||
|
AVLBTBP(HashComparator(resolver, Fail())), self.used
|
||||||
|
)
|
||||||
assert isinstance(used, ActiveBinaryTree)
|
assert isinstance(used, ActiveBinaryTree)
|
||||||
|
|
||||||
in_coin: HashPoint[Coin]
|
in_coin: HashPoint[Coin]
|
||||||
|
@ -13,7 +13,7 @@ class BadSignature(nacl.exceptions.BadSignatureError):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Signature(Atomic['Signature']):
|
class Signature(Atomic):
|
||||||
def __init__(self, source: bytes):
|
def __init__(self, source: bytes):
|
||||||
assert isinstance(source, bytes)
|
assert isinstance(source, bytes)
|
||||||
assert len(source) == nacl.bindings.crypto_sign_BYTES
|
assert len(source) == nacl.bindings.crypto_sign_BYTES
|
||||||
|
@ -6,7 +6,7 @@ from rainbowadn.data.atomic.atomic import Atomic
|
|||||||
__all__ = ('Subject',)
|
__all__ = ('Subject',)
|
||||||
|
|
||||||
|
|
||||||
class Subject(Atomic['Subject']):
|
class Subject(Atomic):
|
||||||
def __init__(self, verify_key: VerifyKey):
|
def __init__(self, verify_key: VerifyKey):
|
||||||
assert isinstance(verify_key, VerifyKey)
|
assert isinstance(verify_key, VerifyKey)
|
||||||
self.verify_key: VerifyKey = verify_key
|
self.verify_key: VerifyKey = verify_key
|
||||||
|
@ -20,7 +20,7 @@ from rainbowadn.v13.subject import Subject
|
|||||||
__all__ = ('CoinData', 'Coin', 'TransactionData', 'Transaction',)
|
__all__ = ('CoinData', 'Coin', 'TransactionData', 'Transaction',)
|
||||||
|
|
||||||
|
|
||||||
class CoinData(RecursiveMentionable, StaticMentionable['CoinData']):
|
class CoinData(RecursiveMentionable, StaticMentionable):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
owner: HashPoint[Subject],
|
owner: HashPoint[Subject],
|
||||||
@ -56,7 +56,7 @@ class CoinData(RecursiveMentionable, StaticMentionable['CoinData']):
|
|||||||
f'{tabulate(tab)}{resolver.resolve(self.value)}'
|
f'{tabulate(tab)}{resolver.resolve(self.value)}'
|
||||||
|
|
||||||
|
|
||||||
class Coin(RecursiveMentionable, StaticMentionable['Coin']):
|
class Coin(RecursiveMentionable, StaticMentionable):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
data: HashPoint[CoinData],
|
data: HashPoint[CoinData],
|
||||||
@ -99,7 +99,7 @@ class Coin(RecursiveMentionable, StaticMentionable['Coin']):
|
|||||||
f'{tabulate(tab)})'
|
f'{tabulate(tab)})'
|
||||||
|
|
||||||
|
|
||||||
class TransactionData(RecursiveMentionable, StaticMentionable['TransactionData']):
|
class TransactionData(RecursiveMentionable, StaticMentionable):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
in_coins: NullableReference[Stack[Coin]],
|
in_coins: NullableReference[Stack[Coin]],
|
||||||
@ -250,7 +250,7 @@ class TransactionData(RecursiveMentionable, StaticMentionable['TransactionData']
|
|||||||
f'{tabulate(tab)}{self.out_coins.str(resolver, tab)}'
|
f'{tabulate(tab)}{self.out_coins.str(resolver, tab)}'
|
||||||
|
|
||||||
|
|
||||||
class Transaction(RecursiveMentionable, StaticMentionable['Transaction']):
|
class Transaction(RecursiveMentionable, StaticMentionable):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
data: HashPoint[TransactionData],
|
data: HashPoint[TransactionData],
|
||||||
|
0
rainbowadn/wrisbt/__init__.py
Normal file
0
rainbowadn/wrisbt/__init__.py
Normal file
312
rainbowadn/wrisbt/weakreferenceindexsetbtree.py
Normal file
312
rainbowadn/wrisbt/weakreferenceindexsetbtree.py
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
import bisect
|
||||||
|
from typing import Iterable, Sequence
|
||||||
|
|
||||||
|
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.nullability.notnull import NotNull
|
||||||
|
from rainbowadn.hashing.nullability.null import Null
|
||||||
|
from rainbowadn.hashing.nullability.nullable import Nullable
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
|
||||||
|
|
||||||
|
__all__ = ('WeakReferenceIndexSetBTree', 'WrisbtFactory',)
|
||||||
|
|
||||||
|
|
||||||
|
class WeakReferenceIndexSetBTree(RecursiveMentionable):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
source: bytes,
|
||||||
|
height: int,
|
||||||
|
keymin: int,
|
||||||
|
root: bool,
|
||||||
|
cache: tuple[Nullable['WeakReferenceIndexSetBTree'], ...]
|
||||||
|
):
|
||||||
|
assert isinstance(source, bytes)
|
||||||
|
assert isinstance(height, int)
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
assert isinstance(root, bool)
|
||||||
|
assert isinstance(cache, tuple)
|
||||||
|
|
||||||
|
self.length = len(source) // HashPoint.HASH_LENGTH
|
||||||
|
assert len(source) == self.length * HashPoint.HASH_LENGTH
|
||||||
|
self.source = source
|
||||||
|
|
||||||
|
assert height >= 0
|
||||||
|
self.height = height
|
||||||
|
self.leaf = height == 0
|
||||||
|
|
||||||
|
self.empty = self.length == 0
|
||||||
|
if self.empty:
|
||||||
|
assert self.leaf
|
||||||
|
|
||||||
|
if self.leaf:
|
||||||
|
self.keys = self.length
|
||||||
|
self.children = 0
|
||||||
|
else:
|
||||||
|
self.keys = self.length // 2
|
||||||
|
self.children = self.keys + 1
|
||||||
|
assert self.length == self.keys + self.children
|
||||||
|
|
||||||
|
assert keymin > 0
|
||||||
|
self.keymin = keymin
|
||||||
|
|
||||||
|
self.root = root
|
||||||
|
|
||||||
|
if not root:
|
||||||
|
assert keymin <= self.keys
|
||||||
|
assert self.keys <= 2 * keymin + 1
|
||||||
|
|
||||||
|
assert len(cache) == self.children
|
||||||
|
child_index: int
|
||||||
|
cached: Nullable[WeakReferenceIndexSetBTree]
|
||||||
|
self.cache = cache
|
||||||
|
|
||||||
|
if self.balanced():
|
||||||
|
self._hash_point = HashPoint.of(self)
|
||||||
|
|
||||||
|
def hash_point(self) -> HashPoint['WeakReferenceIndexSetBTree']:
|
||||||
|
return self._hash_point
|
||||||
|
|
||||||
|
def full(self) -> bool:
|
||||||
|
return self.keys == 2 * self.keymin + 1
|
||||||
|
|
||||||
|
def bytes_no(self, index: int) -> bytes:
|
||||||
|
assert isinstance(index, int)
|
||||||
|
assert 0 <= index < self.length
|
||||||
|
return self.source[HashPoint.HASH_LENGTH * index:HashPoint.HASH_LENGTH * (index + 1)]
|
||||||
|
|
||||||
|
def key_no(self, index: int) -> bytes:
|
||||||
|
assert isinstance(index, int)
|
||||||
|
assert 0 <= index < self.keys
|
||||||
|
return self.bytes_no(index)
|
||||||
|
|
||||||
|
def cached_no(self, index: int) -> Nullable['WeakReferenceIndexSetBTree']:
|
||||||
|
assert isinstance(index, int)
|
||||||
|
assert 0 <= index < self.children
|
||||||
|
assert not self.leaf
|
||||||
|
cached: Nullable[WeakReferenceIndexSetBTree] = self.cache[index]
|
||||||
|
assert isinstance(cached, Nullable)
|
||||||
|
if isinstance(cached, NotNull):
|
||||||
|
tree: WeakReferenceIndexSetBTree = cached.value
|
||||||
|
assert self.bytes_no(self.keys + index) == tree.hash_point().point
|
||||||
|
return cached
|
||||||
|
|
||||||
|
def child_no(self, index: int) -> HashPoint['WeakReferenceIndexSetBTree']:
|
||||||
|
assert isinstance(index, int)
|
||||||
|
assert 0 <= index < self.children
|
||||||
|
assert not self.leaf
|
||||||
|
return HashPoint(
|
||||||
|
WrisbtFactory(self.height - 1, self.keymin, False),
|
||||||
|
self.bytes_no(self.keys + index),
|
||||||
|
self.cached_no(index)
|
||||||
|
)
|
||||||
|
|
||||||
|
def balanced(self) -> bool:
|
||||||
|
return self.keys <= 2 * self.keymin
|
||||||
|
|
||||||
|
def points(self) -> Iterable[HashPoint]:
|
||||||
|
assert self.balanced()
|
||||||
|
if self.leaf:
|
||||||
|
return []
|
||||||
|
else:
|
||||||
|
return [self.child_no(child_index) for child_index in range(self.children)]
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
assert self.balanced()
|
||||||
|
return self.source
|
||||||
|
|
||||||
|
def __topology_hash__(self) -> bytes:
|
||||||
|
return HashPoint.hash(self.source[self.keys * HashPoint.HASH_LENGTH:])
|
||||||
|
|
||||||
|
def __factory__(self) -> RainbowFactory['WeakReferenceIndexSetBTree']:
|
||||||
|
assert self.balanced()
|
||||||
|
return WrisbtFactory(self.height, self.keymin, self.root)
|
||||||
|
|
||||||
|
def range(self, left: int, right: int) -> 'WeakReferenceIndexSetBTree':
|
||||||
|
assert isinstance(left, int)
|
||||||
|
assert isinstance(right, int)
|
||||||
|
assert 0 <= left < right <= self.keys
|
||||||
|
hl: int = HashPoint.HASH_LENGTH
|
||||||
|
assert isinstance(hl, int)
|
||||||
|
if self.leaf:
|
||||||
|
return WeakReferenceIndexSetBTree(
|
||||||
|
self.source[hl * left:hl * right],
|
||||||
|
0,
|
||||||
|
self.keymin,
|
||||||
|
False,
|
||||||
|
()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
keybytes: bytes = self.source[hl * left:hl * right]
|
||||||
|
assert isinstance(keybytes, bytes)
|
||||||
|
childbytes: bytes = self.source[hl * (self.keys + left):hl * (self.keys + right + 1)]
|
||||||
|
assert isinstance(childbytes, bytes)
|
||||||
|
return WeakReferenceIndexSetBTree(
|
||||||
|
keybytes + childbytes,
|
||||||
|
self.height,
|
||||||
|
self.keymin,
|
||||||
|
False,
|
||||||
|
self.cache[left:right + 1],
|
||||||
|
)
|
||||||
|
|
||||||
|
def split(self) -> tuple['WeakReferenceIndexSetBTree', bytes, 'WeakReferenceIndexSetBTree']:
|
||||||
|
assert self.full()
|
||||||
|
return (
|
||||||
|
self.range(0, self.keymin),
|
||||||
|
self.key_no(self.keymin),
|
||||||
|
self.range(self.keymin + 1, 2 * self.keymin + 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
def str(self, resolver: HashResolver, tab: int) -> str:
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(tab, int)
|
||||||
|
|
||||||
|
formatted = f'{self.height}' \
|
||||||
|
f'{tabulate(tab)}('
|
||||||
|
for key_index in range(self.keys):
|
||||||
|
formatted += f'{tabulate(tab + 1)}{self.key_no(key_index).hex()}'
|
||||||
|
for child_index in range(self.children):
|
||||||
|
formatted += f'{tabulate(tab + 1)}{hash_point_format(self.child_no(child_index), resolver, tab + 1)}'
|
||||||
|
|
||||||
|
return f'{formatted}' \
|
||||||
|
f'{tabulate(tab)})'
|
||||||
|
|
||||||
|
def contains(self, resolver: HashResolver, key: bytes) -> bool:
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(key, bytes)
|
||||||
|
assert len(key) == HashPoint.HASH_LENGTH
|
||||||
|
hl: int = HashPoint.HASH_LENGTH
|
||||||
|
assert isinstance(hl, int)
|
||||||
|
|
||||||
|
assert self.balanced()
|
||||||
|
|
||||||
|
index: int = bisect.bisect_left(KeyView(self), key)
|
||||||
|
assert isinstance(index, int)
|
||||||
|
|
||||||
|
if index < self.keys and self.key_no(index) == key:
|
||||||
|
return True
|
||||||
|
if index < self.keys:
|
||||||
|
assert key < self.key_no(index)
|
||||||
|
if index > 0:
|
||||||
|
assert key > self.key_no(index - 1)
|
||||||
|
if self.leaf:
|
||||||
|
return False
|
||||||
|
child: WeakReferenceIndexSetBTree = resolver.resolve(self.child_no(index))
|
||||||
|
assert isinstance(child, WeakReferenceIndexSetBTree)
|
||||||
|
return child.contains(resolver, key)
|
||||||
|
|
||||||
|
def add(self, resolver: HashResolver, key: bytes) -> 'WeakReferenceIndexSetBTree':
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(key, bytes)
|
||||||
|
assert len(key) == HashPoint.HASH_LENGTH
|
||||||
|
hl: int = HashPoint.HASH_LENGTH
|
||||||
|
assert isinstance(hl, int)
|
||||||
|
|
||||||
|
assert self.balanced()
|
||||||
|
|
||||||
|
index: int = bisect.bisect_left(KeyView(self), key)
|
||||||
|
assert isinstance(index, int)
|
||||||
|
|
||||||
|
if index < self.keys and self.key_no(index) == key:
|
||||||
|
return self
|
||||||
|
if index < self.keys:
|
||||||
|
assert key < self.key_no(index)
|
||||||
|
if index > 0:
|
||||||
|
assert key > self.key_no(index - 1)
|
||||||
|
if self.leaf:
|
||||||
|
return WeakReferenceIndexSetBTree(
|
||||||
|
self.source[:hl * index] + key + self.source[hl * index:],
|
||||||
|
self.height,
|
||||||
|
self.keymin,
|
||||||
|
self.root,
|
||||||
|
()
|
||||||
|
)
|
||||||
|
child: WeakReferenceIndexSetBTree = resolver.resolve(self.child_no(index))
|
||||||
|
assert isinstance(child, WeakReferenceIndexSetBTree)
|
||||||
|
child: WeakReferenceIndexSetBTree = child.add(resolver, key)
|
||||||
|
assert isinstance(child, WeakReferenceIndexSetBTree)
|
||||||
|
if child.full():
|
||||||
|
left, middle, right = child.split()
|
||||||
|
assert isinstance(left, WeakReferenceIndexSetBTree)
|
||||||
|
assert isinstance(middle, bytes)
|
||||||
|
assert isinstance(right, WeakReferenceIndexSetBTree)
|
||||||
|
return WeakReferenceIndexSetBTree(
|
||||||
|
(
|
||||||
|
self.source[:hl * index]
|
||||||
|
+
|
||||||
|
middle
|
||||||
|
+
|
||||||
|
self.source[hl * index:hl * (self.keys + index)]
|
||||||
|
+
|
||||||
|
bytes(left.hash_point())
|
||||||
|
+
|
||||||
|
bytes(right.hash_point())
|
||||||
|
+
|
||||||
|
self.source[hl * (self.keys + index + 1):]
|
||||||
|
),
|
||||||
|
self.height,
|
||||||
|
self.keymin,
|
||||||
|
self.root,
|
||||||
|
self.cache[:index] + (NotNull(left), NotNull(right)) + self.cache[index + 1:]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return WeakReferenceIndexSetBTree(
|
||||||
|
(
|
||||||
|
self.source[:hl * (self.keys + index)]
|
||||||
|
+
|
||||||
|
bytes(HashPoint.of(child))
|
||||||
|
+
|
||||||
|
self.source[hl * (self.keys + index + 1):]
|
||||||
|
),
|
||||||
|
self.height,
|
||||||
|
self.keymin,
|
||||||
|
self.root,
|
||||||
|
self.cache[:index] + (NotNull(child),) + self.cache[index + 1:]
|
||||||
|
)
|
||||||
|
|
||||||
|
def iter_keys(self, resolver: HashResolver) -> Iterable[bytes]:
|
||||||
|
if self.leaf:
|
||||||
|
for key_index in range(self.keys):
|
||||||
|
yield self.key_no(key_index)
|
||||||
|
else:
|
||||||
|
for index in range(self.length):
|
||||||
|
real_index, mode = divmod(index, 2)
|
||||||
|
if mode:
|
||||||
|
yield self.key_no(real_index)
|
||||||
|
else:
|
||||||
|
yield from resolver.resolve(self.child_no(real_index)).iter_keys(resolver)
|
||||||
|
|
||||||
|
|
||||||
|
class KeyView(Sequence[WeakReferenceIndexSetBTree]):
|
||||||
|
def __init__(self, wrisbt: WeakReferenceIndexSetBTree):
|
||||||
|
assert isinstance(wrisbt, WeakReferenceIndexSetBTree)
|
||||||
|
self.wrisbt = wrisbt
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.wrisbt.keys
|
||||||
|
|
||||||
|
def __getitem__(self, index: int) -> bytes:
|
||||||
|
return self.wrisbt.key_no(index)
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtFactory(RainbowFactory[WeakReferenceIndexSetBTree]):
|
||||||
|
def __init__(self, height: int, keymin: int, root: bool):
|
||||||
|
assert isinstance(height, int)
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
assert isinstance(root, bool)
|
||||||
|
assert height >= 0
|
||||||
|
self.height = height
|
||||||
|
assert keymin > 0
|
||||||
|
self.keymin = keymin
|
||||||
|
self.root = root
|
||||||
|
|
||||||
|
def from_bytes(self, source: bytes) -> WeakReferenceIndexSetBTree:
|
||||||
|
assert isinstance(source, bytes)
|
||||||
|
return WeakReferenceIndexSetBTree(
|
||||||
|
source,
|
||||||
|
self.height,
|
||||||
|
self.keymin,
|
||||||
|
self.root,
|
||||||
|
(Null(),) * (len(source) // (2 * HashPoint.HASH_LENGTH) + 1) if self.height else ()
|
||||||
|
)
|
45
rainbowadn/wrisbt/wrisbtchainprotocol.py
Normal file
45
rainbowadn/wrisbt/wrisbtchainprotocol.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
from typing import Generic, TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.blockchainprotocol import BlockChainProtocol
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
from rainbowadn.wrisbt.wrisbtindex import WrisbtIndex, WrisbtIndexFactory
|
||||||
|
from rainbowadn.wrisbt.wrisbtprotocol import WrisbtProtocol
|
||||||
|
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot, WrisbtRootFactory
|
||||||
|
|
||||||
|
__all__ = ('WrisbtChainProtocol',)
|
||||||
|
|
||||||
|
TargetType = TypeVar('TargetType')
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtChainProtocol(
|
||||||
|
BlockChainProtocol[
|
||||||
|
TargetType,
|
||||||
|
WrisbtIndex,
|
||||||
|
WrisbtRoot
|
||||||
|
],
|
||||||
|
Generic[TargetType]
|
||||||
|
):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
resolver: HashResolver,
|
||||||
|
total_factory: RainbowFactory[TargetType],
|
||||||
|
keymin: int
|
||||||
|
):
|
||||||
|
assert isinstance(total_factory, RainbowFactory)
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
assert keymin >= 2
|
||||||
|
self.keymin = keymin
|
||||||
|
super().__init__(
|
||||||
|
WrisbtProtocol(resolver, keymin),
|
||||||
|
total_factory,
|
||||||
|
WrisbtIndexFactory(keymin)
|
||||||
|
)
|
||||||
|
self.total_factory = total_factory
|
||||||
|
|
||||||
|
def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]:
|
||||||
|
return WrisbtRootFactory(self.keymin)
|
||||||
|
|
||||||
|
def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]:
|
||||||
|
return state.total
|
60
rainbowadn/wrisbt/wrisbtindex.py
Normal file
60
rainbowadn/wrisbt/wrisbtindex.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from typing import Iterable
|
||||||
|
|
||||||
|
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.nullability.null import Null
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
|
||||||
|
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot, WrisbtRootFactory
|
||||||
|
|
||||||
|
__all__ = ('WrisbtIndex', 'WrisbtIndexFactory',)
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtIndex(RecursiveMentionable):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
total: HashPoint[WrisbtRoot],
|
||||||
|
delta: HashPoint[WrisbtRoot],
|
||||||
|
keymin: int
|
||||||
|
):
|
||||||
|
assert isinstance(total, HashPoint)
|
||||||
|
assert isinstance(delta, HashPoint)
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
self.total = total
|
||||||
|
self.delta = delta
|
||||||
|
assert keymin >= 2
|
||||||
|
self.keymin = keymin
|
||||||
|
|
||||||
|
def points(self) -> Iterable[HashPoint]:
|
||||||
|
return [self.total, self.delta]
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
return bytes(self.total) + bytes(self.delta)
|
||||||
|
|
||||||
|
def __factory__(self) -> RainbowFactory['WrisbtIndex']:
|
||||||
|
return WrisbtIndexFactory(self.keymin)
|
||||||
|
|
||||||
|
def str(self, resolver: HashResolver, tab: int) -> str:
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(tab, int)
|
||||||
|
return f'(index)' \
|
||||||
|
f'{tabulate(tab)}{hash_point_format(self.total, resolver, tab)}' \
|
||||||
|
f'{tabulate(tab)}{hash_point_format(self.delta, resolver, tab)}'
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtIndexFactory(RainbowFactory[WrisbtIndex]):
|
||||||
|
def __init__(self, keymin: int):
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
assert keymin >= 2
|
||||||
|
self.keymin = keymin
|
||||||
|
self.root_factory: RainbowFactory[WrisbtRoot] = WrisbtRootFactory(keymin)
|
||||||
|
assert isinstance(self.root_factory, RainbowFactory)
|
||||||
|
|
||||||
|
def from_bytes(self, source: bytes) -> WrisbtIndex:
|
||||||
|
assert isinstance(source, bytes)
|
||||||
|
return WrisbtIndex(
|
||||||
|
HashPoint(self.root_factory, source[:HashPoint.HASH_LENGTH], Null()),
|
||||||
|
HashPoint(self.root_factory, source[HashPoint.HASH_LENGTH:], Null()),
|
||||||
|
self.keymin
|
||||||
|
)
|
52
rainbowadn/wrisbt/wrisbtprotocol.py
Normal file
52
rainbowadn/wrisbt/wrisbtprotocol.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from rainbowadn.chain.states.activestateprotocol import ActiveStateProtocol
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
|
from rainbowadn.wrisbt.wrisbtindex import WrisbtIndex
|
||||||
|
from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot
|
||||||
|
|
||||||
|
__all__ = ('WrisbtProtocol',)
|
||||||
|
|
||||||
|
TargetType = TypeVar('TargetType')
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtProtocol(ActiveStateProtocol[TargetType, WrisbtIndex]):
|
||||||
|
def __init__(self, resolver: HashResolver, keymin: int):
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
super().__init__(resolver)
|
||||||
|
assert keymin >= 2
|
||||||
|
self.keymin = keymin
|
||||||
|
|
||||||
|
def _initial_state(self) -> HashPoint[WrisbtIndex]:
|
||||||
|
return HashPoint.of(
|
||||||
|
WrisbtIndex(
|
||||||
|
HashPoint.of(WrisbtRoot.empty(self.keymin)),
|
||||||
|
HashPoint.of(WrisbtRoot.empty(self.keymin)),
|
||||||
|
self.keymin
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def _derive(
|
||||||
|
self,
|
||||||
|
previous: HashPoint[WrisbtIndex],
|
||||||
|
header: HashPoint[TargetType]
|
||||||
|
) -> HashPoint[WrisbtIndex]:
|
||||||
|
assert isinstance(previous, HashPoint)
|
||||||
|
assert isinstance(header, HashPoint)
|
||||||
|
index = self.resolver.resolve(previous)
|
||||||
|
assert isinstance(index, WrisbtIndex)
|
||||||
|
|
||||||
|
empty: WrisbtRoot = WrisbtRoot.empty(self.keymin)
|
||||||
|
assert isinstance(empty, WrisbtRoot)
|
||||||
|
total: WrisbtRoot = self.resolver.resolve(index.total)
|
||||||
|
assert isinstance(total, WrisbtRoot)
|
||||||
|
|
||||||
|
return HashPoint.of(
|
||||||
|
WrisbtIndex(
|
||||||
|
HashPoint.of(total.index(self.resolver, header, empty)),
|
||||||
|
HashPoint.of(empty.index(self.resolver, header, total)),
|
||||||
|
index.keymin
|
||||||
|
)
|
||||||
|
)
|
123
rainbowadn/wrisbt/wrisbtroot.py
Normal file
123
rainbowadn/wrisbt/wrisbtroot.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
from typing import Iterable, Optional
|
||||||
|
|
||||||
|
from rainbowadn.data.atomic.integer import Integer
|
||||||
|
from rainbowadn.wrisbt.weakreferenceindexsetbtree import WeakReferenceIndexSetBTree, WrisbtFactory
|
||||||
|
from rainbowadn.hashing.hash_point_format import hash_point_format, tabulate
|
||||||
|
from rainbowadn.hashing.hashmentionable import HashMentionable
|
||||||
|
from rainbowadn.hashing.hashpoint import HashPoint
|
||||||
|
from rainbowadn.hashing.hashresolver import HashResolver
|
||||||
|
from rainbowadn.hashing.nullability.notnull import NotNull
|
||||||
|
from rainbowadn.hashing.nullability.null import Null
|
||||||
|
from rainbowadn.hashing.rainbow_factory import RainbowFactory
|
||||||
|
from rainbowadn.hashing.recursivementionable import RecursiveMentionable
|
||||||
|
|
||||||
|
__all__ = ('WrisbtRoot','WrisbtRootFactory',)
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtRoot(RecursiveMentionable):
|
||||||
|
def __init__(self, root: HashPoint[WeakReferenceIndexSetBTree], height: int, keymin: int):
|
||||||
|
assert isinstance(root, HashPoint)
|
||||||
|
assert isinstance(height, int)
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
self.root = root
|
||||||
|
self.height = height
|
||||||
|
self.keymin = keymin
|
||||||
|
|
||||||
|
def points(self) -> Iterable[HashPoint]:
|
||||||
|
return [self.root]
|
||||||
|
|
||||||
|
def __bytes__(self):
|
||||||
|
return bytes(self.root) + bytes(Integer(self.height))
|
||||||
|
|
||||||
|
def __factory__(self) -> RainbowFactory['WrisbtRoot']:
|
||||||
|
return WrisbtRootFactory(self.keymin)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def empty(cls, keymin: int) -> 'WrisbtRoot':
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
return WrisbtRoot(HashPoint.of(WeakReferenceIndexSetBTree(b'', 0, keymin, True, ())), 0, keymin)
|
||||||
|
|
||||||
|
def str(self, resolver: HashResolver, tab: int) -> str:
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(tab, int)
|
||||||
|
return f'(root)' \
|
||||||
|
f'{tabulate(tab)}{self.height}' \
|
||||||
|
f'{tabulate(tab)}{hash_point_format(self.root, resolver, tab)}'
|
||||||
|
|
||||||
|
def contains(self, resolver: HashResolver, key: bytes) -> bool:
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(key, bytes)
|
||||||
|
assert len(key) == HashPoint.HASH_LENGTH
|
||||||
|
|
||||||
|
root: WeakReferenceIndexSetBTree = resolver.resolve(self.root)
|
||||||
|
assert isinstance(root, WeakReferenceIndexSetBTree)
|
||||||
|
|
||||||
|
return root.contains(resolver, key)
|
||||||
|
|
||||||
|
def add(self, resolver: HashResolver, key: bytes) -> 'WrisbtRoot':
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(key, bytes)
|
||||||
|
assert len(key) == HashPoint.HASH_LENGTH
|
||||||
|
|
||||||
|
root: WeakReferenceIndexSetBTree = resolver.resolve(self.root).add(resolver, key)
|
||||||
|
assert isinstance(root, WeakReferenceIndexSetBTree)
|
||||||
|
|
||||||
|
if root.full():
|
||||||
|
left, middle, right = root.split()
|
||||||
|
assert isinstance(left, WeakReferenceIndexSetBTree)
|
||||||
|
assert isinstance(middle, bytes)
|
||||||
|
assert isinstance(right, WeakReferenceIndexSetBTree)
|
||||||
|
root = WeakReferenceIndexSetBTree(
|
||||||
|
middle + bytes(HashPoint.of(left)) + bytes(HashPoint.of(right)),
|
||||||
|
root.height + 1,
|
||||||
|
root.keymin,
|
||||||
|
True,
|
||||||
|
(NotNull(left), NotNull(right))
|
||||||
|
)
|
||||||
|
assert isinstance(root, WeakReferenceIndexSetBTree)
|
||||||
|
return self.of(root)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def of(cls, root: WeakReferenceIndexSetBTree) -> 'WrisbtRoot':
|
||||||
|
assert isinstance(root, WeakReferenceIndexSetBTree)
|
||||||
|
return cls(HashPoint.of(root), root.height, root.keymin)
|
||||||
|
|
||||||
|
def keys(self, resolver: HashResolver) -> list[bytes]:
|
||||||
|
return list(resolver.resolve(self.root).iter_keys(resolver))
|
||||||
|
|
||||||
|
def index(
|
||||||
|
self, resolver: HashResolver, target: HashPoint, exclude: Optional['WrisbtRoot']
|
||||||
|
) -> 'WrisbtRoot':
|
||||||
|
assert isinstance(resolver, HashResolver)
|
||||||
|
assert isinstance(target, HashPoint)
|
||||||
|
if exclude is None:
|
||||||
|
exclude = self.empty(self.keymin)
|
||||||
|
assert isinstance(exclude, WrisbtRoot)
|
||||||
|
key: bytes = target.point
|
||||||
|
assert isinstance(key, bytes)
|
||||||
|
if exclude.contains(resolver, key) or self.contains(resolver, key):
|
||||||
|
return self
|
||||||
|
tree = self
|
||||||
|
value: HashMentionable = resolver.resolve(target)
|
||||||
|
assert isinstance(value, HashMentionable)
|
||||||
|
if isinstance(value, RecursiveMentionable):
|
||||||
|
for hash_point in value.points():
|
||||||
|
tree = tree.index(resolver, hash_point, exclude)
|
||||||
|
tree = tree.add(resolver, key)
|
||||||
|
return tree
|
||||||
|
|
||||||
|
|
||||||
|
class WrisbtRootFactory(RainbowFactory[WrisbtRoot]):
|
||||||
|
def __init__(self, keymin: int):
|
||||||
|
assert isinstance(keymin, int)
|
||||||
|
self.keymin = keymin
|
||||||
|
|
||||||
|
def from_bytes(self, source: bytes) -> WrisbtRoot:
|
||||||
|
assert isinstance(source, bytes)
|
||||||
|
height: int = Integer.from_bytes(source[HashPoint.HASH_LENGTH:]).integer
|
||||||
|
assert isinstance(height, int)
|
||||||
|
return WrisbtRoot(
|
||||||
|
HashPoint(WrisbtFactory(height, self.keymin, True), source[:HashPoint.HASH_LENGTH], Null()),
|
||||||
|
height,
|
||||||
|
self.keymin
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user