package edu.usc.enl.dynamicmeasurement.algorithms.tasks.hhh.flow; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.hhh.HHHAlgorithm; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.hhh.NeedInitHHHAlgorithm; import edu.usc.enl.dynamicmeasurement.model.WildcardPattern; import edu.usc.enl.dynamicmeasurement.ui.GraphVizOutput; import org.w3c.dom.Element; import java.util.*; /** * Created with IntelliJ IDEA. * User: masoud * Date: 3/3/13 * Time: 7:52 AM */ public abstract class FlowHHHAlgorithm extends HHHAlgorithm { public FlowHHHAlgorithm(Element element) { super(element); } @Override public void match(long srcIP, double size) { } /** * Find HHs in a post-order traversal algorithm * * @param weightThreshold * @param monitors * @param root * @return */ public static Collection<WildcardPattern> findHHHPostOrder(double weightThreshold, Collection<WildcardPattern> monitors, WildcardPattern root) { Set<WildcardPattern> output = new HashSet<>(); LinkedList<WildcardPattern> unresolved = new LinkedList<>(); if (monitors.size() == 0) { return output; } TreeMap<WildcardPattern, WildcardPattern> weightMap = new TreeMap<>(WildcardPattern.WILDCARDNUM_COMPARATOR); for (WildcardPattern monitor : monitors) { weightMap.put(monitor, monitor); } while (weightMap.size() > 0) { WildcardPattern wildcardPattern = weightMap.pollFirstEntry().getKey(); boolean isHH = false; if (wildcardPattern.getWeight() >= weightThreshold) { output.add(wildcardPattern); //just set its weight to zero isHH = true; } if (!canGoUp(wildcardPattern, root)) {//this is the root break; } if (wildcardPattern.isLeft()) { if (isHH) { WildcardPattern clone = wildcardPattern.clone(); clone.setWeight(0); wildcardPattern = clone; } //check for right WildcardPattern parent = wildcardPattern.clone().goUp(); SortedMap<WildcardPattern, WildcardPattern> lowerNodes = weightMap.headMap(parent, false); boolean siblingDescendantFound = false; for (WildcardPattern lowerNode : lowerNodes.keySet()) { if (parent.match(lowerNode)) { siblingDescendantFound = true; break; } } if (siblingDescendantFound) { //keep me for sibling to retrieve unresolved.push(wildcardPattern); } else { //don't wait for sibling add parent parent.setWeight(wildcardPattern.getWeight()); putParent(weightMap, parent); } } else { WildcardPattern sibling = null; if (unresolved.size() > 0) { sibling = unresolved.pop(); if (!wildcardPattern.isSibling(sibling)) { //push it back unresolved.push(sibling); sibling = null; } } //create parent WildcardPattern parent = wildcardPattern.clone().goUp(); parent.setWeight((sibling == null ? 0 : sibling.getWeight()) + (isHH ? 0 : wildcardPattern.getWeight())); putParent(weightMap, parent); } } return output; } private static void putParent(TreeMap<WildcardPattern, WildcardPattern> weightMap, WildcardPattern parent) { WildcardPattern currentParent = weightMap.get(parent); if (currentParent != null) { parent.setWeight(currentParent.getWeight() + parent.getWeight()); weightMap.remove(parent); weightMap.put(parent, parent); //don't mess with the monitors } else { weightMap.put(parent, parent); } } /** * Fill the algorithm with "capacity" number of prefixes that cover all leaves under "rootWildcardPattern" * * @param capacity * @param algorithm * @param rootWildcardPattern */ public static void initMonitors(int capacity, NeedInitHHHAlgorithm algorithm, WildcardPattern rootWildcardPattern) { int startLevel = (int) (Math.log(capacity) / Math.log(2)); int unusedCapacity; if (startLevel < rootWildcardPattern.getWildcardNum()) { unusedCapacity = capacity - (1 << startLevel); } else { startLevel = rootWildcardPattern.getWildcardNum(); unusedCapacity = 0; } try { //create init list int preliminaryLevel = rootWildcardPattern.getWildcardNum() - startLevel; long baseData = rootWildcardPattern.getData() << startLevel; for (int i = 0; i < 1 << startLevel; i++) { WildcardPattern wildcardPattern = new WildcardPattern(baseData + i, preliminaryLevel, 0); algorithm.addMonitor(wildcardPattern); } //now use the unused space fillUnusedCapacity(unusedCapacity, algorithm); } catch (WildcardPattern.InvalidWildCardValue invalidWildCardValue) { invalidWildCardValue.printStackTrace(); } } private static void fillUnusedCapacity(int unusedCapacity, NeedInitHHHAlgorithm algorithm) throws WildcardPattern.InvalidWildCardValue { // Random random = new Random(125623); for (int i = 0; i < unusedCapacity; i++) { //pick a random node WildcardPattern wildcardPattern = algorithm.pollAMonitor(); if (wildcardPattern.canGoDown()) { WildcardPattern lClone = wildcardPattern.clone(); lClone.goDown(false); algorithm.addMonitor(lClone); wildcardPattern.goDown(true); algorithm.addMonitor(wildcardPattern); } else { algorithm.addMonitor(wildcardPattern); } } } public static boolean canGoUp(WildcardPattern wp, WildcardPattern root) { return (wp.canGoUp() && root.getWildcardNum() > wp.getWildcardNum()); } public Collection<WildcardPattern> findHHH() { return findHHHPostOrder(threshold, getMonitors(), taskWildcardPattern); } @Override public void reset() { for (WildcardPattern wildcardPattern : getMonitors()) { wildcardPattern.setWeight(0); } } /** * @return is always sorted */ public abstract Collection<WildcardPattern> getMonitors(); public void printMonitors() { for (WildcardPattern monitor : getMonitors()) { System.out.println(monitor); } } public void displayHook(Collection<WildcardPattern> hhh, int step) { if (hhh == null) { //don't print intermediate steps // return; } if (graphFolder != null) { new GraphVizOutput().print(getMonitors(), graphFolder + "/" + getStep() + "_" + (step) + ".jpg", hhh); } } private Collection<WildcardPattern> findHHHInOrder(double weightThreshold) { Set<WildcardPattern> output = new HashSet<>(); Collection<WildcardPattern> monitors = getMonitors(); if (monitors.size() == 0) { return output; } Map<WildcardPattern, Double> weightMap = new HashMap<WildcardPattern, Double>(); for (WildcardPattern monitor : monitors) { weightMap.put(monitor, monitor.getWeight()); } Iterator<WildcardPattern> iterator = monitors.iterator(); LinkedList<WildcardPattern> unResolved = new LinkedList<WildcardPattern>(); WildcardPattern wildcardPattern = iterator.next(); while (wildcardPattern != null) { if (weightMap.get(wildcardPattern) >= weightThreshold) { output.add(wildcardPattern); //just set its weight to zero weightMap.put(wildcardPattern, 0d); } if (!wildcardPattern.canGoUp()) {//this is the root break; } WildcardPattern sibling; if (wildcardPattern.isLeft()) { //next is sibling, handle it next unResolved.add(wildcardPattern); wildcardPattern = iterator.hasNext() ? iterator.next() : null; } else { //my sibling must be head of unresolved sibling = unResolved.pollLast(); if (!wildcardPattern.isSibling(sibling)) { System.err.println("Not found the sibling"); System.exit(1); } //create parent WildcardPattern parent = wildcardPattern.clone().goUp(); parent.setWeight(weightMap.get(wildcardPattern) + weightMap.get(sibling)); weightMap.put(parent, parent.getWeight()); wildcardPattern = parent; } } if (unResolved.size() > 0) { System.err.println("Some points are unresolved"); for (WildcardPattern pattern : unResolved) { System.err.println(pattern); } } return output; } }