package edu.usc.enl.dynamicmeasurement.algorithms.tasks.changedetection.multiswitch; import edu.usc.enl.dynamicmeasurement.algorithms.matcher.HashMatcher; import edu.usc.enl.dynamicmeasurement.algorithms.matcher.Matcher; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.changedetection.ChangeDetectionAlgorithm; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.hh.flow.MultiSwitch2ForHHDetection; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.hhh.flow.multiswitch.MultiSwitchWildcardPattern; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.multiswitch.separateallocation.MultiSwitchTask; import edu.usc.enl.dynamicmeasurement.data.FinishPacket; import edu.usc.enl.dynamicmeasurement.floodlight.TCAMAlgorithm; import edu.usc.enl.dynamicmeasurement.model.WildcardPattern; import edu.usc.enl.dynamicmeasurement.model.monitorpoint.MonitorPoint; import edu.usc.enl.dynamicmeasurement.util.profile.Profilable; import org.w3c.dom.Element; import java.util.Collection; import java.util.HashMap; import java.util.Map; /** * Created with IntelliJ IDEA. * User: masoud * Date: 1/11/14 * Time: 4:20 PM <br/> * Uses the divide and merge algorithm to find large changes */ public class MultiSwitchChangeDetection extends ChangeDetectionAlgorithm implements MultiSwitchTask.MultiSwitchTaskImplementation, TCAMAlgorithm, Profilable { private final Matcher matcher; private MultiSwitch2ForChangeDetection algorithm; public MultiSwitchChangeDetection(Element element) { super(element); algorithm = new MultiSwitch2ForChangeDetection(element); matcher = new HashMatcher(); matcher.setMonitors(algorithm.getMonitors()); } @Override public void match(long item, double diff) { WildcardPattern match = matcher.match(item); match.setWeight(match.getWeight() + diff); } @Override public Collection<WildcardPattern> findBigChanges(int step) { algorithm.setStep(step); return algorithm.findHHH(); } @Override public void update(int step) { super.update(step); algorithm.update(); matcher.setMonitors(algorithm.getMonitors()); } @Override public void setCapacityShare(Map<MonitorPoint, Integer> resource) { algorithm.setCapacityShare(resource); } @Override public void estimateAccuracy(Map<MonitorPoint, Double> accuracy) { algorithm.estimateAccuracy(accuracy); } @Override public double getGlobalAccuracy() { return algorithm.getGlobalAccuracy(); } @Override public void getUsedResources(Map<MonitorPoint, Integer> resource) { algorithm.getUsedResources(resource); } @Override public void reset() { super.reset(); algorithm.reset(); } @Override public void setFolder(String folder) { super.setFolder(folder); algorithm.setFolder(folder); } @Override public void finish(FinishPacket p) { algorithm.finish(); super.finish(p); } @Override public void writeProfiles() { algorithm.writeProfiles(); } @Override public void createProfiler() { algorithm.createProfiler(); } @Override public void finishProfiler() { algorithm.finishProfiler(); } @Override public Collection<MonitorPoint> getWhichSwitch(WildcardPattern monitor) { return algorithm.getWhichSwitch(monitor); } @Override public Collection<WildcardPattern> getMonitors() { return algorithm.getMonitors(); } /** * The adapter class for divide and merge algorithm. The changes are as follows * <ul> * <li> Divide & Merge: must update the history of the children or the parent based on the monitored data</li> * <li> set the weight of monitored nodes as weight-mean before finding big items</li> * <li> set the score for updating the items based on weight/(level+1) as we are only interested in * lowest level big changes</li> * </ul> */ private class MultiSwitch2ForChangeDetection extends MultiSwitch2ForHHDetection { private Map<WildcardPattern, Double> monitorMean = new HashMap<>(); public MultiSwitch2ForChangeDetection(Element element) { super(element); monitorMean.put(taskWildcardPattern.clone(), 0d); } @Override public Collection<WildcardPattern> findHHH() { //update the weight for finding big items for (WildcardPattern wildcardPattern : monitors.keySet()) { Double mean = monitorMean.get(wildcardPattern); double weight = wildcardPattern.getWeight(); monitorMean.put(wildcardPattern, mean * ewmaAlpha + weight * (1 - ewmaAlpha)); wildcardPattern.setWeight(Math.abs(mean - weight)); } return super.findHHH(); } @Override protected void updateForMerge(WildcardPattern toMergeSiblingsParent, MultiSwitchWildcardPattern toMerge, MultiSwitchWildcardPattern foundNode1, MultiSwitchWildcardPattern foundNode2) throws WildcardPattern.InvalidWildCardValue { super.updateForMerge(toMergeSiblingsParent, toMerge, foundNode1, foundNode2); Double mean1 = monitorMean.remove(foundNode1.getWildcardPattern()); Double mean2 = monitorMean.remove(foundNode2.getWildcardPattern()); monitorMean.put(toMerge.getWildcardPattern(), mean1 + mean2); } @Override protected void updateForDivide(MultiSwitchWildcardPattern divideCandidate, MultiSwitchWildcardPattern divideChild1, MultiSwitchWildcardPattern divideChild2) throws WildcardPattern.InvalidWildCardValue { super.updateForDivide(divideCandidate, divideChild1, divideChild2); Double mean = monitorMean.remove(divideCandidate.getWildcardPattern()); monitorMean.put(divideChild1.getWildcardPattern(), mean / 2); monitorMean.put(divideChild2.getWildcardPattern(), mean / 2); } } }