diff --git a/main.py b/main.py index 08a10c3..f970217 100644 --- a/main.py +++ b/main.py @@ -25,6 +25,7 @@ from rainbowadn.v13.bankchain import BankChain from rainbowadn.v13.subject import Subject from rainbowadn.v13.transaction import CoinData, Transaction from rainbowadn.wrisbt.wrisbtchainprotocol import WrisbtChainProtocol +from rainbowadn.wrisbt.wrisbtparametres import WrisbtParametres from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot @@ -93,21 +94,19 @@ def main1(): stoptime = now dr = DumbResolver() - btree = WrisbtRoot.empty(16) + btree = WrisbtRoot.empty(WrisbtParametres(1, 5)) 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'))) + key = os.urandom(5) + assert not btree.contains(dr, key) + btree = btree.add(dr, key) + assert btree.contains(dr, key) 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') + measure('resolve') def main2(): @@ -134,4 +133,4 @@ def main(): if __name__ == '__main__': - main() + main1() diff --git a/rainbowadn/data/collection/trees/comparison/plaincomparator.py b/rainbowadn/data/collection/trees/comparison/plaincomparator.py index 986e6fd..40418c5 100644 --- a/rainbowadn/data/collection/trees/comparison/plaincomparator.py +++ b/rainbowadn/data/collection/trees/comparison/plaincomparator.py @@ -13,7 +13,7 @@ class PlainComparator(ProtocolComparator[Plain]): original_value: Plain = self.resolver.resolve(original) assert isinstance(original_value, Plain) key_value: Plain = self.resolver.resolve(key) - assert isinstance(key, Plain) + assert isinstance(key_value, Plain) if key_value.source < original_value.source: return Left() elif key_value.source > original_value.source: diff --git a/rainbowadn/wrisbt/weakreferenceindexsetbtree.py b/rainbowadn/wrisbt/weakreferenceindexsetbtree.py index 9fd6fb8..207a502 100644 --- a/rainbowadn/wrisbt/weakreferenceindexsetbtree.py +++ b/rainbowadn/wrisbt/weakreferenceindexsetbtree.py @@ -12,54 +12,55 @@ from rainbowadn.hashing.recursivementionable import RecursiveMentionable __all__ = ('WeakReferenceIndexSetBTree', 'WrisbtFactory',) +from rainbowadn.wrisbt.wrisbtparametres import WrisbtParametres + class WeakReferenceIndexSetBTree(RecursiveMentionable): def __init__( self, source: bytes, height: int, - keymin: int, + parametres: WrisbtParametres, root: bool, - cache: tuple[Nullable['WeakReferenceIndexSetBTree'], ...] + cache: tuple[HashPoint['WeakReferenceIndexSetBTree'], ...] ): assert isinstance(source, bytes) assert isinstance(height, int) - assert isinstance(keymin, int) + assert isinstance(parametres, WrisbtParametres) assert isinstance(root, bool) assert isinstance(cache, tuple) - self.length = len(source) // HashPoint.HASH_LENGTH - assert len(source) == self.length * HashPoint.HASH_LENGTH + self.length = len(source) self.source = source assert height >= 0 self.height = height self.leaf = height == 0 - self.empty = self.length == 0 + self.empty = not self.source if self.empty: assert self.leaf if self.leaf: - self.keys = self.length + self.keys = self.length // parametres.keysize self.children = 0 else: - self.keys = self.length // 2 + self.keys = self.length // (parametres.keysize + HashPoint.HASH_LENGTH) self.children = self.keys + 1 - assert self.length == self.keys + self.children - - assert keymin > 0 - self.keymin = keymin + assert self.length == self.keys * parametres.keysize + self.children * HashPoint.HASH_LENGTH + self.parametres = parametres + self.keymin = parametres.keymin + self.keysize = parametres.keysize self.root = root if not root: - assert keymin <= self.keys - assert self.keys <= 2 * keymin + 1 + assert self.keymin <= self.keys + assert self.keys <= 2 * self.keymin + 1 + + self.keyend = self.keys * self.keysize assert len(cache) == self.children - child_index: int - cached: Nullable[WeakReferenceIndexSetBTree] self.cache = cache if self.balanced(): @@ -71,15 +72,15 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): def full(self) -> bool: return self.keys == 2 * self.keymin + 1 - def bytes_no(self, index: int) -> bytes: + def bytes_no(self, index: int, start: int, size: int) -> bytes: assert isinstance(index, int) assert 0 <= index < self.length - return self.source[HashPoint.HASH_LENGTH * index:HashPoint.HASH_LENGTH * (index + 1)] + return self.source[start + size * index:start + size * (index + 1)] def key_no(self, index: int) -> bytes: assert isinstance(index, int) assert 0 <= index < self.keys - return self.bytes_no(index) + return self.bytes_no(index, 0, self.keysize) def cached_no(self, index: int) -> Nullable['WeakReferenceIndexSetBTree']: assert isinstance(index, int) @@ -89,7 +90,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): assert isinstance(cached, Nullable) if isinstance(cached, NotNull): tree: WeakReferenceIndexSetBTree = cached.value - assert self.bytes_no(self.keys + index) == tree.hash_point().point + assert self.bytes_no(index, self.keyend, HashPoint.HASH_LENGTH) == tree.hash_point().point return cached def child_no(self, index: int) -> HashPoint['WeakReferenceIndexSetBTree']: @@ -97,8 +98,8 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): assert 0 <= index < self.children assert not self.leaf return HashPoint( - WrisbtFactory(self.height - 1, self.keymin, False), - self.bytes_no(self.keys + index), + WrisbtFactory(self.height - 1, self.parametres, False), + self.bytes_no(index, self.keyend, HashPoint.HASH_LENGTH), self.cached_no(index) ) @@ -117,11 +118,11 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): return self.source def __topology_hash__(self) -> bytes: - return HashPoint.hash(self.source[self.keys * HashPoint.HASH_LENGTH:]) + return HashPoint.hash(self.source[self.keyend:]) def __factory__(self) -> RainbowFactory['WeakReferenceIndexSetBTree']: assert self.balanced() - return WrisbtFactory(self.height, self.keymin, self.root) + return WrisbtFactory(self.height, self.parametres, self.root) def range(self, left: int, right: int) -> 'WeakReferenceIndexSetBTree': assert isinstance(left, int) @@ -131,21 +132,21 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): assert isinstance(hl, int) if self.leaf: return WeakReferenceIndexSetBTree( - self.source[hl * left:hl * right], + self.source[self.keysize * left:self.keysize * right], 0, - self.keymin, + self.parametres, False, () ) else: - keybytes: bytes = self.source[hl * left:hl * right] + keybytes: bytes = self.source[self.keysize * left:self.keysize * right] assert isinstance(keybytes, bytes) - childbytes: bytes = self.source[hl * (self.keys + left):hl * (self.keys + right + 1)] + childbytes: bytes = self.source[self.keyend + hl * left:self.keyend + hl * (right + 1)] assert isinstance(childbytes, bytes) return WeakReferenceIndexSetBTree( keybytes + childbytes, self.height, - self.keymin, + self.parametres, False, self.cache[left:right + 1], ) @@ -175,9 +176,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): 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 len(key) == self.keysize assert self.balanced() @@ -199,9 +198,7 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): 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 len(key) == self.keysize assert self.balanced() @@ -216,9 +213,9 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): assert key > self.key_no(index - 1) if self.leaf: return WeakReferenceIndexSetBTree( - self.source[:hl * index] + key + self.source[hl * index:], + self.source[:self.keysize * index] + key + self.source[self.keysize * index:], self.height, - self.keymin, + self.parametres, self.root, () ) @@ -233,34 +230,34 @@ class WeakReferenceIndexSetBTree(RecursiveMentionable): assert isinstance(right, WeakReferenceIndexSetBTree) return WeakReferenceIndexSetBTree( ( - self.source[:hl * index] + self.source[:self.keysize * index] + middle + - self.source[hl * index:hl * (self.keys + index)] + self.source[self.keysize * index:self.keyend + HashPoint.HASH_LENGTH * index] + bytes(left.hash_point()) + bytes(right.hash_point()) + - self.source[hl * (self.keys + index + 1):] + self.source[self.keyend + HashPoint.HASH_LENGTH * (index + 1):] ), self.height, - self.keymin, + self.parametres, self.root, self.cache[:index] + (NotNull(left), NotNull(right)) + self.cache[index + 1:] ) else: return WeakReferenceIndexSetBTree( ( - self.source[:hl * (self.keys + index)] + self.source[:self.keyend + HashPoint.HASH_LENGTH * index] + bytes(HashPoint.of(child)) + - self.source[hl * (self.keys + index + 1):] + self.source[self.keyend + HashPoint.HASH_LENGTH * (index + 1):] ), self.height, - self.keymin, + self.parametres, self.root, self.cache[:index] + (NotNull(child),) + self.cache[index + 1:] ) @@ -291,14 +288,13 @@ class KeyView(Sequence[WeakReferenceIndexSetBTree]): class WrisbtFactory(RainbowFactory[WeakReferenceIndexSetBTree]): - def __init__(self, height: int, keymin: int, root: bool): + def __init__(self, height: int, parametres: WrisbtParametres, root: bool): assert isinstance(height, int) - assert isinstance(keymin, int) + assert isinstance(parametres, WrisbtParametres) assert isinstance(root, bool) assert height >= 0 self.height = height - assert keymin > 0 - self.keymin = keymin + self.parametres = parametres self.root = root def from_bytes(self, source: bytes) -> WeakReferenceIndexSetBTree: @@ -306,7 +302,7 @@ class WrisbtFactory(RainbowFactory[WeakReferenceIndexSetBTree]): return WeakReferenceIndexSetBTree( source, self.height, - self.keymin, + self.parametres, self.root, - (Null(),) * (len(source) // (2 * HashPoint.HASH_LENGTH) + 1) if self.height else () + (Null(),) * (len(source) // (HashPoint.HASH_LENGTH + self.parametres.keysize) + 1) if self.height else () ) diff --git a/rainbowadn/wrisbt/wrisbtchainprotocol.py b/rainbowadn/wrisbt/wrisbtchainprotocol.py index 20d0857..b02f292 100644 --- a/rainbowadn/wrisbt/wrisbtchainprotocol.py +++ b/rainbowadn/wrisbt/wrisbtchainprotocol.py @@ -5,6 +5,7 @@ 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.wrisbtparametres import WrisbtParametres from rainbowadn.wrisbt.wrisbtprotocol import WrisbtProtocol from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot, WrisbtRootFactory @@ -39,7 +40,7 @@ class WrisbtChainProtocol( self.total_factory = total_factory def actual_state_factory(self) -> RainbowFactory[WrisbtRoot]: - return WrisbtRootFactory(self.keymin) + return WrisbtRootFactory(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH)) def actual_state(self, state: WrisbtIndex) -> HashPoint[WrisbtRoot]: return state.total diff --git a/rainbowadn/wrisbt/wrisbtindex.py b/rainbowadn/wrisbt/wrisbtindex.py index c907d13..0cecad1 100644 --- a/rainbowadn/wrisbt/wrisbtindex.py +++ b/rainbowadn/wrisbt/wrisbtindex.py @@ -6,6 +6,7 @@ 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.wrisbtparametres import WrisbtParametres from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot, WrisbtRootFactory __all__ = ('WrisbtIndex', 'WrisbtIndexFactory',) @@ -48,7 +49,9 @@ class WrisbtIndexFactory(RainbowFactory[WrisbtIndex]): assert isinstance(keymin, int) assert keymin >= 2 self.keymin = keymin - self.root_factory: RainbowFactory[WrisbtRoot] = WrisbtRootFactory(keymin) + self.root_factory: RainbowFactory[WrisbtRoot] = WrisbtRootFactory( + WrisbtParametres(keymin, HashPoint.HASH_LENGTH) + ) assert isinstance(self.root_factory, RainbowFactory) def from_bytes(self, source: bytes) -> WrisbtIndex: diff --git a/rainbowadn/wrisbt/wrisbtparametres.py b/rainbowadn/wrisbt/wrisbtparametres.py new file mode 100644 index 0000000..1d9c6db --- /dev/null +++ b/rainbowadn/wrisbt/wrisbtparametres.py @@ -0,0 +1,11 @@ +__all__ = ('WrisbtParametres',) + + +class WrisbtParametres: + def __init__(self, keymin: int, keysize: int): + assert isinstance(keymin, int) + assert isinstance(keysize, int) + assert keymin > 0 + assert keysize > 0 + self.keymin = keymin + self.keysize = keysize diff --git a/rainbowadn/wrisbt/wrisbtprotocol.py b/rainbowadn/wrisbt/wrisbtprotocol.py index 5450884..f4911bd 100644 --- a/rainbowadn/wrisbt/wrisbtprotocol.py +++ b/rainbowadn/wrisbt/wrisbtprotocol.py @@ -4,6 +4,7 @@ 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.wrisbtparametres import WrisbtParametres from rainbowadn.wrisbt.wrisbtroot import WrisbtRoot __all__ = ('WrisbtProtocol',) @@ -15,15 +16,15 @@ 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 + super().__init__(resolver) def _initial_state(self) -> HashPoint[WrisbtIndex]: return HashPoint.of( WrisbtIndex( - HashPoint.of(WrisbtRoot.empty(self.keymin)), - HashPoint.of(WrisbtRoot.empty(self.keymin)), + HashPoint.of(WrisbtRoot.empty(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH))), + HashPoint.of(WrisbtRoot.empty(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH))), self.keymin ) ) @@ -38,7 +39,7 @@ class WrisbtProtocol(ActiveStateProtocol[TargetType, WrisbtIndex]): index = self.resolver.resolve(previous) assert isinstance(index, WrisbtIndex) - empty: WrisbtRoot = WrisbtRoot.empty(self.keymin) + empty: WrisbtRoot = WrisbtRoot.empty(WrisbtParametres(self.keymin, HashPoint.HASH_LENGTH)) assert isinstance(empty, WrisbtRoot) total: WrisbtRoot = self.resolver.resolve(index.total) assert isinstance(total, WrisbtRoot) diff --git a/rainbowadn/wrisbt/wrisbtroot.py b/rainbowadn/wrisbt/wrisbtroot.py index 5495177..678bfe8 100644 --- a/rainbowadn/wrisbt/wrisbtroot.py +++ b/rainbowadn/wrisbt/wrisbtroot.py @@ -1,7 +1,6 @@ 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 @@ -10,18 +9,21 @@ 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 +from rainbowadn.wrisbt.weakreferenceindexsetbtree import WeakReferenceIndexSetBTree, WrisbtFactory -__all__ = ('WrisbtRoot','WrisbtRootFactory',) +__all__ = ('WrisbtRoot', 'WrisbtRootFactory',) + +from rainbowadn.wrisbt.wrisbtparametres import WrisbtParametres class WrisbtRoot(RecursiveMentionable): - def __init__(self, root: HashPoint[WeakReferenceIndexSetBTree], height: int, keymin: int): + def __init__(self, root: HashPoint[WeakReferenceIndexSetBTree], height: int, parametres: WrisbtParametres): assert isinstance(root, HashPoint) assert isinstance(height, int) - assert isinstance(keymin, int) + assert isinstance(parametres, WrisbtParametres) self.root = root self.height = height - self.keymin = keymin + self.parametres = parametres def points(self) -> Iterable[HashPoint]: return [self.root] @@ -30,12 +32,12 @@ class WrisbtRoot(RecursiveMentionable): return bytes(self.root) + bytes(Integer(self.height)) def __factory__(self) -> RainbowFactory['WrisbtRoot']: - return WrisbtRootFactory(self.keymin) + return WrisbtRootFactory(self.parametres) @classmethod - def empty(cls, keymin: int) -> 'WrisbtRoot': - assert isinstance(keymin, int) - return WrisbtRoot(HashPoint.of(WeakReferenceIndexSetBTree(b'', 0, keymin, True, ())), 0, keymin) + def empty(cls, parametres: WrisbtParametres) -> 'WrisbtRoot': + assert isinstance(parametres, WrisbtParametres) + return WrisbtRoot(HashPoint.of(WeakReferenceIndexSetBTree(b'', 0, parametres, True, ())), 0, parametres) def str(self, resolver: HashResolver, tab: int) -> str: assert isinstance(resolver, HashResolver) @@ -47,7 +49,7 @@ class WrisbtRoot(RecursiveMentionable): def contains(self, resolver: HashResolver, key: bytes) -> bool: assert isinstance(resolver, HashResolver) assert isinstance(key, bytes) - assert len(key) == HashPoint.HASH_LENGTH + assert len(key) == self.parametres.keysize root: WeakReferenceIndexSetBTree = resolver.resolve(self.root) assert isinstance(root, WeakReferenceIndexSetBTree) @@ -57,7 +59,7 @@ class WrisbtRoot(RecursiveMentionable): def add(self, resolver: HashResolver, key: bytes) -> 'WrisbtRoot': assert isinstance(resolver, HashResolver) assert isinstance(key, bytes) - assert len(key) == HashPoint.HASH_LENGTH + assert len(key) == self.parametres.keysize root: WeakReferenceIndexSetBTree = resolver.resolve(self.root).add(resolver, key) assert isinstance(root, WeakReferenceIndexSetBTree) @@ -70,7 +72,7 @@ class WrisbtRoot(RecursiveMentionable): root = WeakReferenceIndexSetBTree( middle + bytes(HashPoint.of(left)) + bytes(HashPoint.of(right)), root.height + 1, - root.keymin, + root.parametres, True, (NotNull(left), NotNull(right)) ) @@ -80,7 +82,7 @@ class WrisbtRoot(RecursiveMentionable): @classmethod def of(cls, root: WeakReferenceIndexSetBTree) -> 'WrisbtRoot': assert isinstance(root, WeakReferenceIndexSetBTree) - return cls(HashPoint.of(root), root.height, root.keymin) + return cls(HashPoint.of(root), root.height, root.parametres) def keys(self, resolver: HashResolver) -> list[bytes]: return list(resolver.resolve(self.root).iter_keys(resolver)) @@ -91,7 +93,7 @@ class WrisbtRoot(RecursiveMentionable): assert isinstance(resolver, HashResolver) assert isinstance(target, HashPoint) if exclude is None: - exclude = self.empty(self.keymin) + exclude = self.empty(self.parametres) assert isinstance(exclude, WrisbtRoot) key: bytes = target.point assert isinstance(key, bytes) @@ -108,16 +110,16 @@ class WrisbtRoot(RecursiveMentionable): class WrisbtRootFactory(RainbowFactory[WrisbtRoot]): - def __init__(self, keymin: int): - assert isinstance(keymin, int) - self.keymin = keymin + def __init__(self, parametres: WrisbtParametres): + assert isinstance(parametres, WrisbtParametres) + self.parametres = parametres 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()), + HashPoint(WrisbtFactory(height, self.parametres, True), source[:HashPoint.HASH_LENGTH], Null()), height, - self.keymin + self.parametres )