scripts: Changed most tree renderers to be pseudo-standalone
I'm trying to avoid having classes with different implementations across scripts, as it makes updating things error-prone, but at same time copying all the tree renderers to all dbg scripts would be a bit much. Monkey-patching the TreeArt class in relevant scripts seems like a reasonable compromise.
This commit is contained in:
+136
-132
@@ -1516,151 +1516,155 @@ class TreeArt:
|
||||
|
||||
return '%s ' % ''.join(trunk)
|
||||
|
||||
# some more renderers
|
||||
# some more renderers
|
||||
|
||||
# render a btree rbyd tree for debugging
|
||||
@classmethod
|
||||
def _frombtreertree(cls, btree, *,
|
||||
depth=None,
|
||||
inner=False,
|
||||
**args):
|
||||
# precompute rbyd trees so we know the max depth at each layer
|
||||
# to nicely align trees
|
||||
rtrees = {}
|
||||
rdepths = {}
|
||||
for bid, rbyd, path in btree.traverse(path=True, depth=depth):
|
||||
if not rbyd:
|
||||
continue
|
||||
# render a btree rbyd tree for debugging
|
||||
@classmethod
|
||||
def _treeartfrombtreertree(cls, btree, *,
|
||||
depth=None,
|
||||
inner=False,
|
||||
**args):
|
||||
# precompute rbyd trees so we know the max depth at each layer
|
||||
# to nicely align trees
|
||||
rtrees = {}
|
||||
rdepths = {}
|
||||
for bid, rbyd, path in btree.traverse(path=True, depth=depth):
|
||||
if not rbyd:
|
||||
continue
|
||||
|
||||
rtree = cls.fromrbyd(rbyd, **args)
|
||||
rtrees[rbyd] = rtree
|
||||
rdepths[len(path)] = max(rdepths.get(len(path), 0), rtree.depth)
|
||||
rtree = cls.fromrbyd(rbyd, **args)
|
||||
rtrees[rbyd] = rtree
|
||||
rdepths[len(path)] = max(rdepths.get(len(path), 0), rtree.depth)
|
||||
|
||||
# map rbyd branches into our btree space
|
||||
tree = set()
|
||||
for bid, rbyd, path in btree.traverse(path=True, depth=depth):
|
||||
if not rbyd:
|
||||
continue
|
||||
# map rbyd branches into our btree space
|
||||
tree = set()
|
||||
for bid, rbyd, path in btree.traverse(path=True, depth=depth):
|
||||
if not rbyd:
|
||||
continue
|
||||
|
||||
# yes we can find new rbyds if disk is being mutated, just
|
||||
# ignore these
|
||||
if rbyd not in rtrees:
|
||||
continue
|
||||
# yes we can find new rbyds if disk is being mutated, just
|
||||
# ignore these
|
||||
if rbyd not in rtrees:
|
||||
continue
|
||||
|
||||
rtree = rtrees[rbyd]
|
||||
rz = max((t.z+1 for t in rtree), default=0)
|
||||
d = sum(rdepths[d]+1 for d in range(len(path)))
|
||||
rtree = rtrees[rbyd]
|
||||
rz = max((t.z+1 for t in rtree), default=0)
|
||||
d = sum(rdepths[d]+1 for d in range(len(path)))
|
||||
|
||||
# map into our btree space
|
||||
for t in rtree:
|
||||
# note we adjust our bid to be left-leaning, this allows
|
||||
# a global order and makes tree rendering quite a bit easier
|
||||
a_rid, a_tag = t.a
|
||||
b_rid, b_tag = t.b
|
||||
_, (_, a_w, _) = rbyd.lookupnext(a_rid)
|
||||
_, (_, b_w, _) = rbyd.lookupnext(b_rid)
|
||||
tree.add(cls.Branch(
|
||||
(bid-(rbyd.weight-1)+a_rid-(a_w-1), len(path), a_tag),
|
||||
(bid-(rbyd.weight-1)+b_rid-(b_w-1), len(path), b_tag),
|
||||
d + rdepths[len(path)]-rz + t.z,
|
||||
t.color))
|
||||
|
||||
# connect rbyd branches to rbyd roots
|
||||
if path:
|
||||
l_bid, l_rbyd, l_rid, l_name = path[-1]
|
||||
l_branch = l_rbyd.lookup(l_rid, TAG_BRANCH, 0x3)
|
||||
|
||||
if rtree:
|
||||
r_rid, r_tag = min(rtree, key=lambda t: t.z).a
|
||||
_, (_, r_w, _) = rbyd.lookupnext(r_rid)
|
||||
else:
|
||||
r_rid, (r_tag, r_w, _) = rbyd.lookupnext(-1)
|
||||
|
||||
tree.add(cls.Branch(
|
||||
(l_bid-(l_name.weight-1), len(path)-1, l_branch.tag),
|
||||
(bid-(rbyd.weight-1)+r_rid-(r_w-1), len(path), r_tag),
|
||||
d-1))
|
||||
|
||||
# remap branches to leaves if we aren't showing inner branches
|
||||
if not inner:
|
||||
# step through each btree layer backwards
|
||||
b_depth = max((t.a[1]+1 for t in tree), default=0)
|
||||
|
||||
for d in reversed(range(b_depth-1)):
|
||||
# find bid ranges at this level
|
||||
bids = set()
|
||||
for t in tree:
|
||||
if t.b[1] == d:
|
||||
bids.add(t.b[0])
|
||||
bids = sorted(bids)
|
||||
|
||||
# find the best root for each bid range
|
||||
roots = {}
|
||||
for i in range(len(bids)):
|
||||
for t in tree:
|
||||
if (t.a[1] > d
|
||||
and t.a[0] >= bids[i]
|
||||
and (i == len(bids)-1 or t.a[0] < bids[i+1])
|
||||
and (bids[i] not in roots
|
||||
or t < roots[bids[i]])):
|
||||
roots[bids[i]] = t
|
||||
|
||||
# remap branches to leaf-roots
|
||||
tree = {t.map(
|
||||
lambda x: x[1] == d and x[0] in roots,
|
||||
lambda x: roots[x[0]].a)
|
||||
for t in tree}
|
||||
|
||||
return cls(tree)
|
||||
|
||||
# render a btree btree tree for debugging
|
||||
@classmethod
|
||||
def _frombtreebtree(cls, btree, *,
|
||||
depth=None,
|
||||
inner=False,
|
||||
**args):
|
||||
# find all branches
|
||||
tree = set()
|
||||
root = None
|
||||
branches = {}
|
||||
for bid, name, path in btree.bids(
|
||||
path=True,
|
||||
depth=depth):
|
||||
# create branch for each jump in path
|
||||
#
|
||||
# map into our btree space
|
||||
for t in rtree:
|
||||
# note we adjust our bid to be left-leaning, this allows
|
||||
# a global order and makes tree rendering quite a bit easier
|
||||
a = root
|
||||
for d, (bid_, rbyd_, rid_, name_) in enumerate(path):
|
||||
# map into our btree space
|
||||
bid__ = bid_-(name_.weight-1)
|
||||
b = (bid__, d, name_.tag)
|
||||
a_rid, a_tag = t.a
|
||||
b_rid, b_tag = t.b
|
||||
_, (_, a_w, _) = rbyd.lookupnext(a_rid)
|
||||
_, (_, b_w, _) = rbyd.lookupnext(b_rid)
|
||||
tree.add(cls.Branch(
|
||||
(bid-(rbyd.weight-1)+a_rid-(a_w-1), len(path), a_tag),
|
||||
(bid-(rbyd.weight-1)+b_rid-(b_w-1), len(path), b_tag),
|
||||
d + rdepths[len(path)]-rz + t.z,
|
||||
t.color))
|
||||
|
||||
# remap branches to leaves if we aren't showing inner
|
||||
# branches
|
||||
if not inner:
|
||||
if b not in branches:
|
||||
bid_, rbyd_, rid_, name_ = path[-1]
|
||||
bid__ = bid_-(name_.weight-1)
|
||||
branches[b] = (bid__, len(path)-1, name_.tag)
|
||||
b = branches[b]
|
||||
# connect rbyd branches to rbyd roots
|
||||
if path:
|
||||
l_bid, l_rbyd, l_rid, l_name = path[-1]
|
||||
l_branch = l_rbyd.lookup(l_rid, TAG_BRANCH, 0x3)
|
||||
|
||||
# render the root path on first rid, this is arbitrary
|
||||
if root is None:
|
||||
root, a = b, b
|
||||
if rtree:
|
||||
r_rid, r_tag = min(rtree, key=lambda t: t.z).a
|
||||
_, (_, r_w, _) = rbyd.lookupnext(r_rid)
|
||||
else:
|
||||
r_rid, (r_tag, r_w, _) = rbyd.lookupnext(-1)
|
||||
|
||||
tree.add(cls.Branch(a, b, d))
|
||||
a = b
|
||||
tree.add(cls.Branch(
|
||||
(l_bid-(l_name.weight-1), len(path)-1, l_branch.tag),
|
||||
(bid-(rbyd.weight-1)+r_rid-(r_w-1), len(path), r_tag),
|
||||
d-1))
|
||||
|
||||
return cls(tree)
|
||||
# remap branches to leaves if we aren't showing inner branches
|
||||
if not inner:
|
||||
# step through each btree layer backwards
|
||||
b_depth = max((t.a[1]+1 for t in tree), default=0)
|
||||
|
||||
# render a btree tree for debugging
|
||||
@classmethod
|
||||
def frombtree(cls, btree, **args):
|
||||
if args.get('tree_btree'):
|
||||
return cls._frombtreebtree(btree, **args)
|
||||
else:
|
||||
return cls._frombtreertree(btree, **args)
|
||||
for d in reversed(range(b_depth-1)):
|
||||
# find bid ranges at this level
|
||||
bids = set()
|
||||
for t in tree:
|
||||
if t.b[1] == d:
|
||||
bids.add(t.b[0])
|
||||
bids = sorted(bids)
|
||||
|
||||
# find the best root for each bid range
|
||||
roots = {}
|
||||
for i in range(len(bids)):
|
||||
for t in tree:
|
||||
if (t.a[1] > d
|
||||
and t.a[0] >= bids[i]
|
||||
and (i == len(bids)-1 or t.a[0] < bids[i+1])
|
||||
and (bids[i] not in roots
|
||||
or t < roots[bids[i]])):
|
||||
roots[bids[i]] = t
|
||||
|
||||
# remap branches to leaf-roots
|
||||
tree = {t.map(
|
||||
lambda x: x[1] == d and x[0] in roots,
|
||||
lambda x: roots[x[0]].a)
|
||||
for t in tree}
|
||||
|
||||
return cls(tree)
|
||||
|
||||
# render a btree btree tree for debugging
|
||||
@classmethod
|
||||
def _treeartfrombtreebtree(cls, btree, *,
|
||||
depth=None,
|
||||
inner=False,
|
||||
**args):
|
||||
# find all branches
|
||||
tree = set()
|
||||
root = None
|
||||
branches = {}
|
||||
for bid, name, path in btree.bids(
|
||||
path=True,
|
||||
depth=depth):
|
||||
# create branch for each jump in path
|
||||
#
|
||||
# note we adjust our bid to be left-leaning, this allows
|
||||
# a global order and makes tree rendering quite a bit easier
|
||||
a = root
|
||||
for d, (bid_, rbyd_, rid_, name_) in enumerate(path):
|
||||
# map into our btree space
|
||||
bid__ = bid_-(name_.weight-1)
|
||||
b = (bid__, d, name_.tag)
|
||||
|
||||
# remap branches to leaves if we aren't showing inner
|
||||
# branches
|
||||
if not inner:
|
||||
if b not in branches:
|
||||
bid_, rbyd_, rid_, name_ = path[-1]
|
||||
bid__ = bid_-(name_.weight-1)
|
||||
branches[b] = (bid__, len(path)-1, name_.tag)
|
||||
b = branches[b]
|
||||
|
||||
# render the root path on first rid, this is arbitrary
|
||||
if root is None:
|
||||
root, a = b, b
|
||||
|
||||
tree.add(cls.Branch(a, b, d))
|
||||
a = b
|
||||
|
||||
return cls(tree)
|
||||
|
||||
# render a btree tree for debugging
|
||||
@classmethod
|
||||
def treeartfrombtree(cls, btree, **args):
|
||||
if args.get('tree_btree'):
|
||||
return cls._frombtreebtree(btree, **args)
|
||||
else:
|
||||
return cls._frombtreertree(btree, **args)
|
||||
|
||||
TreeArt._frombtreertree = _treeartfrombtreertree
|
||||
TreeArt._frombtreebtree = _treeartfrombtreebtree
|
||||
TreeArt.frombtree = treeartfrombtree
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user