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