Commit 517ec668 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 46d7baf4
......@@ -376,42 +376,46 @@ def Restructure(ztree, newStructure):
for i in range(len(rbucketv)-1):
assert rbucketv[i].range.khi <= rbucketv[i+1].klo
rbucketv[i] .node.next_bucket = rbucketv[i+1].node
rbucketv[i+1].node.prev_bucket = rbucketv[i] .node
rbucketv[-1].node.next_bucket = None
rbucketv[0] .node.prev_bucket = None
# associate every bucket to zbucket
assign(zrbucketv, rbucketv)
# set znode states according to established tnew->znode association
# bucket.embedded_in_tree will indicate that this bucket's state was
# embedded into containing tree node.
for rb in rbucketv:
rb.node.embedded_in_tree = False
rlevelv = rlevelv_orig
for rnodev in reversed(rlevelv):
for rnodev in rlevelv:
for rn in rnodev:
node = rn.node
assert isinstance(node, (Tree,Bucket))
# https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/BTreeTemplate.c#L1087
if isinstance(node, Tree):
# special case for empty tree and tree with just one bucket without oid.
#
# we cannot special case e.g. T/T/B because on loading ZODB
# wants to have !NULL T.firstbucket, and so if T/B is
# represented as empty or as T with embedded B, for top-level T
# there won't be a way to link to firstbucket and
# Tree.__setstate__ will raise "TypeError: No firstbucket in
# non-empty BTree".
zstate = unset = object()
if len(node.keyv) == 0:
child = node.children[0]
if isinstance(child, Bucket):
# empty bucket noone links to
if len(child.keyv) == 0 and child.prev_bucket is None:
zstate = None # -> empty tree
child.embedded_in_tree = True
# tree with single bucket noone links to
elif child.Z._p_oid is None and child.prev_bucket is None:
zstate = ((child.Z.__getstate__(),),) # tree with bucket without oid
child.embedded_in_tree = True
if len(rlevelv) == 2: # only 2 levels
assert len(rlevelv[0]) == 1 # top-one has empty tree
assert rlevelv[0][0].node is node
child = node.children[0] # bottom-on has 1 bucket
assert isinstance(child, Bucket)
assert len(rlevelv[1]) == 1
assert rlevelv[1][0].node is child
# empty bucket -> empty tree
if len(child.keyv) == 0:
zstate = None
# tree with single bucket withou oid -> tree with embedded bucket
elif child.Z._p_oid is None:
zstate = ((child.Z.__getstate__(),),)
if zstate is unset:
# normal tree node
......@@ -423,15 +427,10 @@ def Restructure(ztree, newStructure):
zstate = (zstate,)
# firstbucket
firstbucket = node.firstbucket()
print('firstbucket: %s (embedded: %s)' % (firstbucket, firstbucket.embedded_in_tree))
if not firstbucket.embedded_in_tree:
zstate += (firstbucket.Z,)
zstate += (node.firstbucket().Z,)
# https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/BucketTemplate.c#L1195
if isinstance(node, Bucket):
# ignore .embedded_in_tree - wrt tree it won't make a
# difference if we change an object not reachable through it.
zstate = ()
for k in node.keyv:
zstate += (k, kv.pop(k)) # (k1, v1, k2, v2, ..., kN, vN)
......
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