def add_vertex(self, v): vaddr = v.data.address i = self.support.locate(vaddr) if i is not None: mo = self.support._map[i] if vaddr in mo: oldnode = mo.data.val if oldnode == v: return 0 # so v cuts an existing node/block: # repair oldblock and fix self childs = oldnode.N(+1) oldblock = oldnode.data oldblock.cut(vaddr) Graph.add_vertex(self, v) # ! avoid recursion for add_edge self.support.write(vaddr, v) self.add_edge(link(oldnode, v)) for n in childs: self.add_edge(link(v, n)) self.remove_edge(oldnode.e_to(n)) return 1 else: #v does not cut an existing block, try: # but may swallow next one... nextmo = self.support._map[i + 1] except IndexError: # no more nodes here so back to default case: pass else: nextnode = nextmo.data.val if vaddr + len(v) >= nextnode.data.address: v.data.cut(nextnode.data.address) Graph.add_vertex(self, v) # before support write !! self.support.write(vaddr, v) return 1
def _layout_graph_sugiyama(graph): """ Arrange the graph automatically using grandalf package """ from grandalf.graphs import Graph, Vertex, Edge from grandalf.layouts import SugiyamaLayout # Build the viez class for grandalf vertices class View(object): def __init__(self, w, h): self.w = w self.h = h self.xy = (0, 0) # Build the grandalf graph ggraph = Graph() # Vertices vertices_by_id = {} all_nodes_by_id = {n.id: n for n in graph.all_nodes()} # Get average width for distance between nodes avg_width = 0 avg_height = 0 for n in all_nodes_by_id.values(): v = Vertex(n.id) if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL: view = View(n.view.height, n.view.width) else: view = View(n.view.width, n.view.height) avg_width += n.view.width avg_height += n.view.height v.view = view vertices_by_id[n.id] = v avg_width /= len(all_nodes_by_id) avg_height /= len(all_nodes_by_id) for v in vertices_by_id.values(): ggraph.add_vertex(v) # Edges inverted_edges = [] looked_up_nodes = set([]) for n in all_nodes_by_id.values(): for cns in n.connected_output_nodes().values(): for cn in cns: e = Edge(vertices_by_id[n.id], vertices_by_id[cn.id]) if cn.id in looked_up_nodes: inverted_edges.append(e) else: looked_up_nodes.add(cn.id) ggraph.add_edge(e) # Build the layout sug = SugiyamaLayout(ggraph.C[0]) sug.yspace = avg_width if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL else avg_height sug.xspace = avg_height if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL else avg_width print(inverted_edges) # sug.init_all(inverted_edges=inverted_edges or None) sug.init_all() sug.draw(10) for v in ggraph.C[0].sV: node = all_nodes_by_id[v.data] if NODE_LAYOUT_DIRECTION == NODE_LAYOUT_HORIZONTAL: node.set_pos(*reversed(v.view.xy)) else: node.set_pos(*v.view.xy)