Commit cb93b11f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent bef6285c
...@@ -148,8 +148,9 @@ class Tree(object): ...@@ -148,8 +148,9 @@ class Tree(object):
# copy returns a deep copy of the tree. # copy returns a deep copy of the tree.
def copy(t): # if onlyKeys=Y buckets in returned tree will contain only keys not values.
return Tree(t.keyv, *[_.copy() for _ in t.children]) def copy(t, onlyKeys=False):
return Tree(t.keyv, *[_.copy(onlyKeys) for _ in t.children])
# firstbucket returns Bucket reachable through leftmost child links. # firstbucket returns Bucket reachable through leftmost child links.
def firstbucket(t): def firstbucket(t):
...@@ -194,19 +195,23 @@ class Bucket(object): ...@@ -194,19 +195,23 @@ class Bucket(object):
return "B" + ','.join(kvv) return "B" + ','.join(kvv)
__repr__ = __str__ __repr__ = __str__
def copy(b): def copy(b, onlyKeys=False):
if onlyKeys:
return Bucket(b.keyv, None)
else:
return Bucket(b.keyv, b.valuev) return Bucket(b.keyv, b.valuev)
# StructureOf returns internal structure of a ZODB BTree. # StructureOf returns internal structure of a ZODB BTree.
# #
# The structure is represented as Tree and Bucket nodes. # The structure is represented as Tree and Bucket nodes.
def StructureOf(znode): # If onlyKeys=Y values of the tree are not represented in returned structure.
def StructureOf(znode, onlyKeys=False):
ztype = _zclassify(znode) ztype = _zclassify(znode)
if ztype.is_zbucket: if ztype.is_zbucket:
keys, values = zbcheck.crack_bucket(znode, ztype.is_map) keys, values = zbcheck.crack_bucket(znode, ztype.is_map)
if not ztype.is_map: if (not ztype.is_map) or onlyKeys:
return Bucket(keys, None) return Bucket(keys, None)
else: else:
return Bucket(keys, values) return Bucket(keys, values)
...@@ -214,15 +219,15 @@ def StructureOf(znode): ...@@ -214,15 +219,15 @@ def StructureOf(znode):
if ztype.is_ztree: if ztype.is_ztree:
kind, keys, children = zbcheck.crack_btree(znode, ztype.is_map) kind, keys, children = zbcheck.crack_btree(znode, ztype.is_map)
if kind == zbcheck.BTREE_EMPTY: if kind == zbcheck.BTREE_EMPTY:
return Tree([], Bucket([], [] if ztype.is_map else None)) return Tree([], Bucket([], [] if (ztype.is_map or not onlyKeys) else None))
if kind == zbcheck.BTREE_ONE: if kind == zbcheck.BTREE_ONE:
b = znode._bucket_type() b = znode._bucket_type()
b.__setstate__(keys) # it is keys+values for BTREE_ONE case b.__setstate__(keys) # it is keys+values for BTREE_ONE case
return Tree([], StructureOf(b)) return Tree([], StructureOf(b, onlyKeys))
if kind == zbcheck.BTREE_NORMAL: if kind == zbcheck.BTREE_NORMAL:
return Tree(keys, *[StructureOf(_) for _ in children]) return Tree(keys, *[StructureOf(_, onlyKeys) for _ in children])
panic("bad tree kind %r" % kind) panic("bad tree kind %r" % kind)
...@@ -232,6 +237,8 @@ def StructureOf(znode): ...@@ -232,6 +237,8 @@ def StructureOf(znode):
# Restructure reorganizes ZODB BTree instance (not Tree) according to specified # Restructure reorganizes ZODB BTree instance (not Tree) according to specified
# topology structure. # topology structure.
# #
# The new structure should be given with buckets without values. XXX should -> can?
#
# NOTE ZODB BTree package does not tolerate structures with empty BTree nodes # NOTE ZODB BTree package does not tolerate structures with empty BTree nodes
# except for the sole single case of empty tree. # except for the sole single case of empty tree.
@func @func
...@@ -285,9 +292,9 @@ def Restructure(ztree, newStructure): ...@@ -285,9 +292,9 @@ def Restructure(ztree, newStructure):
# we will modify nodes from new set: # we will modify nodes from new set:
# - node.Z will point to associated znode # - node.Z will point to associated znode
# - bucket.next_bucket will point to bucket that is coming with next keys in the tree # - bucket.next_bucket will point to bucket that is coming with next keys in the tree
tnew = newStructure.copy() tnew = newStructure.copy() # XXX onlyKeys=True ?
# assign assignes tree nodes from RNv to ztree nodes from RZv in optimal way. # assign assigns tree nodes from RNv to ztree nodes from RZv in optimal way.
# Bj ∈ RNv is mapped into Ai ∈ RZv such that that sum_j D(A_i, Bj) is minimal. # Bj ∈ RNv is mapped into Ai ∈ RZv such that that sum_j D(A_i, Bj) is minimal.
# it is used to associate nodes in tnew to ztree nodes. # it is used to associate nodes in tnew to ztree nodes.
def assign(RZv, RNv): def assign(RZv, RNv):
...@@ -493,7 +500,7 @@ def Restructure(ztree, newStructure): ...@@ -493,7 +500,7 @@ def Restructure(ztree, newStructure):
assert len(kv) == 0 # all keys must have been popped assert len(kv) == 0 # all keys must have been popped
_zbcheck(ztree) # verify ztree after our tweaks _zbcheck(ztree) # verify ztree after our tweaks
tstruct = StructureOf(ztree) tstruct = StructureOf(ztree, onlyKeys=True)
if tstruct != newStructure: if tstruct != newStructure:
panic("BUG: Restructure: result structure is not what was" panic("BUG: Restructure: result structure is not what was"
" requested:\n%s\n\nwant:\n%s" % (tstruct, newStructure)) " requested:\n%s\n\nwant:\n%s" % (tstruct, newStructure))
......
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