package edu.usc.enl.dynamicmeasurement.algorithms.tasks.hhh.flow.multiswitch;
import edu.usc.enl.dynamicmeasurement.model.WildcardPattern;
import edu.usc.enl.dynamicmeasurement.model.monitorpoint.MonitorPoint;
import edu.usc.enl.dynamicmeasurement.util.Util;
import java.util.Set;
/**
* Created with IntelliJ IDEA.
* User: masoud
* Date: 8/22/13
* Time: 10:31 PM <br/>
* Represents a node in the prefix tree
*/
public class MultiSwitchWildcardPattern implements Comparable<MultiSwitchWildcardPattern> {
/**
* prefix
*/
private final WildcardPattern wildcardPattern;
/**
* The weight of node plus left subtree and right subtree
*/
protected double internalWeight = 0;
/**
* All prefixes that have traffic on this prefix
*/
private final Set<MonitorPoint> monitorPoints;
/**
* The set of common switches among left and right subtree
*/
private Set<MonitorPoint> commonSet;
/**
* commonSet + common set of left and right.
* This is equal to the any switch that we can save an entry on if we collapse all leaves to this internal node
*/
private Set<MonitorPoint> internalCommonSet;
private MultiSwitchWildcardPattern right = null;
protected MultiSwitchWildcardPattern left = null;
public MultiSwitchWildcardPattern(WildcardPattern wildcardPattern, Set<MonitorPoint> monitorPoints) {
this.wildcardPattern = wildcardPattern;
this.monitorPoints = monitorPoints;
}
public void compress() {
right = null;
left = null;
}
public WildcardPattern getWildcardPattern() {
return wildcardPattern;
}
public double getBenefit() {
return wildcardPattern.getWeight();
}
public double getCost() {
return getInternalWeight();
}
public Set<MonitorPoint> getMonitorPoints() {
return monitorPoints;
}
public double getInternalWeight() {
return internalWeight;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(wildcardPattern.toString() + " (");
boolean first = true;
for (MonitorPoint monitorPoint : monitorPoints) {
sb.append(first ? "" : ",").append(monitorPoint.getIntId());
first = false;
}
return sb.append(")").toString();
}
@Override
public int compareTo(MultiSwitchWildcardPattern o) {
return wildcardPattern.compareTo(o.wildcardPattern);
}
public Set<MonitorPoint> getCommonSet() {
return commonSet;
}
Set<MonitorPoint> getInternalCommonSet() {
if (internalCommonSet == null) {
internalCommonSet = Util.cloneSet(getMonitorPoints());
internalCommonSet.clear();
internalWeight = 0;
}
return internalCommonSet;
}
public MultiSwitchWildcardPattern getLeft() throws WildcardPattern.InvalidWildCardValue {
if (left == null) {
WildcardPattern wp = wildcardPattern.clone().goDown(false);
left = new MultiSwitchWildcardPattern(wp, MultiSwitch2.hasDataFrom(wp, monitorPoints));
}
return left;
}
public MultiSwitchWildcardPattern getRight() throws WildcardPattern.InvalidWildCardValue {
if (right == null) {
WildcardPattern wp = wildcardPattern.clone().goDown(true);
right = new MultiSwitchWildcardPattern(wp, MultiSwitch2.hasDataFrom(wp, monitorPoints));
}
return right;
}
public void computeCommonSet() throws WildcardPattern.InvalidWildCardValue {
commonSet = Util.cloneSet(getLeft().getMonitorPoints());
commonSet.retainAll(getRight().getMonitorPoints());
}
/**
* re-populate the common set and internal common set of this internal node
*
* @throws WildcardPattern.InvalidWildCardValue
*/
public void computeInternalCommonSet() throws WildcardPattern.InvalidWildCardValue {
if (commonSet == null) {
computeCommonSet();
}
if (internalCommonSet == MultiSwitch2.EMPTY_SET || internalCommonSet == null) {
internalCommonSet = Util.cloneSet((getLeft().getInternalCommonSet()));
} else {
internalCommonSet.clear();
internalCommonSet.addAll(getLeft().getInternalCommonSet());
}
internalCommonSet.addAll(getRight().getInternalCommonSet());
internalCommonSet.addAll(commonSet);
updateInternalWeight();
}
public double getWeight() {
return wildcardPattern.getWeight();
}
/**
* You should not call this on leaves
*
* @param weight
*/
public void setWeight(double weight) {
wildcardPattern.setWeight(weight);
updateInternalWeight();
}
public void resetInternalCommonSet() {
internalCommonSet.clear();
internalWeight = 0;
}
/**
* always make sure left and right is there
*
* @throws edu.usc.enl.dynamicmeasurement.model.WildcardPattern.InvalidWildCardValue
*/
public void updateInternalWeight() {
try {
if (left != null) { //if it is really an internal node, its left should not be null by now
internalWeight = getWeight() + getLeft().getInternalWeight() + getRight().getInternalWeight();
}
} catch (WildcardPattern.InvalidWildCardValue invalidWildCardValue) {
}
}
}