001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015:
016: package org.griphyn.cPlanner.partitioner;
017:
018: import org.griphyn.cPlanner.classes.Data;
019:
020: import org.griphyn.cPlanner.partitioner.graph.GraphNode;
021:
022: import java.io.Writer;
023: import java.io.StringWriter;
024: import java.io.IOException;
025:
026: import java.util.HashMap;
027: import java.util.LinkedHashSet;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.ArrayList;
031: import java.util.Map;
032: import java.util.Set;
033:
034: /**
035: * This is an abstract container for a partition in the graph. This used for
036: * the generation of the partition element in the partition graph, and identifies
037: * the relations between the jobs in the partition if any.
038: *
039: *
040: * @author Karan Vahi
041: * @version $Revision: 50 $
042: */
043:
044: public class Partition extends Data {
045:
046: /**
047: * The set of node id's in the partition.
048: */
049: private Set mNodeSet;
050:
051: /**
052: * A map containing a node and it's parents ids in the partition.
053: * A node id's is the key and the corresponding value is the list of
054: * String id's of it's parents. The map only contain those nodes for
055: * which there is a parent.
056: */
057: private Map mParentsMap;
058:
059: /**
060: * The list of <code>GraphNode<code> objects corresponding to the nodes
061: * making the partiition.
062: */
063: private List mNodeList;
064:
065: /**
066: * The partition id of the partition.
067: */
068: private String mID;
069:
070: /**
071: * The index associated with the partition. In most cases the ID of the
072: * partition is constructed using this index.
073: */
074: private int mIndex;
075:
076: /**
077: * The name of the partition.
078: */
079: private String mName;
080:
081: /**
082: * A pointer to the last added node to the partition.
083: */
084: private GraphNode mLastAddedNode;
085:
086: /**
087: * The default constructor.
088: */
089: public Partition() {
090: mID = null;
091: mName = "test";
092: mIndex = -1;
093: mNodeSet = new LinkedHashSet();
094: mParentsMap = new HashMap();
095: mNodeList = new java.util.LinkedList();
096: mLastAddedNode = null;
097: }
098:
099: /**
100: * The overloaded constructor.
101: *
102: * @param nodeList list of <code>GraphNode</code> objects.
103: * @param id the partition id of the partition.
104: */
105: public Partition(List nodeList, String id) {
106: mNodeList = nodeList;
107: mID = id;
108: mParentsMap = new HashMap(nodeList.size());
109: mNodeSet = new LinkedHashSet(nodeList.size());
110: mIndex = -1;
111: //default to test
112: mName = "test";
113: mLastAddedNode = null;
114: for (Iterator it = mNodeList.iterator(); it.hasNext();) {
115: mNodeSet.add(((GraphNode) it.next()).getID());
116: }
117: }
118:
119: /**
120: * Adds a node to the partition. It ends up adding it to the underneath
121: * node list.
122: *
123: * @param node the <code>GraphNode</code> object corresponding to the job
124: * that is to be added.
125: */
126: public void addNode(GraphNode node) {
127: mNodeList.add(node);
128: //also add it to the underlying job set
129: mNodeSet.add(node.getID());
130: mLastAddedNode = node;
131: }
132:
133: /**
134: * Returns the last added node to the partition.
135: *
136: * @return the last added node, or null in case partition is empty
137: */
138: public GraphNode lastAddedNode() {
139: return mLastAddedNode;
140: }
141:
142: /**
143: * Returns a list of nodes making up the partition.
144: *
145: * @return List of <code>GraphNode</code> objects.
146: */
147: public List getNodes() {
148: return this .mNodeList;
149: }
150:
151: /**
152: * Returns the root nodes in the partition. They can only be determined, after
153: * the constructPartition() has been called.
154: *
155: * @return List of <code>GraphNode</code> objects that are the root.
156: */
157: public List getRootNodes() {
158: List l = new ArrayList(10);
159: Map m = this .getRelations();
160: for (Iterator it = getNodes().iterator(); it.hasNext();) {
161: GraphNode gn = (GraphNode) it.next();
162: if (!m.containsKey(gn.getID())) {
163: l.add(gn);
164: }
165: }
166: return l;
167: }
168:
169: /**
170: * It while looking at the node list constructs the relations between
171: * the jobs in the partition, that can be gotten through
172: * getRelationsInPartition().
173: */
174: public void constructPartition() {
175: //traverse through all the nodes in the partition
176: for (Iterator it = mNodeList.iterator(); it.hasNext();) {
177: GraphNode node = (GraphNode) it.next();
178: List parents = node.getParents();
179: if (parents == null) {
180: continue;
181: }
182:
183: //traverse through all the parents of the node, in
184: //the original DAX/Graph,that may or maynot be in
185: //this partition
186: List partitionParents = new java.util.LinkedList();
187: for (Iterator pIt = parents.iterator(); pIt.hasNext();) {
188: GraphNode parent = (GraphNode) pIt.next();
189: if (mNodeSet.contains(parent.getID())) {
190: //relation between 2 nodes in the same partition.
191: partitionParents.add(parent.getID());
192: }
193: }
194: //only add if there are any parents
195: if (!partitionParents.isEmpty()) {
196: mParentsMap.put(node.getID(), partitionParents);
197: }
198: }
199: }
200:
201: /**
202: * It sets the partition name to the value passed.
203: *
204: * @param name the name to which the partition name needs to be set to.
205: */
206: public void setName(String name) {
207: mName = name;
208: }
209:
210: /**
211: * It returns the name of the partition.
212: */
213: public String getName() {
214: return mName;
215: }
216:
217: /**
218: * It sets the index associated with this partition to the value passed.
219: *
220: * @param index the index value.
221: */
222: public void setIndex(int index) {
223: mIndex = index;
224: }
225:
226: /**
227: * It returns the index to number of the partition.
228: */
229: public int getIndex() {
230: return mIndex;
231: }
232:
233: /**
234: * It returns the unique id that is associated with the partition.
235: */
236: public String getID() {
237: return mID;
238: }
239:
240: /**
241: * It sets the id of the partition.
242: *
243: * @param id the id of the partition.
244: */
245: public void setID(String id) {
246: mID = id;
247: }
248:
249: /**
250: * Returns the number of nodes in the partition.
251: *
252: * @return the number of nodes.
253: */
254: public int size() {
255: return mNodeList.size();
256: }
257:
258: /**
259: * Returns a String version of the object.
260: */
261: public String toString() {
262: StringBuffer sb = new StringBuffer();
263: sb.append("Partition ID ->").append(mID);
264: Iterator it = mNodeSet.iterator();
265: while (it.hasNext()) {
266: String id = (String) it.next();
267: sb.append("\nJob ->").append(id);
268:
269: List l = (List) mParentsMap.get(id);
270: if (l == null)
271: continue;
272:
273: Iterator it1 = l.iterator();
274: sb.append(" Parents {");
275: while (it1.hasNext()) {
276: sb.append(it1.next()).append(',');
277:
278: }
279: sb.append("}");
280: }
281:
282: return sb.toString();
283: }
284:
285: /**
286: * Returns the xml description of the object. This is used for generating
287: * the partition graph. That is no longer done.
288: *
289: * @param writer is a Writer opened and ready for writing. This can also
290: * be a StringWriter for efficient output.
291: *
292: * @exception IOException if something fishy happens to the stream.
293: */
294: public void toXML(Writer writer) throws IOException {
295: String newLine = System.getProperty("line.separator", "\r\n");
296: String indent = "\t";
297:
298: //write out the partition xml element
299: writer.write(indent);
300: writer.write("<partition");
301: writeAttribute(writer, "name", mName);
302: writeAttribute(writer, "index", Integer.toString(mIndex));
303: writeAttribute(writer, "id", mID);
304: writer.write(">");
305: writer.write(newLine);
306:
307: //write out all the jobs making up the partition
308: String newIndent = indent + "\t";
309: for (Iterator it = mNodeList.iterator(); it.hasNext();) {
310: GraphNode gn = (GraphNode) it.next();
311: writer.write(newIndent);
312: writer.write("<job");
313: writeAttribute(writer, "name", gn.getName());
314: writeAttribute(writer, "id", gn.getID());
315: writer.write("/>");
316: writer.write(newLine);
317: }
318:
319: //write out all the dependencies amongst the jobs.
320: String id;
321: for (Iterator it = mNodeSet.iterator(); it.hasNext();) {
322: id = (String) it.next();
323:
324: List l = (List) mParentsMap.get(id);
325: if (l == null || l.isEmpty())
326: continue;
327:
328: //write out the child
329: writer.write(newIndent);
330: writer.write("<child");
331: writeAttribute(writer, "ref", id);
332: writer.write(">");
333: writer.write(newLine);
334:
335: //write out all the parents of the child
336: String parentIndent = newIndent + "\t";
337: for (Iterator it1 = l.iterator(); it1.hasNext();) {
338: writer.write(parentIndent);
339: writer.write("<parent");
340: writeAttribute(writer, "ref", (String) it1.next());
341: writer.write("/>");
342: writer.write(newLine);
343: }
344:
345: writer.write(newIndent);
346: writer.write("</child>");
347: writer.write(newLine);
348: }
349:
350: writer.write(indent);
351: writer.write("</partition>");
352: writer.write(newLine);
353: }
354:
355: /**
356: * Returns the xml description of the object. This is used for generating
357: * the partition graph. That is no longer done.
358: *
359: * @return String containing the Partition object in XML.
360: *
361: * @exception IOException if something fishy happens to the stream.
362: */
363: public String toXML() throws IOException {
364: Writer writer = new StringWriter(32);
365: toXML(writer);
366: return writer.toString();
367: }
368:
369: /**
370: * Writes an attribute to the stream. Wraps the value in quotes as required
371: * by XML.
372: *
373: * @param writer
374: * @param key
375: * @param value
376: *
377: * @exception IOException if something fishy happens to the stream.
378: */
379: private void writeAttribute(Writer writer, String key, String value)
380: throws IOException {
381: writer.write(" ");
382: writer.write(key);
383: writer.write("=\"");
384: writer.write(value);
385: writer.write("\"");
386: }
387:
388: /**
389: * It returns the set of the job ids making up the partition.
390: */
391: public Set getNodeIDs() {
392: return mNodeSet;
393: }
394:
395: /**
396: * Ends up assigning the parents to a particular node. It does assign
397: * the parents to the node, if the node is in the partition. It however
398: * does not check if the parents are in the partition or not.
399: *
400: * @param node the id of the node for which you want to add the parents.
401: * @param parents list of id's of the parents of the nodes.
402: */
403: public void addParents(String node, List parents) {
404: //check if node is in the node set
405: if (mNodeSet.contains(node)) {
406: //add to the graph
407: mParentsMap.put(node, parents);
408: }
409: }
410:
411: /**
412: * A function to return the child-parent relations for the jobs making up the
413: * partition. The child parent relations are only returned for the jobs
414: * that have parents in the partition.
415: *
416: * @return Map containing the job id's as the keys and the values as the
417: * list of the parent id's in the partition.
418: */
419: public Map getRelations() {
420: return mParentsMap;
421: }
422:
423: /**
424: * Returns a copy of the object
425: */
426: public Object clone() throws CloneNotSupportedException {
427: throw new CloneNotSupportedException(
428: "Clone method not implemented in Partition");
429: }
430: }
|