Commit 3fe6f599 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f24be16b
......@@ -78,7 +78,7 @@ in left-to-right order.
from __future__ import print_function, absolute_import
from BTrees import check as bcheck
from golang import panic
from golang import func, panic
from golang.gcompat import qq
import itertools
import re
......@@ -198,6 +198,19 @@ def TopoEncode(tree):
topo = ''
# breadth-first traversal of the tree with '/' injected in between layers
for nodev in _walkBFS(tree):
if len(topo) != 0:
topo += '/'
tnodev = []
for node in nodev:
assert isinstance(node, (Tree, Bucket))
tnode = ('T' if isinstance(node, Tree) else 'B') + \
(','.join(['%d' % _ for _ in node.keyv]))
tnodev.append(tnode)
topo += '-'.join(tnodev)
"""
queue = [tree, '/']
while 1:
x = queue.pop(0)
......@@ -218,6 +231,7 @@ def TopoEncode(tree):
if isinstance(node, Tree):
queue += node.children
"""
if 1: # make sure that every topology we emit, can be loaded back
t2 = TopoDecode(topo)
......@@ -226,6 +240,23 @@ def TopoEncode(tree):
return topo
# _walkBFS walks tree in breadth-first order layer by layer.
def _walkBFS(tree): # i[] of [](of nodes on each level)
assert isinstance(tree, Tree)
currentv = []
nextq = [tree]
while len(nextq) > 0:
yield tuple(nextq)
currentq = nextq
nextq = []
while len(currentq) > 0:
node = currentq.pop(0)
assert isinstance(node, (Tree, Bucket))
if isinstance(node, Tree):
nextq += node.children
# TopoDecode decodes topology-encoded text into Tree structure.
#
# See top-level docstring for description of topology encoding.
......@@ -392,3 +423,87 @@ def _assertIncv(v):
if not (v[i] > prev):
panic("assert incv: [%d] not ↑: %s -> %s" % (i, v[i], prev))
prev = v[i]
# ----------------------------------------
import sys
# graphviz returns tree graph representation in dot language.
@func(Tree)
def graphviz(t):
assert isinstance(t, Tree)
symtab = {} # node -> name
outv = []
def emit(line):
outv.append(line)
emit('digraph {')
emit(' splines=false')
for (level, nodev) in enumerate(_walkBFS(t)):
for (i, node) in enumerate(nodev):
assert isinstance(node, (Tree,Bucket))
# register node insymtab
assert node not in symtab
kind = ('T' if isinstance(node, Tree) else 'B')
symtab[node] = '%s%d:%d' % (kind, level, i)
# emit node itself
# approach based on https://github.com/Felerius/btree-generator
emit(' %s' % qq(symtab[node]))
emit(' [')
emit(' shape = none')
emit(' label = <<table border="1" cellborder="0" cellspacing="0">')
emit(' <tr>')
for (j,key) in enumerate(node.keyv):
if kind == 'T':
emit(' <td port="con%d"></td>' % j)
if 1:
emit(' <td port="key%d">%d</td>' % (j,key))
emit(' <td port="con%d"></td>' % len(node.keyv))
emit(' </tr>')
emit(' </table>>')
emit(' ]')
# second pass: emit links + node ranks
for nodev in _walkBFS(t):
# same rank for nodes on the same level
emit('')
emit(' {rank=same; %s}' % ' '.join([qq(symtab[_]) for _ in nodev]))
# links
for node in nodev:
if not isinstance(node, Tree):
continue
for (j,child) in enumerate(node.children):
emit('%s:"con%d" -> %s' % (qq(symtab[node]), j, qq(symtab[child])))
emit('}')
emit('')
return '\n'.join(outv)
# topoview display topologies provided in argv.
def topoview(argv):
if len(argv) == 0:
raise RuntimeError('E: empty argument')
topov = [TopoDecode(_) for _ in argv]
import graphviz as gv
#g = gv.Digraph(comment='AAA')
#print(g.render(format='pdf', view=True))
g = gv.Source(topov[0].graphviz())
print(g.source)
g.view()
if __name__ == '__main__':
topoview(sys.argv[1:])
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