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

.

parent f24be16b
...@@ -78,7 +78,7 @@ in left-to-right order. ...@@ -78,7 +78,7 @@ in left-to-right order.
from __future__ import print_function, absolute_import from __future__ import print_function, absolute_import
from BTrees import check as bcheck from BTrees import check as bcheck
from golang import panic from golang import func, panic
from golang.gcompat import qq from golang.gcompat import qq
import itertools import itertools
import re import re
...@@ -198,6 +198,19 @@ def TopoEncode(tree): ...@@ -198,6 +198,19 @@ def TopoEncode(tree):
topo = '' topo = ''
# breadth-first traversal of the tree with '/' injected in between layers # 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, '/'] queue = [tree, '/']
while 1: while 1:
x = queue.pop(0) x = queue.pop(0)
...@@ -218,6 +231,7 @@ def TopoEncode(tree): ...@@ -218,6 +231,7 @@ def TopoEncode(tree):
if isinstance(node, Tree): if isinstance(node, Tree):
queue += node.children queue += node.children
"""
if 1: # make sure that every topology we emit, can be loaded back if 1: # make sure that every topology we emit, can be loaded back
t2 = TopoDecode(topo) t2 = TopoDecode(topo)
...@@ -226,6 +240,23 @@ def TopoEncode(tree): ...@@ -226,6 +240,23 @@ def TopoEncode(tree):
return topo 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. # TopoDecode decodes topology-encoded text into Tree structure.
# #
# See top-level docstring for description of topology encoding. # See top-level docstring for description of topology encoding.
...@@ -392,3 +423,87 @@ def _assertIncv(v): ...@@ -392,3 +423,87 @@ def _assertIncv(v):
if not (v[i] > prev): if not (v[i] > prev):
panic("assert incv: [%d] not ↑: %s -> %s" % (i, v[i], prev)) panic("assert incv: [%d] not ↑: %s -> %s" % (i, v[i], prev))
prev = v[i] 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