00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 package dfengine;
00025
00026 import java.util.*;
00027
00028 import utils.*;
00029
00030 public class FailureDepGraph extends DoubleLinkedDAG {
00031
00032 protected GraphMatrix indirectDeps;
00033
00034 protected GraphMatrix commonAncestorGraph;
00035
00036 protected boolean useProbabilities;
00037
00038 public FailureDepGraph(boolean useProbabilities) {
00039 this.useProbabilities = useProbabilities;
00040 }
00041
00042 public String toString() {
00043 StringBuffer result = new StringBuffer(super.toString());
00044
00045 result.append("\n\nTRANSITIVE CLOSURE:\n\n");
00046 Iterator itEdges = indirectDeps.getEdgeIterator();
00047 while (itEdges.hasNext()) {
00048 GraphMatrix.Edge e = (GraphMatrix.Edge)itEdges.next();
00049 FailureDepNode fromNode = (FailureDepNode)getNode(e.from);
00050 FailureDepNode toNode = (FailureDepNode)getNode(e.to);
00051 result.append(fromNode + " => " + toNode);
00052
00053 int dist = ((DoubleLinkedDAG.MinMaxDistance)indirectDeps.getTag(e.from, e.to)).minDist;
00054 result.append(" (" + dist + ")\n");
00055 }
00056
00057 result.append("\n\nCOMMON ANCESTOR GRAPH:\n\n");
00058 itEdges = commonAncestorGraph.getEdgeIterator();
00059 while (itEdges.hasNext()) {
00060 GraphMatrix.Edge e = (GraphMatrix.Edge)itEdges.next();
00061 FailureDepNode fromNode = (FailureDepNode)getNode(e.from);
00062 FailureDepNode toNode = (FailureDepNode)getNode(e.to);
00063 result.append(fromNode + " => " + toNode);
00064
00065 int dist = ((Integer)commonAncestorGraph.getTag(e.from, e.to)).intValue();
00066 result.append(" (" + dist + ")\n");
00067 }
00068
00069 return result.toString();
00070 }
00071
00072 public Object clone() {
00073 throw new UnsupportedOperationException("class FailureDepGraph does not support clone()");
00074 }
00075
00076 boolean useProbabilities() {
00077 return useProbabilities;
00078 }
00079
00085 public FailureDepNode addNode(Component comp) {
00086 assert(!useProbabilities || (comp.getProbIF() >= 0.0));
00087
00088 FailureDepNode newNode = new FailureDepNode(comp);
00089 super.addNode(newNode);
00090 comp.fdNode = newNode;
00091 return newNode;
00092 }
00093
00099 public void addEdge(Component from, Component to) {
00100 assert(!useProbabilities && (from.fdNode != null) && (to.fdNode != null));
00101
00102 super.addEdge(from.fdNode, to.fdNode);
00103 }
00104
00110 public void addEdge(Component from, Component to, double prob_df) {
00111 assert(useProbabilities && (from.fdNode != null) && (to.fdNode != null));
00112
00113 super.addEdge(from.fdNode, to.fdNode);
00114 to.fdNode.prob_df.put(new Integer(from.fdNode.getID()), new Double(prob_df));
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 public void computeIndirectDeps() {
00125 indirectDeps = computeTransitiveClosure(true);
00126 }
00127
00128
00129
00130
00131 public boolean hasIndirectDependency(Component from, Component to) {
00132 if (indirectDeps == null) computeIndirectDeps();
00133
00134 return (indirectDeps.hasEdge(from.getFDNode().getID(), to.getFDNode().getID()));
00135 }
00136
00137
00138
00139
00140
00141 public boolean haveCommonAncestor(Component c1, Component c2) {
00142 int id1 = c1.getFDNode().getID();
00143 int id2 = c2.getFDNode().getID();
00144
00145 return commonAncestorGraph.hasEdge(id1, id2);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 public void computeCommonAncestorGraph(boolean computeMinDistances) {
00166 assert(indirectDeps != null);
00167
00168 commonAncestorGraph = new GraphMatrix(nodes.size());
00169
00170 for (int i = 0; i < nodes.size(); ++i) {
00171
00172 for (int j = i + 1; j < nodes.size(); ++j) {
00173
00174 if (!indirectDeps.hasEdge(i, j)
00175 && !indirectDeps.hasEdge(j, i)) {
00176
00177 for (int k = 0; k < nodes.size(); ++k) {
00178 if ((k != i) && (k != j)
00179 && indirectDeps.hasEdge(k, i)
00180 && indirectDeps.hasEdge(k, j)) {
00181
00182 if (computeMinDistances) {
00183 Object tag_i = indirectDeps.getTag(k, i);
00184 Object tag_j = indirectDeps.getTag(k, j);
00185 assert((tag_i != null) && (tag_j) != null);
00186 int di = ((DoubleLinkedDAG.MinMaxDistance)tag_i).minDist;
00187 int dj = ((DoubleLinkedDAG.MinMaxDistance)tag_j).minDist;
00188 int maxd;
00189 if (di > dj) maxd = di;
00190 else maxd = dj;
00191
00192 if (commonAncestorGraph.hasEdge(i, j)) {
00193 assert(commonAncestorGraph.hasEdge(j, i));
00194
00195 Integer dk = (Integer)commonAncestorGraph.getTag(i, j);
00196 if (maxd < dk.intValue()) {
00197 commonAncestorGraph.setTag(i, j, new Integer(maxd));
00198 commonAncestorGraph.setTag(j, i, new Integer(maxd));
00199 }
00200 } else {
00201 commonAncestorGraph.addEdge(i, j);
00202 commonAncestorGraph.addEdge(j, i);
00203 commonAncestorGraph.setTag(i, j, new Integer(maxd));
00204 commonAncestorGraph.setTag(j, i, new Integer(maxd));
00205 }
00206 } else {
00207 commonAncestorGraph.addEdge(i, j);
00208 commonAncestorGraph.addEdge(j, i);
00209 break;
00210 }
00211
00212 }
00213 }
00214 }
00215 }
00216 }
00217
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 public boolean isAncestorConnected(Component c1, Component c2, int maxPathLen) {
00229
00230 boolean result = isAncestorConnected_Impl(c1, c2, maxPathLen);
00231
00232
00233 assert(result == isAncestorConnected_Impl(c2, c1, maxPathLen));
00234
00235 return result;
00236 }
00237
00238 protected boolean isAncestorConnected_Impl(Component c1, Component c2, int maxPathLen) {
00239 int id1 = c1.getFDNode().getID();
00240 int id2 = c2.getFDNode().getID();
00241
00242 boolean result = false;
00243
00244 if (indirectDeps.hasEdge(id1, id2)) {
00245 int dist = ((DoubleLinkedDAG.MinMaxDistance)indirectDeps.getTag(id1, id2)).minDist;
00246 if (dist <= maxPathLen) result = true;
00247 } else if (indirectDeps.hasEdge(id2, id1)) {
00248 int dist = ((DoubleLinkedDAG.MinMaxDistance)indirectDeps.getTag(id2, id1)).minDist;
00249 if (dist <= maxPathLen) result = true;
00250 } else if (commonAncestorGraph.hasEdge(id1, id2)) {
00251 int dist = ((Integer)commonAncestorGraph.getTag(id1, id2)).intValue();
00252 if (dist <= maxPathLen) result = true;
00253 }
00254
00255 return result;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 public ArrayList computeTransPiPartitions(LinkedList comps, int maxPathLen) {
00267
00268 ArrayList result = new ArrayList();
00269
00270 while (comps.size() > 0) {
00271
00272 Component c = (Component)comps.removeFirst();
00273 ArrayList newPart = new ArrayList();
00274 newPart.add(c);
00275
00276 boolean progress;
00277 do {
00278 progress = false;
00279
00280 Iterator itR = comps.iterator();
00281 while (itR.hasNext()) {
00282 Component cr = (Component)itR.next();
00283
00284 Iterator itP = newPart.iterator();
00285 while (itP.hasNext()) {
00286 Component cp = (Component)itP.next();
00287 if (isAncestorConnected(cr, cp, maxPathLen)) {
00288 newPart.add(cr);
00289 itR.remove();
00290 progress = true;
00291 break;
00292 }
00293 }
00294 }
00295
00296
00297 } while (progress);
00298
00299 result.add(newPart);
00300
00301 }
00302
00303 return result;
00304
00305 }
00306 }