Commit 67b92578 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent ed20c2a7
...@@ -420,20 +420,55 @@ def TopoEncode(tree): ...@@ -420,20 +420,55 @@ def TopoEncode(tree):
return topo return topo
# _Range represents a range under which a node is placed in its tree.
class _Range:
# .klo
# .khi
def __init__(r, klo, khi):
assert klo <= khi
r.klo = klo
r.khi = khi
def __hash__(r):
return hash(r.klo) ^ hash(r.khi)
def __ne__(a, b):
return not (a == b)
def __eq__(a, b):
if not isinstance(b, _Range):
return False
return (a.klo == b.klo) and (a.khi == b.khi)
# _NodeInRange represents a node (node or znode) coming under range in its tree.
class _NodeInRange:
# .range
# .node
def __init__(nr, r, node):
nr.range = r
nr.node = node
# _walkBFS walks tree in breadth-first order layer by layer. # _walkBFS walks tree in breadth-first order layer by layer.
def _walkBFS(tree): # i[] of [](of nodes on each level) def _walkBFS(tree): # i[] of [](of nodes on each level)
for level in __walkBFS(tree):
yield tuple(rn.node for rn in level)
def __walkBFS(tree): # i[] of [](of _NodeInRange)
assert isinstance(tree, Tree) assert isinstance(tree, Tree)
currentq = [] currentq = []
nextq = [tree] nextq = [_NodeInRange(_Range(-inf,+inf), tree)]
while len(nextq) > 0: while len(nextq) > 0:
yield tuple(nextq) yield tuple(nextq)
currentq = nextq currentq = nextq
nextq = [] nextq = []
while len(currentq) > 0: while len(currentq) > 0:
node = currentq.pop(0) rn = currentq.pop(0)
assert isinstance(node, (Tree, Bucket)) assert isinstance(rn.node, (Tree, Bucket))
if isinstance(node, Tree): if isinstance(rn.node, Tree):
nextq += node.children v = (rn.range.klo,) + rn.node.keyv + (rn.range.khi,)
rv = zip(v[:-1], v[1:]) # (klo,k1), (k1,k2), ..., (kN,khi)
assert len(rv) == len(rn.node.children)
for i in range(len(rv)):
nextq.append(_NodeInRange(_Range(*rv[i]), rn.node.children[i]))
# _zwalkBFS, similarly to _walkBFS, walks ZODB BTree in breadth-first order layer by layer. # _zwalkBFS, similarly to _walkBFS, walks ZODB BTree in breadth-first order layer by layer.
def _zwalkBFS(ztree): # i[] of [](of nodes on each level) def _zwalkBFS(ztree): # i[] of [](of nodes on each level)
......
...@@ -26,6 +26,7 @@ from BTrees.LOBTree import LOBTree, LOBucket ...@@ -26,6 +26,7 @@ from BTrees.LOBTree import LOBTree, LOBucket
from BTrees.tests import testBTrees from BTrees.tests import testBTrees
from BTrees import check as bcheck from BTrees import check as bcheck
from persistent import Persistent from persistent import Persistent
inf = float('inf')
def test_structureOf(): def test_structureOf():
T = xbtree.Tree T = xbtree.Tree
...@@ -397,28 +398,35 @@ def test_restructure(): ...@@ -397,28 +398,35 @@ def test_restructure():
def test_walkBFS(): def test_walkBFS():
T = xbtree.Tree T = xbtree.Tree
B = xbtree.Bucket B = xbtree.Bucket
R = xbtree._Range
bl = B(); br = B() bl = B(); br = B()
tl = T([], bl) tl = T([], bl)
tr = T([], br) tr = T([], br)
t = T([0], tl, tr) t = T([0], tl, tr)
walkv = list(xbtree._walkBFS(t)) walkv = list(xbtree.__walkBFS(t))
assert len(walkv) == 3 # (t) (tl, tr), (bl, br) assert len(walkv) == 3 # (t) (tl, tr), (bl, br)
_ = walkv[0] _ = walkv[0]
assert len(_) == 1 assert len(_) == 1
assert _[0] is t assert _[0].range == R(-inf, inf)
assert _[0].node is t
_ = walkv[1] _ = walkv[1]
assert len(_) == 2 assert len(_) == 2
assert _[0] is tl assert _[0].range == R(-inf, 0)
assert _[1] is tr assert _[0].node is tl
assert _[1].range == R(0, inf)
assert _[1].node is tr
_ = walkv[2] _ = walkv[2]
assert len(_) == 2 assert len(_) == 2
assert _[0] is bl assert _[0].range == R(-inf, 0)
assert _[1] is br assert _[0].node is bl
assert _[1].range == R(0, inf)
assert _[1].node is br
# XXX more tests? # XXX more tests?
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment