checkpoint
[sbp.git] / src / edu / berkeley / sbp / util / GraphViz.java
1 package edu.berkeley.sbp.util;
2 import edu.berkeley.sbp.util.*;
3 import edu.berkeley.sbp.*;
4 import java.io.*;
5 import java.util.*;
6 import java.lang.reflect.*;
7 import java.lang.ref.*;
8
9 public class GraphViz {
10
11     IdentityHashMap<ToGraphViz,Node> ihm = new IdentityHashMap<ToGraphViz,Node>();
12     HashMap<Node,Group> groups = new HashMap<Node,Group>();
13
14     public class Group {
15         public Group() { }
16         public void add(Node n) { groups.put(n, this); }
17     }
18
19     private static int master_idx=0;
20     public class Node {
21         private final int idx = master_idx++;
22         public String label;
23         public boolean directed = false;
24         public String color="black";
25         public ArrayList<Node> edges = new ArrayList<Node>();
26         public ArrayList<Object> labels = new ArrayList<Object>();
27         public ArrayList<Node> inbound = new ArrayList<Node>();
28         public void edge(ToGraphViz o, Object label) {
29             Node n = o.toGraphViz(GraphViz.this);
30             if (n==null) return;
31             edges.add(n);
32             labels.add(label);
33             n.inbound.add(this);
34         }
35         public String name() {
36             if (inbound.size()==1 && inbound.get(0).simple())
37                 return inbound.get(0).name()+":node_"+idx;
38             return "node_"+idx;
39         }
40         public void edges(PrintWriter pw) {
41             if (simple()) return;
42             for(int i=0; i<edges.size(); i++) {
43                 Node n = edges.get(i);
44                 Object label = labels.get(i);
45                 pw.println("    "+name()+" -> " + n.name() + " [color="+color+" " +(label==null?"":("label=\""+label+"\""))+ "];\n");
46             }
47         }
48         public int numEdges() { return edges.size(); }
49         public boolean simple() {
50             boolean simple = true;
51             if (label!=null && !label.equals("")) simple = false;
52             if (simple)
53                 for(Node n : edges)
54                     //if (n.numEdges()>0) { simple = false; break; }
55                     if (n.inbound.size() > 1) { simple = false; break; }
56             return simple;
57         }
58         public void dump(PrintWriter pw) {
59             if (inbound.size() > 0) {
60                 boolean good = false;
61                 for(Node n : inbound)
62                     if (!n.simple())
63                         { good = true; break; }
64                 if (!good) return;
65             }
66             pw.print("    "+name());
67             pw.print(" [");
68             if (directed) pw.print("ordering=out");
69             if (simple()) {
70                 pw.print(" shape=record ");
71                 pw.print(" label=\"");
72                 boolean complex = false;
73                 for(Node n : edges)
74                     if (n.edges.size()>0)
75                         complex = true;
76                 if (!complex) pw.print("{");
77                 boolean first = true;
78                 for(Node n : edges) {
79                     if (!first) pw.print("|");
80                     first = false;
81                     pw.print("<node_"+n.idx+">");
82                     pw.print(StringUtil.escapify(n.label,"\\\""));
83                 }
84                 if (!complex) pw.print("}");
85                 pw.print("\"");
86             } else {
87                 pw.print(" label=\"");
88                 pw.print(StringUtil.escapify(label,"\\\""));
89                 pw.print("\"");
90             }
91             pw.print("color="+color);
92             pw.print("];\n");
93         }
94     }
95
96     public boolean hasNode(ToGraphViz o) {
97         return ihm.get(o)!=null;
98     }
99
100     public Node createNode(ToGraphViz o) {
101         Node n = ihm.get(o);
102         if (n!=null) return n;
103         n = new Node();
104         ihm.put(o, n);
105         return n;
106     }
107
108     public static interface ToGraphViz {
109         public Node    toGraphViz(GraphViz gv);
110         public boolean isTransparent();
111         public boolean isHidden();
112     }
113
114     public void dump(PrintWriter pw) {
115         IdentityHashMap<Node,Node> done = new IdentityHashMap<Node,Node>();
116         pw.println("digraph G { rankdir=LR; \n");
117         for(Group g : groups.values()) {
118             pw.println("  { rank=same;\n");
119             for(Node n : groups.keySet())
120                 if (groups.get(n)==g) {
121                     done.put(n,n);
122                     n.dump(pw);
123                 }
124             pw.println("  }\n");
125         }
126         for(Node n : ihm.values()) {
127             if (done.get(n)!=null) continue;
128             n.dump(pw);
129         }
130         for(Node n : ihm.values()) n.edges(pw);
131         pw.println("}\n");
132     }
133
134 }