671940ae2d01bc1cabcfb36e56df8373dc1f7943
[sbp.git] / src / edu / berkeley / sbp / ResultNode.java
1 // Copyright 2006-2007 all rights reserved; see LICENSE file for BSD-style license
2
3 package edu.berkeley.sbp;
4 import edu.berkeley.sbp.util.*;
5 import edu.berkeley.sbp.Sequence.Pos;
6 import edu.berkeley.sbp.Sequence.Pos;
7 import java.util.*;
8
9 final class ResultNode
10     implements GraphViz.ToGraphViz {
11
12     private Forest.Many f = new Forest.Many();
13     //private HashSet<StateNode> predecessors = new HashSet<StateNode>();
14     //private HashSet<StateNode> successors = new HashSet<StateNode>();
15     private FastSet<StateNode> predecessors = new FastSet<StateNode>();
16     private FastSet<StateNode> successors = new FastSet<StateNode>();
17     private boolean destroyed = false;
18     private boolean primordeal;
19     private int usedByNonDoomedNode = 0;
20     private Pos reduction;
21     private GSS.Phase predPhase;
22
23     public boolean predecessorsContains(StateNode n) {
24         return predecessors.contains(n);
25     }
26     public Pos reduction() { return reduction; }
27     public void merge(Forest newf) {
28         this.f.merge(newf);
29         /*
30         if (predecessors.contains(pred)) return;
31         addPred(pred);
32         if (fromEmptyReduction) return;
33         n.state().invokeReductions(n.phase().getToken(), n, this);        
34         */
35     }
36
37     public boolean noSuccessors() { return successors.size()==0; }
38
39     public GSS.Phase phase() { return predPhase; }
40     public Forest getForest() { return f; }
41     public Iterable<StateNode> getPreds() { return predecessors; }
42     public void addSucc(StateNode succ) {
43         if (successors.contains(succ)) return;
44         successors.add(succ);
45         usedByNonDoomedNode += succ.state().doomed ? 0 : 1;
46         if (predecessors.size() > 1) throw new Error();
47     }
48     public void removeSucc(StateNode succ) {
49         if (!successors.contains(succ)) return;
50         successors.remove(succ);
51         usedByNonDoomedNode -= succ.state().doomed ? 0 : 1;
52         check();
53     }
54
55     public boolean usedByAnyNode() { return successors.size() > 0; }
56     public boolean usedByNonDoomedNode() { return usedByNonDoomedNode > 0; }
57
58     public String toString() { return super.toString()+"->"+predPhase; }
59
60     public void check() {
61         if (successors.size()==0) destroy();
62         else if (predecessors.size()==0) destroy();
63     }
64     public void destroy() {
65         if (destroyed) return;
66         if (primordeal) return;  // never destroy the "primordeal" result
67         destroyed = true;
68         while(predecessors.size() > 0)
69             for(StateNode pred : predecessors) {
70                 removePred(pred);
71                 pred.removeSucc(this);
72                 break;
73             }
74         predecessors = null;
75         while(successors.size() > 0)
76             for(StateNode succ : successors) {
77                 removeSucc(succ);
78                 succ.removeResult(this);
79                 break;
80             }
81         successors = null;
82     }
83
84     public void removePred(StateNode pred) {
85         if (!predecessors.contains(pred)) return;
86         predecessors.remove(pred);
87         check();
88     }
89
90     public void addPred(StateNode pred) {
91         if (predPhase==null) predPhase = pred.phase();
92         if (predPhase != pred.phase()) throw new Error();
93         predecessors.add(pred);
94         pred.addSucc(this);
95         if (predecessors.size() > 1) throw new Error();
96     }
97         
98     public ResultNode() {
99         this(null, null, null);
100         this.primordeal = true;
101     }
102     public ResultNode(Forest f, Pos reduction, StateNode pred) {
103         this.f.merge(f);
104         this.reduction = reduction;
105         if (pred != null) addPred(pred);
106     }
107
108     // GraphViz //////////////////////////////////////////////////////////////////////////////
109
110     public GraphViz.StateNode toGraphViz(GraphViz gv) {
111         if (gv.hasNode(this)) return gv.createNode(this);
112         GraphViz.StateNode n = gv.createNode(this);
113         n.label = ""+f;
114         n.shape = "rectangle";
115         //if (pred()!=null) n.edge(pred, "");
116         n.color = "blue";
117         if (phase() != null)
118             ((GraphViz.Group)phase().toGraphViz(gv)).add(n);
119         return n;
120     }
121     public boolean isTransparent() { return false; }
122     public boolean isHidden() { return false; }
123
124 }