CompositeSoftNode.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package EAnalysis.BinPacking;
import java.util.Collection;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import javax.swing.JOptionPane;
public class CompositeSoftNode extends SoftwareNode {
@Override
public boolean deployed() {
for (Iterator iter = getBasicComponents().iterator(); iter.hasNext();) {
SoftwareNode n = (SoftwareNode) iter.next();
if (!n.deployed()) {
return false;
}
}
return true;
}
double bandwidthCompressionFactor = 0.0;
@Override
public double getBandwidthCompressionFactor() {
return bandwidthCompressionFactor;
}
/**
* Cummulative bandwidth requirements int cycles per second.
*/
double totalBandwidth = 0.0;
Comparator comparator;
Comparator outDegreeComparator;
protected boolean breakable = true;
@Override
public double getBandwidth() {
return totalBandwidth;
}
/**
* Cummulative external message bandwidth from this composite to the outside
*/
double totalMsgBandwidth = 0.0;
public double getTotalMsgBandwidth() {
return totalMsgBandwidth;
}
/**
* The composing modules
*/
TreeSet components;
TreeSet componentsByOutDegree;
@Override
public Object clone() {
CompositeSoftNode n = (CompositeSoftNode) super.clone();
n.components = (TreeSet) components.clone();
n.componentsByOutDegree = (TreeSet) componentsByOutDegree.clone();
return n;
}
public TreeSet getComponents() {
return components;
}
public TreeSet getComponentsByOutDegree() {
return componentsByOutDegree;
}
public boolean containsComponent(SoftwareNode n) {
if (n.equals(this)) {
return true;
}
boolean result = components.contains(n);
if (!result) {
for (Iterator iter = components.iterator(); iter.hasNext();) {
SoftwareNode node = (SoftwareNode) iter.next();
if (node instanceof CompositeSoftNode) {
result = ((CompositeSoftNode) node).containsComponent(n);
}
if (result) {
break;
}
}
}
return result;
}
public TreeSet getBasicComponents() {
TreeSet all = new TreeSet(components.comparator());
for (Iterator iter = components.iterator(); iter.hasNext();) {
SoftwareNode n = (SoftwareNode) iter.next();
if (n instanceof CompositeSoftNode) {
all.addAll(((CompositeSoftNode) n).getBasicComponents());
} else {
all.add(n);
}
}
return all;
}
/**
* Deploy all components to same hardware
*/
@Override
public void setDeployedTo(HardwareNode n) {
for (Iterator iter = components.iterator(); iter.hasNext();) {
ProcessingLoad l = (ProcessingLoad) iter.next();
l.setDeployedTo(n);
}
}
/**
* Cannot provide consistent answer, i.e., a component can be deployed
* individually.
*/
@Override
public HardwareNode getDeployedTo() {
return null;
}
public void addExternalEdgeTo(Map.Entry msgNodePair, TreeMap connectivityVector, Hashtable connVectorByTarget,
TreeMap connectivityMatrix, Hashtable connMatrixByTarget) {
Message msg = null;
try {
msg = (Message) ((Message) msgNodePair.getKey()).clone();
} catch (Exception e) {
e.printStackTrace();
}
msg.setPartner((SoftwareNode) msgNodePair.getValue(), this);
// neighbors.remove();
connectivityVector.put(msg, msgNodePair.getValue());
connVectorByTarget.put(msgNodePair.getValue(), msg);
/* modify the partners connectivity vector */
TreeMap partnerConnectivityVector = (TreeMap) connectivityMatrix.get(msgNodePair.getValue());
if (partnerConnectivityVector == null) {
partnerConnectivityVector = new TreeMap(comparator);
connectivityMatrix.put(msgNodePair.getValue(), partnerConnectivityVector);
}
partnerConnectivityVector.remove(msgNodePair.getKey());
partnerConnectivityVector.put(msg, this);
Hashtable partnerConnVectorByTarget = (Hashtable) connMatrixByTarget.get(msgNodePair.getValue());
if (partnerConnVectorByTarget == null) {
partnerConnVectorByTarget = new Hashtable();
connMatrixByTarget.put(msgNodePair.getValue(), partnerConnVectorByTarget);
}
partnerConnVectorByTarget.remove(msgNodePair.getValue());
partnerConnVectorByTarget.put(this, msg);
totalMsgBandwidth += msg.getBandwidth();
addBandwidthOutDegree(msg.getBandwidth());
}
public void addAll(Collection set, TreeMap connectivityMatrix, Hashtable softConnectivityByTarget,
Hashtable constraints) {
for (Iterator iter = set.iterator(); iter.hasNext();) {
add((SoftwareNode) iter.next(), connectivityMatrix, softConnectivityByTarget, constraints);
}
}
public void addAll(Collection set, TreeMap connectivityMatrix, Hashtable softConnectivityByTarget) {
for (Iterator iter = set.iterator(); iter.hasNext();) {
add((SoftwareNode) iter.next(), connectivityMatrix, softConnectivityByTarget);
}
}
public void add(SoftwareNode n, TreeMap connectivityMatrix, Hashtable softConnectivityByTarget,
Hashtable constraints) {
add(n, connectivityMatrix, softConnectivityByTarget);
Vector v = (Vector) constraints.get(n);
if (v != null) {
int vSize = v.size();
for (int i = 0; i < vSize; i++) {
Constraint c = (Constraint) v.get(i);
if (c instanceof SetConstraint) {
TreeSet bComp = getBasicComponents();
boolean allIn = true;
for (Iterator iter = bComp.iterator(); iter.hasNext();) {
if (!c.members.contains(iter.next())) {
allIn = false;
break;
}
}
if (allIn) {
c.members.add(this);
Vector v1 = (Vector) constraints.get(this);
if (v1 == null) {
v1 = new Vector();
constraints.put(this, v1);
}
v1.add(c);
}
} else {
c.members.add(this);
Vector v1 = (Vector) constraints.get(this);
if (v1 == null) {
v1 = new Vector();
constraints.put(this, v1);
}
v1.add(c);
}
}
}
}
/**
* add
*
* @param n
* to the set of components add to the totalMsgBandwidth all the
* messages from
* @param connectivityVector
* that do not lead to an internal module
*/
public void add(SoftwareNode n, TreeMap connectivityMatrix, Hashtable softConnectivityByTarget) {
if (n instanceof CompositeSoftNode) {
TreeSet basicComponents = ((CompositeSoftNode) n).getBasicComponents();
for (Iterator iter = basicComponents.iterator(); iter.hasNext();) {
add((SoftwareNode) iter.next(), connectivityMatrix, softConnectivityByTarget);
}
return;
}
// CouplerElement newElement = (CouplerElement) n.getSemanticObject();
// String newElementID = (newElement == null ? "composite:"
// + Integer.toString(n.hashCode()) : newElement.getClass()
// .getName()
// + ":" + Integer.toString(newElement.ID().hashCode()));
/*
* get the connectivity vector BEFORE!! modifying this To avoid problems
* with modified hashcode we completely remove the connectivity vector
* and add it at the end of the method.
*/
TreeMap thisConnectivityVector = (TreeMap) connectivityMatrix.remove(this);
Hashtable thisConnVectorByTarget = (Hashtable) softConnectivityByTarget.get(this);
boolean firstNode = false;
/* Reset the message bandwidth */
if (components.isEmpty()) {
totalMsgBandwidth = 0.0;
firstNode = true;
}
components.add(n);
componentsByOutDegree.add(n);
TreeSet basicComponents = getBasicComponents();
TreeSet newBasicComponents = (n instanceof CompositeSoftNode) ? ((CompositeSoftNode) n).getBasicComponents()
: new TreeSet(new BandwidthComparator());
// name += name.substring(0,1)+name.substring(1,name.length()-1)+n.name+
// name.substring(name.length()-1,name.length());
name += n.name;
totalBandwidth += n.getBandwidth();
TreeMap connectivityVector = (TreeMap) connectivityMatrix.get(n);
Hashtable connVectorByTarget = (Hashtable) softConnectivityByTarget.get(n);
if (thisConnectivityVector == null) {
if (connectivityVector != null) {
thisConnectivityVector = new TreeMap(connectivityVector.comparator());
} else {
thisConnectivityVector = new TreeMap(new BandwidthComparator());
}
}
if (thisConnVectorByTarget == null) {
thisConnVectorByTarget = new Hashtable();
}
if (connectivityVector != null) {
Comparator msgComp = connectivityVector.comparator();
Vector addedMsgs = new Vector();
TreeMap pendingAdditions = new TreeMap(msgComp);
Hashtable pendingAdditionsByTarget = new Hashtable();
Hashtable targetToMsgMap = new Hashtable();
int i = 0;
for (Object[] neighbors = connectivityVector.entrySet().toArray(); i < neighbors.length; i++) {
Map.Entry entry = (Map.Entry) neighbors[i];
if (entry == null || entry.getValue() == null) {
continue;
}
Message message = (Message) entry.getKey();
// process only messages to basic nodes
if ((message.getSender() instanceof CompositeSoftNode)
|| (message.getReceiver() instanceof CompositeSoftNode)) {
continue;
}
if (addedMsgs.contains(entry.getKey())) {
// It is included in the pending additions
Message msg = (Message) entry.getKey();
pendingAdditions.remove(entry.getKey());
pendingAdditionsByTarget.remove(entry.getValue());
targetToMsgMap.remove(entry.getValue());
totalMsgBandwidth -= msg.getBandwidth();
removeBandwidthOutDegree(msg.getBandwidth());
System.out.println("\n**********************");
System.out.println("* (0) removing msg(" + /* senderID + */ "," + /* receiverID + */ ") bw("
+ msg.getBandwidth() + ") from composite: " + hashCode());
System.out.println("**********************");
} else if ( // !(((Message)entry.getKey()).getSender()
// instanceof CompositeSoftNode) &&
// !(((Message)entry.getKey()).getReceiver() instanceof
// CompositeSoftNode) &&
(!containsComponent(((Message) entry.getKey()).getSender())
|| !containsComponent(((Message) entry.getKey()).getReceiver()))
&& (((Message) entry.getKey()).getDeployedTo() == null)) {
/*
* message to external component. The message needs to point
* now to the composite node (this)
*/
Message msg = null;
try {
msg = (Message) ((Message) entry.getKey()).clone();
} catch (Exception e) {
e.printStackTrace();
}
// msg.setPartner(n, this);
msg.setPartner((SoftwareNode) entry.getValue(), this);
msg.setPartner(this, (SoftwareNode) entry.getValue());
// CouplerElement eSender = (CouplerElement) msg.getSender()
// .getSemanticObject();
// CouplerElement eReceiver = (CouplerElement) msg
// .getReceiver().getSemanticObject();
//
// String senderID = (eSender == null ? "composite:"
// + Integer.toString(msg.getSender().hashCode())
// : eSender.getClass().getName() + ":"
// + Integer.toString(eSender.ID().hashCode()));
// String receiverID = (eReceiver == null ? "composite:"
// + Integer.toString(msg.getReceiver().hashCode())
// : eReceiver.getClass().getName()
// + ":"
// + Integer.toString(eReceiver.ID()
// .hashCode()));
System.out.println("/////////////////////////");
System.out.println(" Pending addition to this(" + Integer.toString(hashCode()) + ") msg("
+ /* senderID + */ "," + /* receiverID + */ ")");
System.out.println("////////////////////////");
// neighbors.remove();
Message prevMsg = null;
/*
* Merge messages
*/
if ((prevMsg = (Message) targetToMsgMap.get(entry.getValue())) != null) {
if (prevMsg instanceof CompositeMsgNode) {
((CompositeMsgNode) prevMsg).add(msg);
} else {
CompositeMsgNode compMsg = new CompositeMsgNode(new BandwidthComparator());
compMsg.setSender(msg.getSender());
compMsg.setReceiver(msg.getReceiver());
compMsg.add(msg);
// remove previous
pendingAdditions.remove(msg);
pendingAdditionsByTarget.remove(entry.getValue());
targetToMsgMap.remove(entry.getValue());
addedMsgs.add(msg);
// Add new composite
pendingAdditions.put(compMsg, entry.getValue());
pendingAdditionsByTarget.put(entry.getValue(), compMsg);
targetToMsgMap.put(entry.getValue(), compMsg);
}
} else {
addedMsgs.add(msg);
pendingAdditions.put(msg, entry.getValue());
pendingAdditionsByTarget.put(entry.getValue(), msg);
targetToMsgMap.put(entry.getValue(), msg);
}
/* modify the partners connectivity vector */
TreeMap partnerConnectivityVector = (TreeMap) connectivityMatrix.get(entry.getValue());
// partnerConnectivityVector.remove(entry.getKey());
if (partnerConnectivityVector == null) {
if (comparator == null) {
System.out.println(" ***** comparator == null ****");
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
partnerConnectivityVector = new TreeMap(comparator);
connectivityMatrix.put(entry.getValue(), partnerConnectivityVector);
}
Hashtable partnerConnVectorByTarget = (Hashtable) softConnectivityByTarget.get(entry.getValue());
// partnerConnectivityVector.remove(entry.getKey());
if (partnerConnVectorByTarget == null) {
partnerConnVectorByTarget = new Hashtable();
softConnectivityByTarget.put(entry.getValue(), partnerConnVectorByTarget);
}
partnerConnectivityVector.put(msg, this);
// partnerConnectivityVector.remove(entry.getKey());
partnerConnVectorByTarget.put(this, msg);
// partnerConnVectorByTarget.remove(entry.getValue());
Message entryMsg = (Message) entry.getKey();
if (!(entryMsg.getSender() instanceof CompositeSoftNode)
&& !(entryMsg.getReceiver() instanceof CompositeSoftNode)) {
totalMsgBandwidth += msg.getBandwidth();
addBandwidthOutDegree(msg.getBandwidth());
}
} else if (containsComponent(((Message) entry.getKey()).getSender())
&& containsComponent(((Message) entry.getKey()).getReceiver()))
// else if (!entry.getValue().equals(this)&&
// (components.contains(entry.getValue()) ||
// basicComponents.contains(entry.getValue())))
{
/*
* if it leads to internal modules then it means that it was
* added before and now we need to substract it
*/
Message msg = ((Message) entry.getKey());
totalMsgBandwidth -= msg.getBandwidth();
// CouplerElement eSender = (CouplerElement) msg.getSender()
// .getSemanticObject();
// CouplerElement eReceiver = (CouplerElement) msg
// .getReceiver().getSemanticObject();
// String senderID = (eSender == null ? "composite:"
// + Integer.toString(msg.getSender().hashCode())
// : eSender.getClass().getName() + ":"
// + Integer.toString(eSender.ID().hashCode()));
// String receiverID = (eReceiver == null ? "composite:"
// + Integer.toString(msg.getReceiver().hashCode())
// : eReceiver.getClass().getName()
// + ":"
// + Integer.toString(eReceiver.ID()
// .hashCode()));
System.out.println("\n**********************");
System.out.println("* (1) removing msg(" + /* senderID + */ "," + /* receiverID + */ ") bw("
+ msg.getBandwidth() + ") from composite: " + hashCode());
System.out.println("**********************");
removeBandwidthOutDegree(msg.getBandwidth());
// try removing all composing messages
// if (msg instanceof CompositeMsgNode)
// {
// CompositeMsgNode compositeMsg = (CompositeMsgNode) msg;
// TreeSet compMsgs = new TreeSet(comparator);
// compositeMsg.getBasicMessages(compMsgs);
// for (Iterator iter=compMsgs.iterator(); iter.hasNext();)
// {
// Message msg1 = (Message) iter.next();
// thisConnectivityVector.remove(msg1);
// }
// }
/*
* internal edges should dissappear in both row and column
* of the connectivity matrix
*/
// neighbors.remove();
/* remove message from component */
// connectivityVector.remove(entry.getKey());
// connVectorByTarget.remove(entry.getValue());
/* remove message from composite */
Message msg1 = (Message) thisConnVectorByTarget.get(msg.getSender());
if (msg1 != null) {
thisConnVectorByTarget.remove(msg.getSender());
thisConnectivityVector.remove(msg1);
} else {
msg1 = (Message) thisConnVectorByTarget.get(msg.getReceiver());
if (msg1 != null) {
thisConnVectorByTarget.remove(msg.getReceiver());
thisConnectivityVector.remove(msg1);
} else {
}
}
// Message msg1 = (Message) thisConnVectorByTarget.get(n);
// if (msg1 != null)
// {
// thisConnVectorByTarget.remove(n);
// thisConnectivityVector.remove(msg1);
// }
// else
// debugArea.append("cannot remove
// msg("+senderID+","+receiverID+")\n");
} else if (entry.getValue().equals(this)) {
// Message msg2 = (Message) entry.getKey();
// CouplerElement eSender = (CouplerElement) msg2.getSender();
// CouplerElement eReceiver = (CouplerElement) msg2
// .getReceiver();
// String senderID = (eSender == null ? "composite:"
// + Integer.toString(msg2.getSender().hashCode())
// : eSender.getClass().getName() + ":"
// + Integer.toString(eSender.ID().hashCode()));
// String receiverID = (eReceiver == null ? "composite:"
// + Integer.toString(msg2.getReceiver().hashCode())
// : eReceiver.getClass().getName()
// + ":"
// + Integer.toString(eReceiver.ID()
// .hashCode()));
System.out.println("************************");
System.out.println("* (2) removing msg(" + /* senderID + */ "," + /* receiverID + */ ")*");
System.out.println("************************");
/* remove message from component */
connectivityVector.remove(entry.getKey());
connVectorByTarget.remove(entry.getValue());
/* remove message from composite */
Message msg1 = (Message) thisConnVectorByTarget.get(n);
if (msg1 != null) {
thisConnVectorByTarget.remove(n);
thisConnectivityVector.remove(msg1);
}
} else {
Message msg = (Message) entry.getKey();
JOptionPane.showMessageDialog(null,
" msg(" + msg.getSender().toString() + "," + msg.getReceiver().toString() + ")");
}
}
/*
* add any pending additions. This pending additions already have
* merged messages
*/
for (Iterator iter = pendingAdditions.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
Message msg = (Message) entry.getKey();
if (!containsComponent(msg.getSender()) || !containsComponent(msg.getReceiver())) {
thisConnectivityVector.put(entry.getKey(), entry.getValue());
}
}
// thisConnectivityVector.putAll(pendingAdditions);
for (Iterator iter = pendingAdditionsByTarget.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
Message msg = (Message) entry.getValue();
if (!containsComponent(msg.getSender()) || !containsComponent(msg.getReceiver())) {
thisConnVectorByTarget.put(entry.getKey(), entry.getValue());
}
}
// thisConnVectorByTarget.putAll(pendingAdditionsByTarget);
}
/*
* alway add back the connectivity vector of 'this' because modifying
* 'this' (adding components) has being as a cause of not keeping the
* correct mapping in the connectivityMatrix
*/
connectivityMatrix.put(this, thisConnectivityVector);
softConnectivityByTarget.put(this, thisConnVectorByTarget);
/*
* int i=0; totalMsgBandwidth = 0.0; for (Object[] neig =
* thisConnectivityVector.entrySet().toArray(); i < neig.length; i++) {
* Map.Entry entry = (Map.Entry) neig[i]; Message msg = (Message)
* entry.getKey(); totalMsgBandwidth += msg.getBandwidth(); }
*/
bandwidthCompressionFactor = totalMsgBandwidth / totalBandwidth;
}
public CompositeSoftNode(Comparator bwComparator, Comparator outDComparator) {
super();
if (bwComparator == null || outDComparator == null) {
throw new IllegalArgumentException("comparator == null");
}
this.comparator = bwComparator;
components = new TreeSet(comparator);
outDegreeComparator = outDComparator;
componentsByOutDegree = new TreeSet(outDegreeComparator);
name = ":";
}
public CompositeSoftNode(Comparator comp) {
super();
if (comp == null) {
throw new IllegalArgumentException("comparator == null");
}
this.comparator = comp;
components = new TreeSet(comparator);
outDegreeComparator = new OutDegreeComparator();
componentsByOutDegree = new TreeSet(outDegreeComparator);
name = ":";
}
public void getSoftwareNodes(Vector v) {
for (Iterator iter = components.iterator(); iter.hasNext();) {
SoftwareNode n = (SoftwareNode) iter.next();
if (n instanceof CompositeSoftNode) {
((CompositeSoftNode) n).getSoftwareNodes(v);
} else {
v.add(n);
}
}
}
public String componentsToString() {
String temp = "";
for (Iterator iter = components.iterator(); iter.hasNext();) {
SoftwareNode n = (SoftwareNode) iter.next();
if (n instanceof CompositeSoftNode) {
temp += "[" + ((CompositeSoftNode) n).componentsToString() + "]";
} else {
temp += ":" + n.name;
}
}
return temp;
}
}